Assembly 每个机器代码是否必须只能映射到一个装配代码?

Assembly 每个机器代码是否必须只能映射到一个装配代码?,assembly,machine-code,Assembly,Machine Code,假设这两者本质上相同: push 1 及 这表示每个汇编指令都映射到一个机器代码 但是,每个机器代码是否必须只能映射到一个汇编代码?您可以很好地定义一个支持指令“同义词”的汇编程序:如果让用户代码FOO的含义与BAR完全相同,则不会造成任何伤害。我不知道有哪种汇编程序可以做到这一点,但在任何宏汇编程序中,只要使用一个简单的宏,肯定可以达到同样的效果;-) 我不明白为什么不能设计一种汇编语言,其中多个汇编语句映射到底层处理器上的同一操作码 我也看不出有什么特别好的理由这么做,但时间已经晚了,可能

假设这两者本质上相同:

push 1

这表示每个汇编指令都映射到一个机器代码


但是,每个机器代码是否必须只能映射到一个汇编代码?

您可以很好地定义一个支持指令“同义词”的汇编程序:如果让用户代码
FOO
的含义与
BAR
完全相同,则不会造成任何伤害。我不知道有哪种汇编程序可以做到这一点,但在任何宏汇编程序中,只要使用一个简单的宏,肯定可以达到同样的效果;-)

我不明白为什么不能设计一种汇编语言,其中多个汇编语句映射到底层处理器上的同一操作码


我也看不出有什么特别好的理由这么做,但时间已经晚了,可能我遗漏了什么。

即使没有同义词,汇编指令也可以映射到多个机器代码。
例如,
addeax、ebx
可以表示为
03c3
01d8

事实上,这可能很有用,例如用于识别特定的编译器。
您可以在中找到更多示例

在某种程度上,反过来也是正确的。
该示例有点牵强,但相同的机器代码(
F3 90
)映射到x86上的
REP NOP
PAUSE

执行哪一个取决于代码运行的CPU。
尽管故意选择了相同的操作码,并且就处理器状态而言,它们没有区别,而且确切的内部实现在HT(暂停)和非HT(NOP)CPU上可能有所不同

除了与
暂停
vs
REP NOP
几乎没有区别之外,还可以编写难以静态分解的机器代码。
例如,如果拆卸从偏移量0和偏移量1开始,则可以仔细构造机器代码序列,从而产生完全不同的装配指令。

人们还可以编写自我修改的汇编代码,使静态分析变得更加困难。

一般来说,汇编的目的是允许您直接对机器进行编程,而不会对将要执行的操作产生歧义。这几乎需要1:1的映射


如果在某些汇编程序中有一些间接映射,可能用来处理某些处理器行中操作码的更改,我也不会感到惊讶。但是我不知道有什么。

一条特定的机器代码指令的作用是由它的处理器(或处理器系列)决定的。同样的机器代码指令总是做基本相同的事情

通常,一条特定的机器代码指令将只分解为一条语句。在一些更复杂的指令集中,有几种方法可以在汇编程序中编写相同的表达式。一个很好的例子是索引查找。有些语句也可以有同义词,但对处理器来说仍然是相同的意思


但是,一个体系结构可能存在多个完整的装配集。这在x86体系结构中发生过,其中有Intel定义的标准集,然后还有一个基于AT&T创建的标准集,这是GCC使用的标准集。

是的。这方面的一个现实例子是

官方助记符密件抄送中心 结转清算)和BCS(结转分行) 集合)可以重命名为BHS(在 高于或等于)和BLO(分支 在不到),分别。许多的 68000个汇编程序支持这些 替代记忆法


MIPS汇编语言有几个“伪指令”。例如,“move”在内部只是一个带有隐式$0操作数的“add”。

BTW,处理器如何将机器代码按每条指令两个字进行分段?@Mask:如果您的问题是机器代码中是否有一个字节的指令,那么是的,有很多。否。在处理器视图中,所有这些都是一个位序列。它如何知道每条指令的起始位和结束位?@Mask:opcode可以对有关参数及其长度的必要信息进行编码。一个操作码表:一篇关于机器码冗余的文章:@Mask:尽管有一个更好——尽管更长更复杂——的源代码是“英特尔64和IA-32体系结构软件开发人员手册,第2A卷:指令集参考,a-M”,其中一整章专门介绍指令和操作码格式。处理器如何按照每条指令两个字来分割机器代码?机器代码的二进制格式,以及生成该机器代码的汇编语言的语法,是完全不相关的。例如,x86有长度从一个字节到一个字节不等的二进制指令,但每一条指令都是由一条汇编语言指令生成的。在处理器看来,所有指令都是一个位序列。它如何知道每条指令的起始位和结束位呢?@Mask,所有现代处理器都使用字序列(可能包括字节),而不是位。那些具有不同长度指令的指令显然有一些额外的逻辑,因此,根据第一个字节或字,它们知道还需要多少。同样,汇编程序(其工作是读取汇编代码文本并生成二进制机码)与此无关。是的,汇编程序实际上是这样做的。几乎每个x86汇编程序都是为
je
jz
这样做的。它们的意思完全相同,但有时这两种方法中的一种对程序员来说更容易理解。
0x1231