根据汇编程序和装载机 (一本有24年历史的关于汇编程序工作方式的书):
...a单程汇编程序不能生成可重定位的对象文件.只有通过检查原始源指令才能确定指令的类型(绝对的或可重定位的)。一通汇编程序直接将机器指令装入内存中.一旦在内存中,指令只是一个数字。通过查看内存中的机器指令,无法判断原始指令是绝对指令还是可重定位指令。
本书给出了可重定位和绝对指令的下列伪代码:
JMP TO
...
TO: ADD 1,2其中,第一指令使用符号TO,第二指令在寄存器'1‘和寄存器'2’中添加值。
据我理解,您不需要源代码就可以知道第一条指令的机器代码是可重定位的。应该可以使用操作码表来确定它是JMP指令,并且必须跳转到需要重新定位的地址。
我的假设正确吗?
背景:虽然这本书很旧,但我正在读它,对6502和65816这样的旧CPU的组装有了更好的理解。
发布于 2017-02-10 00:14:33
您的书具有误导性,正如大多数人所理解的那样,一次过的汇编程序可以通过发出名为“重新定位”的特殊数据来生成可重定位的对象文件,该数据告诉链接器/加载程序如何重新定位代码。这本书似乎是“一遍汇编程序”的一个特殊定义,根据它自己的定义,它无法输出带有重定位的“可重定位对象文件”。
但是,通常情况下,您无法判断给定的机器代码指令是否可重定位,除非有一组可用于判断什么是可重定位的,哪些是不可重定位的(以及如何重新定位不可重定位的指令)。某些指令很明显,例如,您可以根据目标地址的编码方式来判断JMP TO指令是否可重定位。如果目标地址被编码为与JMP指令地址的相对偏移量,那么它是可重定位的。另一方面,如果编码为绝对地址,则指令不可重定位。在第一种情况下,程序可以在内存中重新定位,而无需修改,JMP指令仍然会跳转到相同的代码中。在第二种情况下,JMP指令总是跳到相同的地址,而不管代码被重新定位到哪里,除非指令被更改为跳转到正确的位置。
在x86程序集中,第一种情况的具体示例如下:
0056: EB 10 JMP LO指令中的第一个字节是操作码EB (我在这里使用的数字都是十六进制),它表示一个具有8位相对偏移量的JMP指令。指令中的第二个字节是8位相对偏移量.它实际上相对于以下指令的开头,因此地址跳转到0056 + 2 + 10或0068。
在6502汇编中,第二种情况的一个例子是:
0056: 4C 68 00 JMP LO在这种情况下,操作码字节4C表示一个JMP指令,该指令使用编码到指令中的2字节绝对地址。接下来的两个字节按小端字节顺序组成该地址:0068。
另一个简单的例子是ADD 1,2,它只使用寄存器。由于不涉及地址,所以可以不修改地重新定位指令,因为指令中没有编码的地址。问题在于ADD #1000,2这样的指令,它将文字值1000添加到存储在寄存器2中的值中。在这种情况下,数字1000是在指令中编码的,因此无法知道该数字是否用作地址。在上下文之外,无法知道指令中是否有编码地址。
像16位ADD #1000,2汇编语言中的x86示例如下:
0068: 81 C3 EB 03 ADD BX, 1000指令EB 03的最后两个字节是以十进制为单位的值,是对指令的直接(文字)操作数进行编码的地方。指令将1000添加到BX寄存器。如果没有更多的上下文,就不可能知道1000是否应该是地址。例如,代码可能计算从地址1000开始的表中某物的地址。
你可能想找另一本书,因为它似乎花了很多时间来处理24年前已经过时、今天已经完全过时的机器架构。
https://stackoverflow.com/questions/42146498
复制相似问题