最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c - Understanding the x86_64 call instruction on a 64bit system - Stack Overflow

programmeradmin4浏览0评论

I'm exploring some disassembled C programs with godbolt and I am having trouble wrapping my head around the x86_64 "call" instruction.

With the C code:

int func(int i)
{
    return i + 1;
}

int main(void)
{
    int i = 5;
    i = func(i);
    return 0;
}

I get the equivalent assembly code:

func:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], edi
        mov     eax, DWORD PTR [rbp-4]
        add     eax, 1
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 5
        mov     eax, DWORD PTR [rbp-4]
        mov     edi, eax
        call    func
        mov     DWORD PTR [rbp-4], eax
        mov     eax, 0
        leave
        ret

I have read that when I do call func the return address is pushed onto the stack. Because this is 64 bit assembly I would assume that this address would be 64 bits wide (i.e 8 bytes). However when investigating the assembly for func the line mov DWORD PTR [rbp-4], edi seems to imply that there are only 4 bytes for the return address as [rbp-4] would be 4 bytes past the base pointer of the stack frame. I have a feeling I am fundamentally misunderstanding what is going on here and I was hoping to get some guidance.

I expected mov DWORD PTR [rbp-8], edi but was given mov DWORD PTR [rbp-4], edi

I'm exploring some disassembled C programs with godbolt and I am having trouble wrapping my head around the x86_64 "call" instruction.

With the C code:

int func(int i)
{
    return i + 1;
}

int main(void)
{
    int i = 5;
    i = func(i);
    return 0;
}

I get the equivalent assembly code:

func:
        push    rbp
        mov     rbp, rsp
        mov     DWORD PTR [rbp-4], edi
        mov     eax, DWORD PTR [rbp-4]
        add     eax, 1
        pop     rbp
        ret
main:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 16
        mov     DWORD PTR [rbp-4], 5
        mov     eax, DWORD PTR [rbp-4]
        mov     edi, eax
        call    func
        mov     DWORD PTR [rbp-4], eax
        mov     eax, 0
        leave
        ret

I have read that when I do call func the return address is pushed onto the stack. Because this is 64 bit assembly I would assume that this address would be 64 bits wide (i.e 8 bytes). However when investigating the assembly for func the line mov DWORD PTR [rbp-4], edi seems to imply that there are only 4 bytes for the return address as [rbp-4] would be 4 bytes past the base pointer of the stack frame. I have a feeling I am fundamentally misunderstanding what is going on here and I was hoping to get some guidance.

I expected mov DWORD PTR [rbp-8], edi but was given mov DWORD PTR [rbp-4], edi

Share Improve this question asked yesterday BatterySodaBatterySoda 211 bronze badge New contributor BatterySoda is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct. 3
  • 1 In the used system sizeof( int ) is equal to 4. So in this statement mov DWORD PTR [rbp-4], edi there is reserved 4 bytes for the parameter of the type int passed to the function through the register edi. – Vlad from Moscow Commented yesterday
  • @VladfromMoscow, That makes perfect sense I'm not too sure what I was thinking. – BatterySoda Commented yesterday
  • 1 The return address is above the base pointer, not below. The stack grows downwards. – BoP Commented yesterday
Add a comment  | 

1 Answer 1

Reset to default 2

However when investigating the assembly for func the line mov DWORD PTR [rbp-4], edi seems to imply that there are only 4 bytes for the return address as [rbp-4] would be 4 bytes past the base pointer of the stack frame.

No. That mov instruction has nothing to do with the return address. It is about argument passing. In particular, it copies the value passed to parameter i into the func's stack frame.

I have a feeling I am fundamentally misunderstanding what is going on here and I was hoping to get some guidance.

Yes. The call instruction pushes the return address onto the stack, including updating the stack pointer. When func executes mov rbp, rsp, that sets its frame pointer past the return address, regardless of the size of that address (and also past the stored value of the caller's frame pointer, which func pushed on top). After that, [rbp-4] is the address of the first 4-byte word in func's stack frame.

发布评论

评论列表(0)

  1. 暂无评论