2016-12-23 174 views
1

我最近利用了一个危险的程序,发现了x86-64架构上的gcc版本之间的差异。gcc版本> = 4.9.0与gcc版本<4.9的改进的原因和好处?

注意:中gets

  1. 不当使用是这里的问题。

  2. 如果我们用其他函数代替gets,问题不会改变。


这是源代码使用:

#include <stdio.h> 
int main() 
{ 
    char buf[16]; 
    gets(buf); 
    return 0; 
} 

我使用gcc.godbolt.org与标志-m32 -fno-stack-protector -z execstack -g拆卸程序。

在反汇编代码,当gcc与版本> = 4.9.0

lea  ecx, [esp+4]   # begin of main 
and  esp, -16 
push DWORD PTR [ecx-4]  # push esp 
push ebp 
mov  ebp, esp 
/* between these comment is not related to the question 
push ecx 
sub  esp, 20 
sub  esp, 12 
lea  eax, [ebp-24] 
push eax 
call gets 
add  esp, 16 
mov  eax, 0 
*/ 
mov  ebp, esp    
mov  ecx, DWORD PTR [ebp-4] # ecx = saved esp 
leave 
lea  esp, [ecx-4] 
ret        # end of main 

但随着版本的GCC < 4.9.0刚:

push ebp      # begin of main 
mov  ebp, esp 
/* between these comment is not related to the question 
and  esp, -16 
sub  esp, 32 
lea  eax, [esp+16] 
mov  DWORD PTR [esp], eax 
call gets 
mov  eax, 0 
*/ 
leave 
ret        # end of main 

我的问题是:什么是cau反汇编代码和它的好处有哪些差异?它有这个技术的名字吗?

+1

注意:[不要使用'gets()',这很危险](http://stackoverflow.com/q/1694036/2173917)。改用['fgets()'](https://linux.die.net/man/3/fgets)。 –

+1

这是优化结果 –

+2

不同的编译器配置。使用'gcc -v'来比较配置 – LPs

回答

0

我不能肯定地说没有实际值:

and  esp, 0xXX    # XX is a number 

但是这看起来很像额外的代码堆栈对齐到更大的值比ABI要求。

编辑:值是-16,这是32位0xFFFFFFF0或64位0xFFFFFFFFFFFFFFF0所以这确实是堆栈对齐到16个字节,可能意味着使用SSE指令。正如评论中所提到的,在> = 4.9.0版本中有更多的代码,因为它也对齐了帧指针而不是只有堆栈指针。

+0

对不起,我用'0xXX'替换'-16'是我的错误。很抱歉 ! – lzutao

+0

@lzutao然后它是堆栈对齐码。 – Olivier

+0

谢谢。但它也有与海湾合作委员会版本<** 4.9.0 ** – lzutao