我正在同时阅读各种有关计算机体系结构的书籍,我很困惑。有的书上说汇编指令只是机器指令的助记符,每条指令恰好对应一条机器指令。然而,Tanenbaum 的 Structured Computer Organization 将汇编放在操作系统之上之上,并且似乎暗示汇编以某种方式使用操作系统(我还没有阅读整本书......)
哪一个是真的?汇编指令只是机器指令吗?它们也可以是由操作系统解释为机器指令的系统调用吗?它们可以是其他东西吗?
标签定义不对应于任何指令 - 它们只是标记内存,以便您可以在其他地方引用它。 标签绝对不对应于指令,即使在某些汇编器下它们占据单独的行。
db 0x90
或
.byte 0x90
等数据指令手动将字节组装到输出文件中。 在执行将到达的区域中使用此类指令可以让您手动编码指令,或者如果您不小心这样做的话会产生错误。汇编器通常支持指令 - 为汇编器本身提供一些指导的行。这些与 CPU 指令不对应,有时会被误认为是真正的命令。
一些汇编器支持宏 - 想想内联函数。
但根据操作数,它可能只需要汇编成 1 条机器指令。 例如
li $t0, 1
可以组装成
ori $t0, $zero, 1
,但
li $t0, 0x55555555
需要
lui
和
ori
(或
addiu
)。在 ARM 上,
ldr r0, =0x5555
可以在来自文字池的 PC 相对加载或
movw
(如果为支持 16 位立即数的
movw
的 ARM CPU 进行汇编)之间进行选择。 在反汇编中你不会看到
ldr r0, =0x5555
,你会看到汇编器选择来实现它的任何机器指令。 (编者注:我不确定是否有 ARM 汇编器会选择 2 条指令 (
movw
+
movk
) 以获得更广泛的
ldr reg, =value
常数)
CALL
,ARM 上有
BL
。就 CPU 文档而言,这些是单个指令。 它们只是在某处存储返回地址的分支。但是,如果您正在调试并单步执行
over函数调用而不是into函数调用,则它们会调用可能包含任意多个指令的过程/函数/子例程。系统调用也是如此:像 syscall
或
svc #0
这样的指令基本上是对内核的函数调用。