我想了解堆栈内存页面究竟是如何分配/分配。
我写了下面的证明了概念的C代码,这显然会导致分段错误(在x86_64的Linux):
#include <string.h>
int main()
{
char a;
memset( (&a - 4444444), 0, 3333333 );
return 0;
}
汇编代码下面的片段(AT&T的语法)是通过从上述C-程序GCC产生:
subq $16, %rsp
leaq -1(%rbp), %rax
subq $4444444, %rax
movl $3333333, %edx
movl $0, %esi
movq %rax, %rdi
call memset
如果我添加subq $5555555, %rsp
调用之前手动memset
:
subq $16, %rsp
leaq -1(%rbp), %rax
subq $4444444, %rax
movl $3333333, %edx
movl $0, %esi
movq %rax, %rdi
subq $5555555, %rsp /* added manually */
call memset
然后分割故障消失,因为堆栈的虚拟内存页面被扣除后分配rsp
寄存器造成了一定的硬件异常和分配异常处理程序被调用(当然,在内核空间)。
我知道打电话memset
这里将造成“小缺页”异常。 但它是一个不同的故事(即分配的物理内存页)。
我的问题是:当产生哪些异常subq $5555555, %rsp
调用? 我认为这将是“堆栈错误”异常,但我没有找到它确切的证据。