C& Nasm64组合 - 堆栈对齐,结语,序幕 - OSX 64

时间:2014-10-12 06:03:39

标签: c macos nasm

以下程序导致分段错误,我似乎不明白为什么:

//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。还是有点新手,所以很可能是傻事。

感谢

1 个答案:

答案 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