Objdump hello world call calls

时间:2015-04-20 01:50:38

标签: x86 objdump

这个简单的问候世界:

#include <stdio.h>
int main(void) {
  printf("Hello, world!\n");
  printf("Hello, world!\n");
  return 0;
}

在objdump中提供以下程序集:

    /helloworld.c:3
     804842c:       83 ec 0c                sub    $0xc,%esp
     804842f:       68 f0 84 04 08          push   $0x80484f0
     8048434:       e8 b7 fe ff ff          call   80482f0 
     8048439:       83 c4 10                add    $0x10,%esp
    /helloworld.c:4
     804843c:       83 ec 0c                sub    $0xc,%esp
     804843f:       68 f0 84 04 08          push   $0x80484f0
     8048444:       e8 a7 fe ff ff          call   80482f0 
     8048449:       83 c4 10                add    $0x10,%esp
  • 为什么对put的同一调用有不同的十六进制代码( b7 vs a7 )?
  • e8 是通话部分,但 b7 fe ff ff 如何转换为 80482f0

2 个答案:

答案 0 :(得分:1)

call rel32指令:调用near,相对于下一条指令的位移

此指令的操作码为E8,后跟由以下等式计算的相对偏移量:destination address - address of next instruction

在这种情况下,第一个呼叫的相对偏移量为80482f0 - 8048439 = FFFFFEB7,第二个呼叫的相对偏移量为80482f0 - 8048449 = FFFFFEA7

答案 1 :(得分:1)

E8操作码属于CALL指令,其地址相对于CALL指令本身的地址。它使用PC relative addressing。因此,您所看到的函数地址实际上是从下一条指令的地址到printf函数起始地址的偏移量。

顺便说一句,英特尔使用小端,因此必须将这些偏移分别读为带符号的32位整数FFFFFEB7FFFEA7。这意味着printf函数位于相对于主程序的较低地址。

您还可以看到,这两个偏移的差异是从一个CALL指令到另一个指令的字节差异,因为第二个CALL将距离{{1}的开头更远比第一个。

printf