繁体   English   中英

使用时间和对齐 NASM 指令将指令放置在复位向量指向的地址中

[英]Placing an instruction in the address pointed by the reset vector using times and align NASM directives

我一直在考虑以下汇编代码(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 处理器。 在 memory 的顶部 4 KB 上,我们有一个 NVRAM(非易失性 RAM)。 重置向量指向 0xFFF0,因此代码尝试将cli指令放置在 0xFFFF0 地址中,而与放置在init16 label 和align 16指令之间的指令数量无关(限制为 16 个字节,因此它可以容纳 1Mbyte) . 但我无法理解它是如何做到的。

我对align 16times指令特别困扰。 因为它们似乎依赖于另一个的结果,所以我不知道 NASM 是如何解决这个问题的。

首先,我们有需要align 16指令结果的times指令。 times需要知道align 16添加了多少字节才能更改code_size label 并用NOP's填充 memory 的 rest。

我们还有align指令,它需要知道times指令的结果是什么,以便知道jmp指令在哪里结束,然后计算它必须添加多少NOP's才能到达新的 16 位对齐 position。

所以在我看来,这两个指令都取决于另一个指令的结果。

此外,如果在clijump之间添加指令,我无法理解为什么cli指令总是独立地以 0xFFFF0 地址结束。 这是目标,但我不知道它是如何工作的。

我认为这两个指令都构成了一个未确定的系统,因此有许多不同的解决方案。 例如,在我认为解决方案可能是之前提出的代码中:

cli指令在 0xFFFF1 结束, jump指令在 0xFFFF2 和align 16用 NOP 填充地址 0xFFFF2 到 0xFFFFF 所以现在定义了code size label 并且times指令用 NOP 填充地址 0x0000 到 0xFFFF0

为什么这不是代码的行为?

首先,我觉得看到ORG 0xFF000USE16很奇怪。 它认为在实地址模式下, ORG是 64KB 段中的 16 位偏移量。

这是多通道汇编器的奇迹

因为在第一遍时,汇编器还不知道endinit_16标签,它可以跳过依赖它的times 这会将当前偏移量 ($) 保留在ORG处。 然后是编码cli和短跳转jmp init_16的 3 个字节,然后是align 16产生的 13 个字节。
此时,两个标签都是已知的,并且可以开始使用这些偏移量进行后续传递。 code_size计算为 16(两个标签之间的差异),因此times填充为 4080 nop s (4096-16)。
尽管这 2 个标签现在在 memory 中向上移动了 4080 个字节,但它们的差异仍然相同 (16),因此不需要进一步的遍历。 代码已解决。

此外,如果在 cli 和 jump 之间添加指令,我无法理解为什么 cli 指令总是独立地以 0xFFFF0 地址结束。 这是目标,但我不知道它是如何工作的

只要两个标签之间的差异保持 16,在此cli之后立即添加一些指令不会更改概述的过程。您可以插入价值 13 个字节的指令。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM