Assembly 堆栈框架的基本结构
我目前正在研究堆栈帧,试图了解它是如何工作的。在阅读了几篇文章之后,这些文章总是解释说,总体结构将是:Assembly 堆栈框架的基本结构,assembly,stack,frame,x86-64,stack-frame,Assembly,Stack,Frame,X86 64,Stack Frame,我目前正在研究堆栈帧,试图了解它是如何工作的。在阅读了几篇文章之后,这些文章总是解释说,总体结构将是: 局部变量它相当依赖于编译器。您可以尝试关闭优化或使用“extern”关键字标记函数(强制使用默认调用约定) 使用寄存器是因为这比按堆栈发送参数快得多。有几个问题。首先,这3个参数是通过寄存器传递的,因为这是ELF ABI规范的一部分。我不确定最近(x86-64)的SysV ABI文档保存在哪里(x86-64.org似乎已经不存在)。Agner Fog保存了很多优秀的文档,包括一个关于 调用\u
局部变量它相当依赖于编译器。您可以尝试关闭优化或使用“extern”关键字标记函数(强制使用默认调用约定)
使用寄存器是因为这比按堆栈发送参数快得多。有几个问题。首先,这3个参数是通过寄存器传递的,因为这是ELF ABI规范的一部分。我不确定最近(x86-64)的SysV ABI文档保存在哪里(x86-64.org似乎已经不存在)。Agner Fog保存了很多优秀的文档,包括一个关于 调用
\uuu stack\u check\u fail
,堆栈分配变得复杂,这是作为检测堆栈崩溃/缓冲区溢出的对策添加的。ABI的一部分还规定,在调用函数之前,堆栈必须对齐16字节。如果使用-fno stack protector
重新编译,您将更好地了解发生了什么
此外,因为函数不做任何事情,所以它不是一个特别好的示例。它存储参数(不需要),需要12个字节buffer1
和buffer2
可能是8字节对齐的,实际上分别需要8和16字节,可能还有4个字节来对齐它们。我可能错了-我手头没有规格。这是36或40字节。然后,调用对齐需要对48个字节进行16字节对齐
我认为关闭堆栈保护并检查此叶函数的堆栈框架更具指导意义,并参考x86-64 ABI规范了解局部变量的对齐要求等。感谢您的快速回复。在这种情况下使用寄存器是有意义的。尽管如此,我还是尝试用“gcc-O0-S-masm=intel main.c”关闭优化来组装它,但仍然得到了相同的结果。我想这只是一种方法。尽管如此,我还是想知道在本例中堆栈帧是如何组成的。有人能帮我吗?我在识别堆栈帧中的缓冲区时遇到问题…另外,缓冲区的地址是否也需要存储在堆栈的某个位置?
那里是否会有一堆未使用的空间?
需要注意的是,堆栈分配总是四舍五入到目标体系结构字大小的倍数。除此之外,ABI还可能强制执行对齐要求(例如x64上的16字节要求),这也可能会增加大小。
#include <stdio.h>
void function(int a, int b, int c);
int main()
{
function(1, 2, 3);
return 0;
}
void function(int a, int b, int c)
{
char buffer1[5];
char buffer2[10];
}
# The arguments are pushed onto the stack:
push 3
push 2
push 1
call function # Pushes ret address onto stack and changes IP to function
...
# In function:
# Push old base pointer onto stack and set current base pointer to point to it
push rbp
mov rbp, rsp
# Reserve space for stack frame etc....
buffers <--- SP low address
old BP <--- BP
ret Addr
1
2
3 high address
mov edx, 3
mov esi, 2
mov edi, 1
call function
.cfi_startproc
push rbp
.cfi_def_cfa_offset 16
.cfi_offset 6, -16
mov rbp, rsp
.cfi_def_cfa_register 6
sub rsp, 48
mov DWORD PTR [rbp-36], edi
mov DWORD PTR [rbp-40], esi
mov DWORD PTR [rbp-44], edx
mov rax, QWORD PTR fs:40
mov QWORD PTR [rbp-8], rax
xor eax, eax
mov rax, QWORD PTR [rbp-8]
xor rax, QWORD PTR fs:40
je .L3
call __stack_chk_fail
3 <--- SP
2
1
??
??
old BP <--- BP
return Address
??