汇编代码中的静态值(Static Values in Assembler Code)

我有以下简单的代码:

#include <cmath> struct init_sin { typedef double type; static constexpr type value(int index) { return 3*std::pow(std::sin(index * 2.0 * 3.1415 / 20.0),1.999); } }; int main(){ static double VALUE = init_sin::value(10); double VALUE_NONSTAT = 3*std::pow(std::sin(10 * 2.0 * 3.1415 / 20.0),1.999); return int(VALUE_NONSTAT); }

我想知道汇编代码的含义是什么。 这里是组件的链接: http : //pastebin.com/211AfSYh 我认为VALUE是计算的编译时间,并直接作为汇编程序代码中的值,如果我没有弄错的话应该在这一行中:

33 .size main, .-main 34 .data 35 .align 8 36 .type _ZZ4mainE5VALUE, @object GAS LISTING /tmp/ccbPDNK8.s page 2 37 .size _ZZ4mainE5VALUE, 8 38 _ZZ4mainE5VALUE: 39 0000 15143B78 .long 2017137685 40 0004 45E95B3E .long 1046210885 为什么.long有两个值? 为什么这些类型很长? (它是一个双重?,也许在汇编程序中只有很长时间。 这是否意味着VALUE是生成的编译时间 VALUE_NON_STATIC的结果在哪里? 这应该在运行时计算得对吗? 我不太清楚在哪里?

非常感谢!

I have the following simple code:

#include <cmath> struct init_sin { typedef double type; static constexpr type value(int index) { return 3*std::pow(std::sin(index * 2.0 * 3.1415 / 20.0),1.999); } }; int main(){ static double VALUE = init_sin::value(10); double VALUE_NONSTAT = 3*std::pow(std::sin(10 * 2.0 * 3.1415 / 20.0),1.999); return int(VALUE_NONSTAT); }

I would like to find out what the meaning of the assembler code is of this given piece. Here the link to the assembly: http://pastebin.com/211AfSYh I thought that VALUE is compile time computed and directly as value in the assembler code Which should be in this line if I am not mistaken:

33 .size main, .-main 34 .data 35 .align 8 36 .type _ZZ4mainE5VALUE, @object GAS LISTING /tmp/ccbPDNK8.s page 2 37 .size _ZZ4mainE5VALUE, 8 38 _ZZ4mainE5VALUE: 39 0000 15143B78 .long 2017137685 40 0004 45E95B3E .long 1046210885 Why are there two values with .long ? And why are the types long? (its a double?, maybe in assembler there is only long. Does that mean that the value of VALUE was compile time generated Where is the result for VALUE_NON_STATIC? This should be computed during run-time right? I cannot quite see where?

Thanks a lot!

最满意答案

这个汇编语法中的.long意味着一个32位的数字。 因为double是64位,所以你看到的是两个32位的VALUE ,它们的double表示。 您还会注意到它正在与8字节边界(通过.align语句)对齐,并且它的大小为8(通过.size语句)。 此外,它位于主.data段中,通常用于初始化为零的全局范围变量(作为旁注, .bss通常用于零初始化的全局范围变量)。

可以看到VALUE_NONSTAT被加载到%rax这里,这是AX寄存器的64位版本:

V 20 0004 48B81514 movabsq $4493441537811354645, %rax 20 3B7845E9 20 5B3E

回想一下15143B7845E95B3E表示3*std::pow(std::sin(index * 2.0 * 3.1415 / 20.0),1.999)当存储在double ,你可以看到以十六进制开始的内部值我插了一个V

稍后语句然后将其推入堆栈( movq %rax, -8(%rbp) ),然后将其加载到FP寄存器( movsd -8(%rbp), %xmm0 ),然后将其转换为整数并将其存储在%eax ,它是返回值的寄存器( cvttsd2si %xmm0, %eax ),然后使用ret从例程返回。

在任何情况下,在您正在使用的优化级别(可能在下面),您的编译器已经发现VALUE_NONSTAT是一个常量表达式,而只是在编译时将其内联,因为该值在编译时是完全已知的。

.long in this assembler syntax implies a 32-bit number. Because a double is 64-bits, what you're seeing there is the two 32-bit parts of VALUE, in their double representation. You'll also notice above it that it's being aligned to an 8-byte boundary (through the .align statement) and that it's size is 8 (through the .size statement). Also, it's in the main .data segment, which is typically used for global-scope variables which are not initialised to zero (as a side-note, .bss is typically used to zero-initialised global scope variables).

The VALUE_NONSTAT can be seen being loaded into %rax here, which is the 64-bit version of the AX register:

V 20 0004 48B81514 movabsq $4493441537811354645, %rax 20 3B7845E9 20 5B3E

Recalling that 15143B7845E95B3E is the representation of the value of 3*std::pow(std::sin(index * 2.0 * 3.1415 / 20.0),1.999) when stored in a double, you can see the internal value in hex starting around where I inserted a V.

Later statements then push it onto the stack (movq %rax, -8(%rbp)), then load it into an FP register (movsd -8(%rbp), %xmm0) before converting it to an integer and storing it in %eax, which is the register for return values (cvttsd2si %xmm0, %eax) and then returning from the routine, using ret.

In any case, at the optimisation level you're using (and probably below), your compiler has figured out that VALUE_NONSTAT is a constant expression, and just inlined it at compile time instead, since the value is fully known at compile time.

更多推荐