【发布时间】:2021-05-01 19:47:22
【问题描述】:
我一直在思考以下汇编代码 (NASM IA-32):
ORG 0xFF000 ; This is (1MB - 4KB) 0x100000 - 0x1000=0xFF000.
USE16 ;produce 16bit code
code_size EQU (end -init_16) ; calculates code length
times (4096-code_size) db 0x90 ; fills the rest of the memory with NOP's
init_16:
cli ;disables interrupts (not really necessary, just an example)
jmp init_16 ;infinite loop
align 16
end :
这只是一个例子。这个想法是我们有一个实模式的 IA-32 处理器。在内存的顶部 4Kbyte 上,我们有一个 NVRAM(非易失性 RAM)。重置向量指向 0xFFF0,因此代码尝试将 cli 指令放置在 0xFFFF0 地址中,而与放置在 init16 标签和 align 16 指令之间的指令数量无关(限制为 16 个字节,因此它可以容纳到 1Mbyte)。但我不明白它是怎么做到的。
我对@987654325@ 和times 指令特别困扰。因为它们似乎依赖于另一个的结果所以我不知道 NASM 是如何解决这个问题的。
首先,我们有times 指令,它需要align 16 指令的结果。 times 需要知道align 16 添加了多少字节才能更改code_size 标签并用NOP's 填充剩余的内存。
我们还有align 指令,它需要知道times 指令的结果是什么,以便知道jmp 指令在哪里结束,然后计算它必须添加多少NOP's到达新的 16 位对齐位置。
所以在我看来,两个指令都依赖于另一个指令的结果。
此外,如果在cli 和jump 之间添加指令,我无法理解为什么cli 指令总是独立地以0xFFFF0 地址结束。这是目标,但我不知道它是如何工作的。
我认为这两个指令都构成了一个未确定的系统,因此有许多不同的解决方案。例如,在我之前提出的代码中,我认为解决方案可能是:
cli 指令在 0xFFFF1 结束
0xFFFF2 中的jump 指令
align 16 用 NOP 填充地址 0xFFFF2 到 0xFFFFF
所以现在定义了code size 标签,times 指令用 NOP 填充地址 0x0000 到 0xFFFF0
为什么这不是代码的行为?
【问题讨论】: