装配分析问题

时间:2011-03-29 03:13:51

标签: assembly gdb

(gdb) l main
1   #include <stdio.h>
2   
3   int main(void)
4   {
5       int i = 6;
6       printf("%d",sizeof(unsigned short));
7       return 0;
8   }
(gdb) disas main
Dump of assembler code for function main:
0x0000000000400498 <main+0>:    push   %rbp
0x0000000000400499 <main+1>:    mov    %rsp,%rbp
0x000000000040049c <main+4>:    sub    $0x10,%rsp
0x00000000004004a0 <main+8>:    movl   $0x6,-0x4(%rbp)
0x00000000004004a7 <main+15>:   mov    $0x2,%esi
0x00000000004004ac <main+20>:   mov    $0x4005c8,%edi
0x00000000004004b1 <main+25>:   mov    $0x0,%eax
0x00000000004004b6 <main+30>:   callq  0x400398 <printf@plt>
0x00000000004004bb <main+35>:   mov    $0x0,%eax
0x00000000004004c0 <main+40>:   leaveq 
0x00000000004004c1 <main+41>:   retq   

我有两个疑问:

  1. 对于int i = 6,只需要4个字节,为什么分配16个字节?
  2. 某些函数使用堆栈传递参数(push xxx),但为什么printf使用esiedi来执行此操作?
  3. 更新

    似乎printf未从esiedi获取:

    (gdb) disas printf
    Dump of assembler code for function printf@plt:
    0x0000000000400398 <printf@plt+0>:  jmpq   *0x2004c2(%rip)        # 0x600860 <_GLOBAL_OFFSET_TABLE_+24>
    0x000000000040039e <printf@plt+6>:  pushq  $0x0
    0x00000000004003a3 <printf@plt+11>: jmpq   0x400388
    

2 个答案:

答案 0 :(得分:3)

  

为什么是16个字节

因为x86_64 ABI要求堆栈在调用指令

之前是16字节对齐的
  

为什么printf使用esi和edi

因为x86_64 ABI指定在rdirsirdxrcxr8r9中传递(前6个)整数参数, {{1}}注册。

答案 1 :(得分:1)

  1. int应为4个字节,堆栈帧指针为8个字节(rbp为64位寄存器),返回值为4个字节(堆栈中)。

  2. 我没有亲眼目睹它(我是老学校:P),但我听说这是一种推动价值观的新方法。通过直接将值存储到堆栈,它应该更快。