以下程序导致分段错误,我似乎不明白为什么:
//something.c
int somefunc3();
void somefunc2();
void* globalptr;
void somefunc1(void* regs)
{
globalptr = regs;
somefunc2();
}
int foo()
{
return somefunc3();
}
int main(void)
{
show_all_registers();
foo();
show_all_registers();
}
ASM:
//something1.asm
extern _somefunc1
global _somefunc2
global _somefunc3
section .text
%macro RESTORE_REGISTERS 0
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
pop rcx
%endmacro
%macro SAVE_REGISTERS 0
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
push rcx
%endmacro
_somefunc3:
push rbp
mov rbp, rsp
SAVE_REGISTERS
mov rdi, rsp
sub rsp,8
call _somefunc1
add rsp,8
pop rbp
ret
_somefunc2:
push rbp
mov rbp, rsp
RESTORE_REGISTERS
pop rbp
ret
几点说明:
请不要试图了解这个程序的功能,因为你找不到任何有意义的东西。这只是我创建的用户模式应用程序,用于理解某些内容。
show_all_registers只是一个向屏幕输出所有64位寄存器的函数。
以下是崩溃之前发生的事情:
64 Bit registers:
RAX=10767ad00, RCX=1, RDX=10767ab70, RBX=0, RSP=7fff58585bd0, RBP=7fff58585bd0, RSI=20000000200, RDI=7
Segmentation fault: 11
使用GDB似乎崩溃发生在somefunc2上(当恢复寄存器时)
我认为它与堆栈对齐或者epilogues&我为ASM函数写的epilogues。还是有点新手,所以很可能是傻事。
感谢
答案 0 :(得分:0)
您的功能结果不正确。您错过了mov rsp, rbp
,因此您的堆栈帧在返回时完全关闭。
正确的功能是:
push rbp
mov rbp, rsp
sub rsp, [size of local variables]
...
mov rsp, rbp
pop rbp
ret
或者您可以使用LEAVE
指令进行简化:
push rbp
mov rbp, rsp
sub rsp, [size of local variables]
...
leave
ret