2

我正在学习汇编(z80 和 x86),现在开始使用汇编器来构建二进制文件。

如何使用具有绝对(而不是相对)地址的标签?

据我了解,汇编程序会在编译时将标签转换为内存地址,但是汇编程序如何知道标签在运行时将驻留在哪个地址

对于 z80 裸机系统来说,这似乎很简单,因为您可以将程序加载到特定的内存地址并发送RST将程序计数器指向的信号0000h当有操作系统运行时会发生什么

在操作系统中执行的代码不会不知道它的起始地址(因此无法在标签上使用非相对操作码)callret

4

4 回答 4

3

如果机器码不是位置无关的,有两种常见的策略:

  • 在可执行文件中包含附加信息(AKA 重定位信息),这些信息会告诉操作系统需要调整的绝对地址在哪里

  • 只需将可执行文件加载到它想要的位置,这意味着您可能需要先驱逐另一个可执行文件,或者您需要为每个可执行文件提供单独的地址空间,因此首先无需为正确的位置而战

于 2014-11-28T01:41:28.270 回答
2

可能值得一读 CP/M 的解决方案,它很简单:二进制文件始终加载到固定地址,操作系统入口点始终位于另一个固定地址。这在 8 位机器上是相当典型的,即使是那些具有正式操作系统的机器,并且被带到 MS-DOS 中。使用 MMU 的多任务操作系统在技术上也是可行的,因为每个进程都有自己的地址空间,因此每个二进制文件都可以认为它是在同一个地方加载的。

使用可重定位代码之间的生成。要么它与位置无关,因为 CPU 很容易支持(根据经典 Mac OS 和 68000 的相对于 PC 的寻址),要么实际上是在加载二进制文件时发生经典两遍汇编程序的第二遍。因此,二进制是编译后的代码,其中包含所有绝对地址的占位符以及这些占位符所在位置的列表,以便在知道实际地址后可以替换它们。

唯一的问题是它会阻止快速的虚拟内存。使用非 MMU Mac OS 方法,程序被编译为 16kb 块,每个块内的跳转直接发生,远程跳转通过寻呼机进行。如果目标块已加载,则关闭它,如果没有,则加载它,然后发生跳转。如果需要在每次加载时计算和填写地址,这种按需加载是令人望而却步的。

于 2014-11-28T21:32:30.863 回答
0

我猜,你的程序会短于 64 kb。在这种情况下,程序只需知道标签的偏移量(称为近跳转)。操作系统每次都在相同的 OFFSET 处启动程序,但在另一个段。条件跳转和“jmp short”仅使用 jmp 命令和标签之间的区别。在某些特殊情况下,例如如果一个过程在执行之前存储到堆栈中,编译器会插入一个代码来更改 jmp 命令的参数。

于 2014-11-28T07:39:52.743 回答
-2

汇编器使用偏移量。

LABEL
     . . . . . 

     JMP LABEL // Knows the number of bytes to label. SO label can be anywhere.
于 2014-11-28T02:26:07.830 回答