7
0x004012d0 <main+0>:    push   %ebp
0x004012d1 <main+1>:    mov    %esp,%ebp
0x004012d3 <main+3>:    sub    $0x28,%esp

如果地址不可用,我们可以自己计算吗?

我的意思是我们只有这个:

push   %ebp
mov    %esp,%ebp
sub    $0x28,%esp
4

5 回答 5

6

字节数是相邻指令之间的地址差:

0x004012d0 <main+0>:    push   %ebp ;1 byte
0x004012d1 <main+1>:    mov    %esp,%ebp ;2 bytes
0x004012d3 <main+3>:    sub    $0x28,%esp

如果您只有文本,请转到此处:http ://www.swansontec.com/sintel.html 和此处:http: //faydoc.tripod.com/cpu/conventions.htm并计算每条指令、前缀和操作数

于 2010-03-30T16:10:35.823 回答
3

您不一定能从助记符中确定指令大小。以下是一些特殊情况:

  • 如果您在 16 位段中,则mov eax, 0需要0x66前缀,而在 32 位段中则不需要。您需要知道段的大小。

  • 在 32 位或 16 位模式下,您可以编码add eax, 10x40( inc eax) 或0x83 0xc0 0x01( add eax, 1)。也就是说,有一些助记符可以用不止一种方式编码。

  • 内存操作数[eax]可以编码eax为基数或索引。如果它是索引,您将在 MOD/RM 之后有一个额外的 SIB 字节。

  • 在 64 位模式下,您可以使用 REX 前缀0x4x对寄存器进行编码r8- r15。但是,您可以将0x40其用作某种空 REX 字节,这将为您的指令添加另一个字节。

  • 即使显式段与隐式段相同,也可以使用段覆盖。

还有许多其他方法可以使用更多或更少的字节对指令进行编码。一个好的汇编器应该总是使用最短的,但架构肯定不需要它。好消息是,如果您学习英特尔 IA-32 软件开发人员手册第 2 卷,您应该能够自己解决。

于 2010-05-03T21:12:10.633 回答
1

第一条指令位于 [main+0] 处,第二条位于 [main+1] 处,因此第一条指令为 1 个字节。第三条指令在 [main+3],所以第二条指令是两个字节。您无法从清单中看出第三条指令有多长,因为它没有显示 4. 指令的地址。

于 2010-03-30T16:40:39.143 回答
0

如果可能,让汇编器生成一个列表。这将显示您的源代码,接下来是指令的二进制表示,您需要做的就是计算有多少字节,然后得到大小。

于 2014-08-24T01:43:40.853 回答
0

如果您有文本形式的汇编代码,则必须使用汇编程序来获取
二进制表示,从而获得指令的大小。当然,这取决于硬件。

例如,这是一个80x86 32 位汇编器开源代码OllyDbg v1.10)。

于 2010-03-30T16:37:19.567 回答