- 此问题在此处已有答案**:
How to read x86 instruction tables from this site(1个答案)
How to tell the length of an x86 instruction?(6个答案)
How to determine if ModR/M is needed through Opcodes?(1个答案)
x86_64 Opcode encoding formats in the intel manual(1个答案)
How to read the Intel Opcode notation(3个答案)
22小时前关门了。
我无法理解一条非常基本的x86指令。
0x080491d7 <+1>: mov %esp,%ebp
我知道它会把esp的值移到ebp中,但是我正在努力理解操作码,这个指令是2个字节长,而不是1个字节长,我很困惑,我本以为它只有1个字节。
此指令的内存为:
0x80491d7 <main+1>: 0x89 0xe5
我知道0x89
是操作码for MOV之一。我一直在阅读英特尔手册。我不知道0xe5
是什么。它是一个后缀还是另一个操作码值还是其他什么?英特尔手册有点混乱。
c程序针对x86 32位进行编译,Linux服务器为x86_64。
2条答案
按热度按时间mftmpeh81#
该指令是2字节长,而不是1,我感到困惑。
是得,查看Intel Developer Manual volume 2中mov指令得说明,可以看到编码为
8B /r
,根据3.1.1.1“指令汇总表中得操作码列”一章,它具有以下含义:/r — Indicates that the ModR/M byte of the instruction contains a register operand and an r/m operand.
因此,第二个字节是ModR/M字节。其含义可在表2-2“ModR/M字节的32位寻址形式”中找到。fhg3lkii2#
我知道0x89是MOV的操作码之一。我一直在阅读英特尔手册。我不知道0xe5是什么。它是像一个后缀或另一个操作码值或其他东西?英特尔手册有点混乱。
您发现
mov %esp, %ebp
指令使用2个字节进行编码:0x89和0xE5的值。参考英特尔手册是正确的做法,但我建议使用正确的英特尔语法
mov ebp, esp
查看您的指令。这可能会使您避免在解释操作码表时出现意外错误。在单字节操作码表中查找89h,您会看到表中提到的"Ev,Gv"。
"使用操作码表"一章解释了这些字符组合的含义。
E---ModR/M字节跟在操作码后面,指定操作数。
v---字或双字,具体取决于操作数大小属性。
,---通常是分隔逗号。
G--ModR/M字节内的寄存器字段选择通用寄存器。
因此第二个字节是ModR/M字节。
您的ModR/M字节是E5h或11 '100' 101b,以二进制表示法表示,紧跟在分组'mod-reg-r/m'之后。
哪些寄存器?为此,我们看一下操作码89h或100010'0 '1b(二进制表示法,跟随在' TTTTTT-d-w '分组之后)。
位0(w)告诉我们这是一个(d)字长的操作(与上面提到的"v"一致)。由于这是32位代码,并且没有使用操作数大小前缀(0x66),因此剩下的是
ESP/EBP
。位1(d)告诉我们哪个操作数是源操作数还是目的操作数(这与上面提到的"E,G"一致)。由于该位为0,所以reg字段(ESP)表示源和r/m字段(EBP)表示目的地。如果设置了d位,则相反,表示字节0x8B,0xEC也是您指令
mov %esp, %ebp
的完美编码。