Assembly 汇编指令是否将1-1映射到机器语言?

Assembly 汇编指令是否将1-1映射到机器语言?,assembly,cpu-architecture,machine-code,Assembly,Cpu Architecture,Machine Code,我同时在读各种关于计算机体系结构的书,我很困惑。有些书说汇编指令只是机器指令的助记符,每条指令只对应一条机器指令。然而,Tanenbaum的结构化计算机组织将程序集放在操作系统之上的层上,似乎暗示程序集以某种方式使用操作系统(我还没有读完整本书…) 哪一个是真的?装配说明书仅仅是机器说明书吗?它们也可以是由操作系统解释为机器指令的系统调用吗?它们可能是其他的吗?基本上是的,一行汇编对应一条CPU指令。但也有一些警告 标签定义与任何指令都不对应——它们只是标记内存,以便您可以在其他地方引用它。标签

我同时在读各种关于计算机体系结构的书,我很困惑。有些书说汇编指令只是机器指令的助记符,每条指令只对应一条机器指令。然而,Tanenbaum的结构化计算机组织将程序集放在操作系统之上的层上,似乎暗示程序集以某种方式使用操作系统(我还没有读完整本书…)


哪一个是真的?装配说明书仅仅是机器说明书吗?它们也可以是由操作系统解释为机器指令的系统调用吗?它们可能是其他的吗?

基本上是的,一行汇编对应一条CPU指令。但也有一些警告

标签定义与任何指令都不对应——它们只是标记内存,以便您可以在其他地方引用它。标签肯定与指令不对应,即使在某些汇编程序中,它们占用单独的行

数据指令,如
db 0x90
.byte 0x90
手动将字节组合到输出文件中。在执行将到达的区域中使用这样的指令可以让您手动编码指令,或者在意外情况下创建bug

汇编器通常支持为汇编器本身提供一些指导的指令行。这些指令与CPU指令不对应,有时可能被误认为是真正的命令

有些汇编程序支持宏,比如内联函数


一些RISC汇编程序,特别是MIPS,有一个组合指令的概念——一行汇编指令对应于少数指令。(这些被称为伪指令。)它们类似于汇编程序提供的内置宏

但根据操作数的不同,它可能只需要汇编成1条机器指令。e、 g.
li$t0,1
可以组合成
ori$t0,
0,1
,但是
li$t0,0x555555
需要
lui
ori
(或
addiu

在ARM上,
ldr r0,=0x5555
可以从文字池中选择PC相对负载,如果为支持带16位立即数的
movw
的ARM CPU组装,则可以选择
movw
。在反汇编中,您不会看到ldr r0,=0x5555,您会看到汇编程序选择哪个机器指令来实现它。(编者按:我不确定是否有ARM汇编程序会选择2条指令(
movw
+
movk
)作为
ldr reg,=value
的更宽常量)


您是否将过程调用计算为“每行多条指令”?英特尔有
CALL
,ARM有
BL
。就CPU文档而言,这些是单个指令。它们只是在某处存储回信地址的分支

但是,如果您正在调试和单步执行函数调用,而不是进入函数调用,则它们会调用可能包含任意多条指令的过程/函数/子例程。系统调用也是如此:像
syscall
svc#0
这样的指令基本上是对内核的函数调用


汇编程序肯定可以使用来自操作系统的服务。你认为常规项目是如何做到这一点的?无论高级程序能做什么,汇编也能做什么。但具体情况各不相同。

这取决于您的想法。如果只考虑用户模式程序,并认为系统调用是不透明的“魔术”的东西,那么当然,你可以认为程序集依赖于操作系统。然而,在这种情况下,机器语言对操作系统的依赖程度与对程序集的依赖程度一样。然而,我想指出的是,汇编并不总是用机器代码映射1:1。在某些平台上,同一个组件可以用多种方式组装,尽管通常一种方式更快。@ThomasJager:谢谢。您能否提供一个机器语言如何依赖操作系统的示例?当CPU在x86_64机器上执行字节
0F 05
(的汇编)时,它开始以特权模式运行操作系统代码。根据体系结构,某些汇编指令可能具有多个机器代码编码,反之亦然。但这些都是例外,在日常实践中并不重要。众所周知,汇编程序会对某些指令执行转换。例如,针对8086上16位代码的汇编程序无法发出指令
shl ax,2
。在8086上,一次移位不能超过1位,因此一些汇编器会发出两个
shl
指令,如
shl ax,1
shl ax,1
(这与处理器上的
shl ax,2
支持增强形式的80186是一样的。MIPS不是唯一一个带有伪指令的ISA。我更新了您的答案(希望)更正确。