汇编代码中的静态值

时间:2013-12-05 10:25:00

标签: c++ assembly c++11 static

我有以下简单的代码:

#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
  1. 为什么.long有两个值?为什么这些类型很长? (它是一个双重?,也许在汇编程序中只有很长时间。
  2. 这是否意味着VALUE的值是生成的编译时间
  3. VALUE_NON_STATIC的结果在哪里?这应该在运行时计算吗?我不太清楚在哪里?
  4. 非常感谢!

1 个答案:

答案 0 :(得分:5)

此汇编语法中的

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

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

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

回顾15143B7845E95B3E3*std::pow(std::sin(index * 2.0 * 3.1415 / 20.0),1.999)存储在double时的值的表示,您可以看到十六进制的内部值从我插入{{1}的位置开始}。

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

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