汇编指令是否将 1-1 映射到机器语言?
Do assembly instructions map 1-1 to machine language?
我正在同时阅读各种关于计算机体系结构的书籍,但我很困惑。有些书说汇编指令只是机器指令的助记符,每条指令恰好对应一条机器指令。但是,Tanenbaum 的 Structured Computer Organization 将程序集放在 层 操作系统之上,似乎暗示程序集以某种方式使用操作系统(我没有还没看完整本书...)
哪个是真的?汇编指令只是机器指令吗?它们也可以是由 OS 解释为机器指令的系统调用吗?他们可以是别的东西吗?
大部分是,一行汇编对应一条CPU指令。但也有一些注意事项。
标签定义不对应任何指令 - 它们只是标记内存,以便您可以在其他地方引用它。标签绝对不对应于说明,即使在某些 assemblers 下它们占据单独的行。
数据指令,如 db 0x90
或 .byte 0x90
手动 assemble 字节到输出文件中。在执行将到达的区域中使用此类指令可以让您手动编码指令,或者如果您不小心这样做会产生错误。
汇编程序通常支持指令 - 为 assembler 本身提供一些指导的行。这些与 CPU 指令不对应,有时会被误认为是真正的指令。
一些 assemblers 支持宏 - 想想内联函数。
一些 RISC assemblers,尤其是 MIPS,有组合指令的概念——一行汇编对应少量指令。 (这些被称为伪指令。)它们就像内置宏,由 assembler.
提供
但根据操作数的不同,可能只需要assemble到1条机器指令。例如li $t0, 1
可以 assemble 到 ori $t0, $zero, 1
但 li $t0, 0x55555555
需要 lui
和 ori
(或 addiu
)。
在 ARM 上,ldr r0, =0x5555
可以选择来自文字池的 PC 相关加载或 movw
(如果为支持 movw
的 ARM CPU 进行汇编)一个 16 位立即数。你不会在反汇编中看到 ldr r0, =0x5555
,你会看到 assembler 选择实现它的任何机器指令。 (编者注:我不确定是否有任何 ARM assemblers 会选择 2 条指令(movw
+ movk
)以获得 ldr reg, =value
的更宽常量)
你把过程调用算作"multiple instructions per line"吗?在 Intel 上有 CALL
,在 ARM 上有 BL
。就 CPU 文档而言,这些是单一指令。它们只是在某处存储 return 地址的分支。
但是如果你正在调试和步进 over 函数调用而不是 into 它们,它们会调用一个 procedure/function/subroutine可能包含任意多条指令。系统调用也是如此:像 syscall
或 svc #0
这样的指令基本上是对内核的函数调用。
汇编程序当然可以使用操作系统的服务。您认为常规程序如何做到这一点?高级程序能做的,汇编也能做。但具体情况有所不同。
我正在同时阅读各种关于计算机体系结构的书籍,但我很困惑。有些书说汇编指令只是机器指令的助记符,每条指令恰好对应一条机器指令。但是,Tanenbaum 的 Structured Computer Organization 将程序集放在 层 操作系统之上,似乎暗示程序集以某种方式使用操作系统(我没有还没看完整本书...)
哪个是真的?汇编指令只是机器指令吗?它们也可以是由 OS 解释为机器指令的系统调用吗?他们可以是别的东西吗?
大部分是,一行汇编对应一条CPU指令。但也有一些注意事项。
标签定义不对应任何指令 - 它们只是标记内存,以便您可以在其他地方引用它。标签绝对不对应于说明,即使在某些 assemblers 下它们占据单独的行。
数据指令,如 db 0x90
或 .byte 0x90
手动 assemble 字节到输出文件中。在执行将到达的区域中使用此类指令可以让您手动编码指令,或者如果您不小心这样做会产生错误。
汇编程序通常支持指令 - 为 assembler 本身提供一些指导的行。这些与 CPU 指令不对应,有时会被误认为是真正的指令。
一些 assemblers 支持宏 - 想想内联函数。
一些 RISC assemblers,尤其是 MIPS,有组合指令的概念——一行汇编对应少量指令。 (这些被称为伪指令。)它们就像内置宏,由 assembler.
提供但根据操作数的不同,可能只需要assemble到1条机器指令。例如li $t0, 1
可以 assemble 到 ori $t0, $zero, 1
但 li $t0, 0x55555555
需要 lui
和 ori
(或 addiu
)。
在 ARM 上,ldr r0, =0x5555
可以选择来自文字池的 PC 相关加载或 movw
(如果为支持 movw
的 ARM CPU 进行汇编)一个 16 位立即数。你不会在反汇编中看到 ldr r0, =0x5555
,你会看到 assembler 选择实现它的任何机器指令。 (编者注:我不确定是否有任何 ARM assemblers 会选择 2 条指令(movw
+ movk
)以获得 ldr reg, =value
的更宽常量)
你把过程调用算作"multiple instructions per line"吗?在 Intel 上有 CALL
,在 ARM 上有 BL
。就 CPU 文档而言,这些是单一指令。它们只是在某处存储 return 地址的分支。
但是如果你正在调试和步进 over 函数调用而不是 into 它们,它们会调用一个 procedure/function/subroutine可能包含任意多条指令。系统调用也是如此:像 syscall
或 svc #0
这样的指令基本上是对内核的函数调用。
汇编程序当然可以使用操作系统的服务。您认为常规程序如何做到这一点?高级程序能做的,汇编也能做。但具体情况有所不同。