为什么nasm在寄存器之间汇编MOV指令时使用0x89? [英] Why does nasm use 0x89 when it assembles a MOV instruction between registers?
问题描述
当NASM在两个寄存器之间汇编MOV
指令时,为什么NASM使用0x89操作码(137)?
Why does NASM use 0x89 opcode (137) when it assembles a MOV
instruction between two registers?
以下是使用NASM汇编的代码示例:
Here is an example of code assembled using NASM:
55 push ebp
89E5 mov ebp, esp
83EC04 sub esp, byte +0x4
31C0 xor eax, eax
C9 leave
C3 ret
我想要这样的东西:
55 push ebp
8BEC mov ebp, esp
83EC04 sub esp, byte +0x4
33C0 xor eax, eax
C9 leave
C3 ret
我想要0x8B的原因是:如果您查看MOV
指令的二进制表示形式,则在NASM中看起来像这样:
The reason I wanted 0x8B was: if you view the binary representation of the MOV
instruction, it looks like this in NASM:
Opcode Mod Reg R/M
10001001 11 100 101 (89 E5)
其中令人困惑的部分是reg操作数是第二个.
The confusing part in this is that the reg operand is the second.
NASM语法是这样的:0x89 11 source_reg destination_reg
MOV指令是mov destination_reg, source_reg
The NASM syntax is this: 0x89 11 source_reg destination_reg
and the MOV instruction is mov destination_reg, source_reg
推荐答案
两个操作码是相同的.这就是x86的冗余.汇编器可以选择喜欢的任何东西
The two opcodes are the same. That's x86's redundancy. The assembler can choose whatever it likes
x86体系结构的典型指令具有两个操作码.它们中的第一个具有一个寄存器作为第一个操作数,一个寄存器或一个内存位置作为第二个操作数(在操作码引用中缩写为
"reg, reg/mem32"
,在操作码表中缩写为"Gv, Ev"
).第二个操作码的操作数被反转(缩写为"reg/mem32, reg"
或"Ev, Gv"
).这是有道理的:处理器必须知道它是复制到内存还是从内存复制.但是当两个操作数都是寄存器时,编码就变得多余了:
A typical instruction of x86 architecture has two opcodes. The first of them has a register as the first operand and a register or a memory location as the second one (that's abbreviated
"reg, reg/mem32"
in the opcode reference or"Gv, Ev"
in the opcode table). The operands for the second opcode are reversed (that's abbreviated"reg/mem32, reg"
or"Ev, Gv"
). This makes sense: the processor must know if it copies to the memory, or from the memory. But when both operands are registers, the encoding becomes redundant:
; mod reg r/m
03C3 add eax, ebx ; 11 000 011
01D8 add eax, ebx ; 11 011 000
像这样的reg/reg样式还有很多.在此处
There are much more than just reg/reg style like this. See it here
不同的汇编器发出不同的操作码,因此可以使用此技术识别汇编器
Different assemblers emit different opcodes, so this technique can be used to identify the assembler
一些汇编器允许您选择编码.例如,如果将.s
附加到末尾
Some assemblers allow you to choose the encoding. For example GAS can emit the other encoding if you affix .s
to the end
10 de adcb %bl,%dh
12 f3 adcb.s %bl,%dh
这篇关于为什么nasm在寄存器之间汇编MOV指令时使用0x89?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!