生成的程序集用于堆栈变量的扩展对齐 [英] Generated assembly for extended alignment of stack variables

查看:103
本文介绍了生成的程序集用于堆栈变量的扩展对齐的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在研究对基于堆栈的变量使用扩展对齐的代码汇编.这是该代码的较小版本

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);
}

使用clang 8.0编译时,它会生成以下代码( https://godbolt.org/z/lf8WW- )

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

早期版本的gcc会产生以下内容( https://godbolt.org/z/LLQ8gW).从gcc 8.1开始,两者都产生相同的代码

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

出于好奇,我对x86不太熟悉-这两段代码中到底发生了什么?

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?

推荐答案

这里没什么神奇的.逐行:

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

这篇关于生成的程序集用于堆栈变量的扩展对齐的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆