2016-11-22 49 views
2
  1. 如果我编写一个返回void的函数,根据x86-64约定调用,我可以破坏rax/eax吗?
  2. 关于返回一个double(因为实际收益将在XMM0发生)
  3. 如果我做MOVQ XMM0功能类似的问题 - >獭兔。然后我得到一个数字,可以把它放到在x86-64调用约定中的返回值

    union { 
        int, 
        double 
    }; 
    

    通过int。然后当我通过双重阅读时,我得到了预期的双倍。我的行为有什么缺陷?

+0

第3部分你在问什么?你是否正在返回这种类型的工会? –

+2

在x86-64中不是'rax' 64位和'int' 32位?你怎么把32位的64位? – MSalters

+1

您是否阅读过关于amd64的SysV ABI的文档? – fuz

回答

2

rax是临时寄存器,和double是在类SSE,所以它是在xmm0/xmm1返回。这些记录在SysV ABI中。没有任何东西可以阻止你在将返回值放到它之前使用xmm0作为scratch。有链接到x86 tag wiki ABI文件。

要回答#3,我们需要查看您的代码。也许它是C++中的UB,或者你的程序集是错误的。

+1

[x86标记wiki]中的当前ABI链接(http://stackoverflow.com/tags/x86/info)。 H.J. Lu的github页面链接到由ABI的LaTeX源代码的当前git修订版构建的PDF。 –

+0

干杯,不知道那些存在。 –

0
  1. 是,void功能可以让任何他们想要的所有ARG-返回寄存器(RAX,RDX,XMM0等)。 void表示主叫方不应该对任何随处随地离开的值做任何事情(当然除了RBX,RBP和RSP等呼叫保存寄存器外)。

  2. 类似什么?一个函数不能被声明为返回void double,所以你要问IDK。

  3. MOVQ允许您复制double的二进制表示。是的,当然,您可以将该64位整数打回到带有C99中的联合的double。但在C++中,联合类型双引号仅作为GNU扩展而合法。在asm中,无论你想要什么,都可以复制。

注意与int成员工会是假的这一点,因为这是在X86-64的SysV ABI只有32位。你大概是截尾你的尾数的低32位,所以你可能只测试了这个小尾数的低位无论如何都是零的小整数。

其实,这听起来不对;它应该截断double的一半,因为x86的浮点字节顺序将包含符号位的字节存储在最高地址处。所以它不应该工作,除非你存储在一个64位商店在联盟的联盟。