假设我有这样的代码:
_TEXT16 SEGMENT USE16 'CODE'
_start:
; some code...
; add padding
byte 512-($-_start) dup (0) ; works fine
_TEXT16 ENDS
_TEXT32 SEGMENT USE32 'CODE'
; some code
byte 1024-($-_start) dup (0) ; error A2192: Operands must be in same segment
_TEXT32 ENDS
在NASM中,您只需执行类似于times 1024-($-$$) db 0
的操作,但不幸的是,MASM或JWASM不支持$$
,这是我目前正在使用的。我需要它来将引导加载程序的块与可读磁盘扇区的大小对齐。
所以,我的问题是,如何在MASM中向代码块添加512字节的填充?
编辑:
情况发生了一些变化。
_TEXT16 SEGMENT USE16 'CODE'
_start:
; some code...
_TEXT16 ENDS
_TEXT32 SEGMENT USE32 'CODE'
; some code
_TEXT32 ENDS
_TEXT64 SEGMENT USE64 'CODE'
; some code
; add padding
byte 510-($-_start) dup (0) ; error A2192: Operands must be in same segment
dw 0AA55h
_TEXT64 ENDS
现在,我该如何在这里添加正确的填充呢?
2条答案
按热度按时间ljsrvy3e1#
好吧,这是一个很难解释的问题,但我终于解决了我的问题。
最后运行的代码如下:
这里发生的事情如下所示。(
org 07C00h
)设置程序的起始地址。它之所以这样做,是因为我们已经使用END
指令告诉它,我们已经给代码的起始位置一个标签。(END _start
)。如果你没有给END
指令一个你的代码的声明标签,第一个org
指令将被解析为在你的实际代码前面加了很多零。或者简而言之,它实际上会将代码偏移您给予它任何值。然而,第二个
org
指令(org org (510 - size16 - size32 - size64 - size_data)
)的作用就像一个偏移量,即使您没有给END
给予一个标签。综合考虑所有这些因素,我们的结果如下:
正如您所看到的,我必须通过在每个段的开头和结尾使用标签来计算每个段的大小。然后,我为这些大小设置了一些常量。如果您问自己,为什么不在代码的开头和结尾分别放置一个标签呢?然后,我必须告诉您,您只能在段中放置标签,并且只能从同一个段中访问它们。因此,设置了常量。计算每一个的大小。
所以总结一下:
END
指定一个标签,则第一个org
将设置程序偏移量org
指令都将充当偏移,无论如何SEGMENT
与BYTE
对齐“请大家不要完全相信我的话,这只是经过多次测试的结果,如果大家有什么问题,请尽管提出来。”
否则,我希望这对找到这个的人有帮助。
uurv41yg2#
也许使用
org 510
或org 510 + 7C00h
来寻找该点?NASM的文档特别提到NASM不支持MASM的
org
指令所允许的欺骗,这意味着MASM的org
* 可以 * 用于此。NASM文档甚至给出了一个MASM示例:我不知道这可能会与多个段交互。OP报告说这只适用于同一个段 * 内 * 的两个
org
指令。也许有一种方法可以指定一个段的起源作为声明它的一部分?或者另一种选择是,在不将这些数据段填充到固定大小的情况下,是否可以让MASM计算这些较早数据段的大小?(当这些数据段的大小固定时,事情显然很简单:您只需将第二个数据段设置为512字节,位于第一个512字节的数据段之后,因此它将在1024处结束。)
像
byte 510 - sizeof _TEXT16 -($-_start) dup (0)
或类似的东西也减去前面的段的长度?我不知道MASM是否允许这样做。显然这是行不通的,所以也许定义一个equ
或size16 = $-start16
或其他东西在前面两个段的每一个。无论哪种方式,都不会考虑段之间的填充,如果有任何填充来对齐它们的开始。
当然,如果你不知道如何让汇编器为你做这件事,你也可以在编译过程中单独地把一个 Boot 签名附加到汇编器的平面二进制输出中。
在Linux shell中,此命令打开
boot.bin
,查找到字节510,然后写入db 0x55, 0xaa
如果你一直在使用Windows,那么就有
dd
的端口,例如http://www.chrysocome.net/downloads/dd-0.6beta3.src.zip。如果你没有使用bash
或zsh
这样的shell来扩展$((510/2))
,那就只有seek=255
,因为dd
将seek作为块的数量,而不是字节。如果已经安装了python
,也许可以使用它,或者只是使用汇编程序创建一个2字节的文件。