最近,我利用了一个危险的程序,发现了x86-64体系结构上gcc版本之间的不同之处。
Note:
gets是而不是的问题。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,我的问题是:,在反汇编的代码上产生这种差异的原因是什么及其好处?它有这个技术的名字吗?
发布于 2016-12-23 16:40:59
如果没有实际值,我就不能肯定地说:
and esp, 0xXX # XX is a number但是,这看起来很像额外的代码,用于将堆栈对齐到比ABI所要求的更大的值。
编辑:值为- 16,这是32位0xFFFFFFF0或64位0xFFFFFFFFFFFFFFF0,因此这确实是堆栈对齐16字节,可能意味着使用SSE指令。正如注释中提到的,在>= 4.9.0版本中有更多的代码,因为它还对框架指针,而不仅仅是堆栈指针。
https://stackoverflow.com/questions/41302625
复制相似问题