我正在用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
(,但我找不到在nasm组装时打印的任何方法。
在填充之前,有没有一种干净或直接的方法来了解指令的大小?
最好避免像在运行时打印或在boot.bin
中向后搜索以查找非零值这样的棘手方法。
您可以在汇编时使用%assign
来计算数字表达式。(每个组装过程也使用预处理器。这就是使用预处理器对标签进行有限运算的方法。(然后使用%warning
显示组装时间消息。唯一的缺点是它将显示";作为警告";,但它是组装时间输出。引用手册:
[…]%警告发出警告,但允许程序集继续:
[…]
在%error、%warning或%fatal之后的消息字符串是可选的。如果是而不是,则单行宏将在其中展开,可用于向用户显示更多信息。
在我的引导扇区加载程序中,我这样做:
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
来自宏集合。关于第一个dw
的含义,请参阅我关于零的问题。
示例输出:
boot.asm:1600: warning: FAT12: 10 bytes still available. [-w+user]
您可以在填充之前放置一个标签,并执行size: dw $-$$
以在引导加载程序中存储一个大小,您可以在asm列表或hexdump中查看该大小。但这需要2个字节。
nasm -fbin foo.asm -l /dev/stdout | less
将显示地址|hexdump|source行的列表,这样可以很容易地查看time ... db 0
的起始位置以及您放入dw
的整数。例如,您可以在我的代码高尔夫答案中看到这种格式的示例。
或者您可以简单地注释掉times 510 - ($-$$) db 0
/dw 0xaa55
填充并查看文件大小!
如果你已经接近极限,那么在优化代码大小的同时将其注释掉,直到你有了你认为应该适合并有效的东西。