生成的程序集用于堆栈变量的扩展对齐 [英] Generated assembly for extended alignment of stack variables
问题描述
我正在研究对基于堆栈的变量使用扩展对齐的代码汇编.这是该代码的较小版本
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屋!