Generated assembly for extended alignment of stack variables [duplicate]

前提是你 提交于 2019-12-11 15:13:35

问题


I was digging into the assembly of code that was using extended alignment for a stack-based variable. This is a smaller version of the code

struct Something {
    Something();
};

void foo(Something*);

void bar() {
    alignas(128) Something something;
    foo(&something);
}

This, when compiled with clang 8.0 generates the following code (https://godbolt.org/z/lf8WW-)

bar():                                # @bar()
        push    rbp
        mov     rbp, rsp
        and     rsp, -128
        sub     rsp, 128
        mov     rdi, rsp
        call    Something::Something() [complete object constructor]
        mov     rdi, rsp
        call    foo(Something*)
        mov     rsp, rbp
        pop     rbp
        ret

And earlier versions of gcc produce the following (https://godbolt.org/z/LLQ8gW). Starting gcc 8.1, both produce the same code

bar():
        lea     r10, [rsp+8]
        and     rsp, -128
        push    QWORD PTR [r10-8]
        push    rbp
        mov     rbp, rsp
        push    r10
        sub     rsp, 232
        lea     rax, [rbp-240]
        mov     rdi, rax
        call    Something::Something() [complete object constructor]
        lea     rax, [rbp-240]
        mov     rdi, rax
        call    foo(Something*)
        nop
        add     rsp, 232
        pop     r10
        pop     rbp
        lea     rsp, [r10-8]
        ret

I'm not too familiar with x86 and just out of curiosity - what exactly is happening here in both pieces of code? Does the compiler pull tricks like std::align() and round up the current stack position to a multiple of 128 for the on-stack variable something?


回答1:


Nothing magical here. Line-by-line:

bar():                                # @bar()
        push    rbp ; preserve base pointer
        mov     rbp, rsp ; set base poiner
        and     rsp, -128 ; Anding with -128 aligns it on 128 boundary
        sub     rsp, 128 ; incrementing stack grows down, incrementing it gives us the space for new object
        mov     rdi, rsp ; address of the new (future) object is passed as an argument to the constructor, in %RDI
        call    Something::Something() [complete object constructor] # call constructor
        mov     rdi, rsp ; callee might have changed %RDI, so need to restore it
        call    foo(Something*) ; calling a function given it address of fully constructed object
        mov     rsp, rbp ; restore stack pointer
        pop     rbp ; restore base pointer
        ret


来源:https://stackoverflow.com/questions/57298598/generated-assembly-for-extended-alignment-of-stack-variables

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!