序言函数的差异

时间:2017-03-09 19:17:06

标签: c gcc assembly

我正在阅读 Haching:利用的艺术,我发现我的编译代码和书中的代码有所不同。

代码:

void test_function(int a, int b, int c, int d) {

   int flag;
   char buffer[10];

   flag = 31337;
   buffer[0] = 'A';
}

int main() {

   test_function(1, 2, 3, 4);
}

在书中他使用gcc编译gcc和disassembles,我不知道软件的版本。 他使用命令:

gcc -g program.c
gdb -q ./a.out

然后他做了:

(gdb) disass main 
Dump of assembler code for function main(): 
0x08048357 <main+0>:    push   ebp 
0x08048358 <main+1>:    mov    ebp,esp 
0x0804835a <main+3>:    sub    esp,0x18 
0x0804835d <main+6>:    and    esp,0xfffffff0 
0x08048360 <main+9>:    mov    eax,0x0 
0x08048365 <main+14>:   sub    esp,eax 
0x08048367 <main+16>:   mov    DWORD PTR [esp+12],0x4 
0x0804836f <main+24>:   mov    DWORD PTR [esp+8],0x3 
0x08048377 <main+32>:   mov    DWORD PTR [esp+4],0x2 
0x0804837f <main+40>:   mov    DWORD PTR [esp],0x1 
0x08048386 <main+47>:   call   0x8048344 <test_function> 
0x0804838b <main+52>:   leave  
0x0804838c <main+53>:   ret    

End of assembler dump
(gdb) disass test_function() 
Dump of assembler code for function test_function: 
0x08048344 <test_function+0>:   push   ebp 
0x08048345 <test_function+1>:   mov    ebp,esp 
0x08048347 <test_function+3>:   sub    esp,0x28 
0x0804834a <test_function+6>:   mov    DWORD PTR [ebp-12],0x7a69 
0x08048351 <test_function+13>:  mov    BYTE PTR [ebp-40],0x41 
0x08048355 <test_function+17>:  leave  
0x08048356 <test_function+18>:  ret    

相反,这是我的输出(使用相同的命令):

(gdb) disass main
Dump of assembler code for function main:
   0x000000000040058b <+0>: push   rbp
   0x000000000040058c <+1>: mov    rbp,rsp
   0x000000000040058f <+4>: mov    ecx,0x4
   0x0000000000400594 <+9>: mov    edx,0x3
   0x0000000000400599 <+14>:    mov    esi,0x2
   0x000000000040059e <+19>:    mov    edi,0x1
   0x00000000004005a3 <+24>:    call   0x400546 <test_function>
   0x00000000004005a8 <+29>:    mov    eax,0x0
   0x00000000004005ad <+34>:    pop    rbp
   0x00000000004005ae <+35>:    ret    
End of assembler dump.

(gdb) disass test_function 
Dump of assembler code for function test_function:
   0x0000000000400546 <+0>: push   rbp
   0x0000000000400547 <+1>: mov    rbp,rsp
   0x000000000040054a <+4>: sub    rsp,0x40
   0x000000000040054e <+8>: mov    DWORD PTR [rbp-0x34],edi
   0x0000000000400551 <+11>:    mov    DWORD PTR [rbp-0x38],esi
   0x0000000000400554 <+14>:    mov    DWORD PTR [rbp-0x3c],edx
   0x0000000000400557 <+17>:    mov    DWORD PTR [rbp-0x40],ecx
   0x000000000040055a <+20>:    mov    rax,QWORD PTR fs:0x28
   0x0000000000400563 <+29>:    mov    QWORD PTR [rbp-0x8],rax
   0x0000000000400567 <+33>:    xor    eax,eax
   0x0000000000400569 <+35>:    mov    DWORD PTR [rbp-0x24],0x7a69
   0x0000000000400570 <+42>:    mov    BYTE PTR [rbp-0x20],0x41
   0x0000000000400574 <+46>:    nop
   0x0000000000400575 <+47>:    mov    rax,QWORD PTR [rbp-0x8]
   0x0000000000400579 <+51>:    xor    rax,QWORD PTR fs:0x28
   0x0000000000400582 <+60>:    je     0x400589 <test_function+67>
   0x0000000000400584 <+62>:    call   0x400420 <__stack_chk_fail@plt>
   0x0000000000400589 <+67>:    leave  
   0x000000000040058a <+68>:    ret    
End of assembler dump.

我正在使用gcc版本5.4.0和gdb版本7.11.1。

我有两个问题:

  • 为什么功能扩展不同?书编译器给出的指令和我给出的指令有什么不同? (我不是在谈论登记册的名称,我在谈论为什么我的主要序言只是推动和移动)

  • 由于可能的堆栈溢出而导致test_function的区别和编译器(比其他编译器更新)知道并修补它吗?如果是这样,它如何知道存在缺陷以及它采用什么方法来修补它?

编辑:我知道图书版本是在32位架构上编译的。我的问题是关于编译器的不同指令,如果他们必须做同样的事情,为什么它们不同?

1 个答案:

答案 0 :(得分:1)

本书版本是在32位架构上编译的,您的版本是64位。使用-m32开关生成32位可执行文件。