如何在启动扇区中获取使用nasm汇编的指令大小?

3

我正在使用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汇编时打印的方法。

是否有一种简洁或直接的方法来知道填充之前指令的大小?

最好避免使用hacky方法,例如在运行时打印或向后搜索boot.bin以查找非零值。


3
只需使用-l选项请求一个列表,或者在nasm外部使用您的构建环境填充文件即可。 - Jester
@Jester的评论是最佳答案。我使用了-l listing.txt来生成一个清单文件。在清单文件中,可以清楚地看到有意义指令的大小。 - Costava
2个回答

4
您可以使用%assign在汇编时计算数字表达式。 (每个汇编通过还使用预处理器。这就是您可以使用预处理器对标签进行有限算术运算的方式。)然后使用%warning显示汇编时消息。唯一的缺点是它会显示“作为警告”,但它是汇编时输出。引用手册:

[...] %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]

1
有趣的是,从名称上看,我本以为“预处理器指令”会在早期执行,在进行任何汇编或计算地址之前,所以我不会猜到这会起作用。 - Nate Eldredge
@Nate Eldredge:我在任何非微不足道的程序中基本上都使用这个集成预处理器方案的特性。这就是为什么您无法对我的任何源代码执行“nasm -E”(仅进行预处理)。提示“错误:符号引用不支持预处理模式”。 - ecm

3
您可以在填充前添加标签,并使用size: dw $-$$在引导加载程序中存储一个大小,您可以在汇编代码列表或十六进制转储中查看它。但这将占用2个字节。
使用nasm -fbin foo.asm -l /dev/stdout | less会显示地址|十六进制码|源代码行的列表,非常容易看到time...db 0的起始位置,以及放入dw中的整数。您可以在我的代码高尔夫答案中看到该格式的示例。
或者,您可以简单地注释掉times 510 - ($-$$) db 0/dw 0xaa55的填充,并查看文件大小!
如果你接近限制,请将其注释掉,同时优化代码大小,直到您拥有了一些您认为应该适合并能正常工作的内容。

@zx485:NASM的预处理器确实有%warning指令,但预处理发生在汇编之前,因此您不能警告那些直到太晚才能知道的事情。 - Brendan
@Brendan:你可以轻松做到这一点。不过,它是 $ - $$ 而不是反过来。而且你想要的是 510 - ($ - $$),只有 $ - $$ 只给出了当前部分组装的字节数。然而,我理解问题是希望无条件地显示。 - ecm
2
@ecm:啊,抱歉。我确实尝试过(但是尝试得“不对”,没有使用%[ ]来扩展它)。 - Brendan
@Brendan:使用%[...]的宏间接引用仅在将结果嵌入到其他单词中时才需要。就像我的回答中所示,num只是%warning中的裸字,并会被扩展为定义的值。 - ecm
1
@zx485:事实证明我错了,NASM的%warning可以引用诸如符号偏移量之类的东西;请参考@ecm的回答。(我所说的简单,并不是指很难实现,而是从语言设计的角度来看有点奇怪,就像将其变成一个脚本语言,可以在运行汇编器的终端上执行I/O操作。) - Peter Cordes
显示剩余7条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接