问题描述
我正在组装一个带有nasm的程序以适合引导扇区(最大512字节)。
例如nasm -f bin boot.asm -o boot.bin
程序的最后两行用0填充剩余空间并添加魔术字节:
times 510 - ($-$$) db 0 ; Pad the remaining of the first 510 bytes with 0
dw 0xaa55 ; Magic bytes required at end of boot sector
输出的boot.bin
文件始终为512字节(预期),因此我不能轻易查看boot.bin
的大小来获取有意义的大小(非填充字节和非魔术字节)说明。
我想在汇编时打印($-$$)
(类似于gcc的#warning
或#pragma message
)是可行的,但是我找不到在原始汇编时打印的任何方法。 / p>
在填充之前是否有一种干净或直接的方法来了解指令的大小?
最好避免在运行时打印或通过boot.bin
向后搜索以寻找非零值之类的骇人方法。
解决方法
您可以在汇编时使用%assign
来计算数字表达式。 (每个汇编过程也使用预处理器。这是使用预处理器对标签进行有限算术的方式。)然后use %warning
to display an assemble time message。唯一的缺点是它将显示“警告”,但这是组装时间输出。引用手册:
[...]%warning发出警告,但允许程序集继续:
[...]
引号%error,%warning或%fatal之后的消息字符串是可选的。如果不是 ,则会在其中展开单行宏,该宏可用于向用户显示更多信息。
在my boot sector loaders中,我这样做:
available:
_fill 508,38,start
signatures:
dw 0
; 2-byte magic bootsector signature
dw 0AA55h
%assign num signatures-available
%assign fatbits 12
%if _FAT16
%assign fatbits 16
%endif
%warning FAT%[fatbits]: num bytes still available.
%endif
end:
_fill
来自the macro collection。有关第一个dw
的含义,请参见my question about the zeros。
示例输出:
boot.asm:1600: warning: FAT12: 10 bytes still available. [-w+user]
,
您可以在填充前放置标签,然后size: dw $-$$
将大小存储在引导加载程序中,您可以在asm列表或hexdump中查看该大小。但这要占用2个字节。
nasm -fbin foo.asm -l /dev/stdout | less
将显示地址的列表 |十六进制转储|源代码行,可以很容易地看到time ... db 0
的起始位置,以及输入dw
的整数。例如,您可以在a code-golf answer of mine中看到该格式的示例。
或者您可以简单地注释掉times 510 - ($-$$) db 0
/ dw 0xaa55
填充并查看文件大小!
如果您已接近极限,请在优化代码大小的同时将其注释掉,直到您认为合适的东西为止。