假设这两个本质上是相同的:
push 1
和
0x1231
这表示每个汇编指令都映射到一个机器代码。
但是每个机器代码是否必须只能映射到一个汇编代码?
假设这两个本质上是相同的:
push 1
和
0x1231
这表示每个汇编指令都映射到一个机器代码。
但是每个机器代码是否必须只能映射到一个汇编代码?
MIPS 汇编语言有几个“伪指令”。例如,“move”在内部只是一个带有隐式 $0 操作数的“add”。
您可以完美地定义一个支持指令“同义词”的汇编程序:如果您让用户代码FOO
的含义与BAR
. 我不知道执行此操作的汇编程序的副手,但是您当然可以在任何宏汇编程序中使用非常简单的宏来实现相同的效果;-)。
即使没有同义词,一条汇编指令也可以映射到多个机器代码。
例如add eax, ebx
,可以表示为03 C3
或01 D8
。
事实上,这可能很有用,例如识别特定的编译器。您可以在本文
中找到更多示例。
在某种程度上,反过来也可能是正确的。
这个例子有点牵强,但相同的机器代码 ( F3 90
) 映射到x86REP NOP
或PAUSE
x86 上。
执行哪一个取决于代码运行的 CPU。
尽管故意选择了相同的操作码,并且就处理器状态而言,它们没有区别,执行时间 - 以及确切的内部实现 - 在 HT (PAUSE) 与非 HT (NOP) CPU 上可能有所不同。
除了几乎没有区别的PAUSE
vs之外REP NOP
,还可以编写难以静态反汇编的机器代码。
例如,如果反汇编从偏移量 0 与偏移量 1 开始,则可以仔细构造一个机器代码序列,该序列会导致完全不同的汇编指令。
还可以编写自修改汇编代码以使静态分析更加困难。
是的。一个真实的例子是68k assembler,其中
官方助记词 BCC(branch on carry clear)和 BCS(branch on carry set)可以分别重命名为 BHS(branch on higher or same)和 BLO(branch on less)。许多 68000 汇编器支持这些替代助记符。
我看不出任何概念上的原因,为什么您不能设计一种汇编语言,其中多个汇编语句映射到底层处理器上的相同操作码。
我也没有立即看到任何特别好的理由这样做,但是已经晚了,也许我错过了一些东西。
特定机器代码指令的作用取决于它所使用的处理器(或处理器系列)。并且相同的机器代码指令将始终做同样的事情。
通常,特定的机器代码指令将反汇编为仅一条语句。在一些更复杂的指令集中,有几种方法可以在汇编程序中编写相同的表达式。一个很好的例子是索引查找。有些语句也可以有同义词,但同样,对处理器来说仍然意味着同样的事情。
但是,一个体系结构可能存在多个完整的装配集。x86 架构发生了这种情况,其中有英特尔定义的标准集,然后还有另一个基于 AT&T 创建的标准集,他的标准集是 GCC 使用的。
通常,组装的目的是让您可以直接对机器进行编程,而不会对将要执行的内容产生歧义。这几乎需要 1:1 映射。
如果在某个汇编程序的某个地方有一些间接映射可能用于处理某些处理器行中操作码的更改,我不会感到惊讶。不过我什么都不知道。