返回介绍

24.2 通过参数传递浮点型变量

发布于 2025-02-22 14:00:49 字数 1602 浏览 0 评论 0 收藏 0

#!cpp
#include <math.h>
#include <stdio.h>
int main ()
{
    printf ("32.01 ^ 1.54 = %lf\n", pow (32.01,1.54));
    return 0;
}

他们通过 XMM0-XMM3 的低一半寄存器传递。

清单 24.3: MSVC 2012 x64 /Ox

#!bash
$SG1354 DB ’32.01 ^ 1.54 = %lf’, 0aH, 00H
__real@40400147ae147ae1 DQ 040400147ae147ae1r ; 32.01
__real@3ff8a3d70a3d70a4 DQ 03ff8a3d70a3d70a4r ; 1.54
main PROC
    sub rsp, 40 ; 00000028H
    movsdx xmm1, QWORD PTR __real@3ff8a3d70a3d70a4
    movsdx xmm0, QWORD PTR __real@40400147ae147ae1
    call pow
    lea rcx, OFFSET FLAT:$SG1354
    movaps xmm1, xmm0
    movd rdx, xmm1
    call printf
    xor eax, eax
    add rsp, 40 ; 00000028H
    ret 0
main ENDP

在 Intel 和 AMD 的手册中(见 14 章和 1 章)并没有 MOVSDX 这个指令,而只有 MOVSD 一个。所以在 x86 中有两个指令共享了同一个名字(另一个见 B.6.2)。显然,微软的开发者想要避免弄得一团糟,所以他们把它重命名为 MOVSDX,它只是会多把一个值载入 XMM 寄存器的低一半中。 pow()函数从 XMM0 和 XMM1 中加载参数,然后返回结果到 XMM0 中。 然后把值移动到 RDX 中,因为接下来 printf() 需要调用这个函数。为什么?老实说我也不知道,也许是因为 printf() 是一个参数不定的函数?

清单 24.4:GCC 4.4.6 x64 -O3

#!bash
.LC2:
.string "32.01 ^ 1.54 = %lf\n"
main:
    sub rsp, 8
    movsd xmm1, QWORD PTR .LC0[rip]
    movsd xmm0, QWORD PTR .LC1[rip]
    call pow
    ; result is now in XMM0
    mov edi, OFFSET FLAT:.LC2
    mov eax, 1 ; number of vector registers passed
    call printf
    xor eax, eax
    add rsp, 8
    ret
.LC0:
    .long 171798692
    .long 1073259479
.LC1:
    .long 2920577761
    .long 1077936455

GCC 让结果更清晰,printf()的值传入到了 XMM0 中。顺带一提,这是一个因为 printf() 才把 1 写入 EAX 中的例子。这意味着参数会被传递到向量寄存器中,就像标准需求一样(见 21 章)。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文