为什么C中的这个堆栈变量不在寄存器中



我对如何执行缓冲区溢出攻击以及寄存器分配在编译器中的工作原理有着合理的理解。

让我困惑的是,为什么C程序中有这么多东西在堆栈中。考虑一下这个易受攻击的程序:

#include <stdio.h>
int main() {
int a = 0;
char str[] = "ABC";
gets(str);
printf("int: %d, str: %sn", a, str);
return a;
}

让我们运行

> gcc run.c
> ./a.out asdfasdf
int: 1717859169, str: asdfasdf

好的,所以str被覆盖为int a。但为什么int a甚至在堆栈上?做一些类似(x86 asm(的事情不是最容易吗

.global _main
.text
_main:
// omitting the gets() stuff
movq $0, %rax
retq

现在我们的内存流量减少了,因为堆栈上什么都没有,代码也减少了很多。

tl;dr为什么int a在堆栈上?

根据我帖子上的评论。发生这种情况是因为我在没有优化的情况下进行编译,而当我使用优化gcc -O3 run.c进行编译时,我不会看到相同的行为。

以下是一些优化的组装

> gcc -o run -O3 run.c
> objdump -d run
...
// Set eax = 0
100003f5c: 31 c0                        xorl    %eax, %eax  
100003f5e: 48 83 c4 08                  addq    $8, %rsp
100003f62: 5b                           popq    %rbx
100003f63: 5d                           popq    %rbp
// Return 0
100003f64: c3                           retq                

还有更复杂的未优化:

...
// put 0 on the stack
100003f33: c7 45 f8 00 00 00 00         movl    $0, -8(%rbp) the stack
...
// take it off the stack and into ecx
100003f61: 8b 4d f8                     movl    -8(%rbp), %ecx 
100003f64: 89 45 e4                     movl    %eax, -28(%rbp)
100003f67: 89 c8                        movl    %ecx, %eax
100003f69: 48 83 c4 20                  addq    $32, %rsp
100003f6d: 5d                           popq    %rbp
// return 0
100003f6e: c3                           retq   

最新更新