【发布时间】:2018-11-03 20:10:59
【问题描述】:
Sum using xmm regsisters using fasm - linux:
$./fasm file.asm
$ gcc -s file.o -o file -lm
结果应该是 14 ,但我得到了7.000000000000000000000000000000。
这是源代码:
format elf64
extrn printf
section '.data' writeable align 16
rad dq 7.0
fmt db "%.30lf",0ah,0
section '.text' executable align 16
public main
main:
push rbp
mov rbp,rsp
pxor xmm0,xmm0
movsd xmm0,[rad]
pxor xmm2,xmm2
movsd xmm2,[rad]
addsd xmm2,xmm0
mov rax,1
mov rdi,fmt
call printf
mov rsp,rbp
pop rbp
ret
【问题讨论】:
-
重放
adds xmm2, xmm0和adds xmm0, xmm2以将加法的结果存储在xmm0中,而不是xmm2中,正如printf所期望的那样。 -
谢谢。我想我累了,显然结果 xmm2 将添加到 xmm0。 printf 只需要 rax 和 rdi (两个参数)。
-
movsd加载没有错误的依赖关系;为了性能或正确性,您不需要在movsd之前pxor xmm0,xmm0。它已经将 64 位负载零扩展至 128 位。就像一个普通人一样,只是movsd xmm0, [rad]/addsd xmm0, xmm0或addsd xmm0,[rad]。 -
是的!是一个步骤:board.flatassembler.net/topic.php?t=20807 外部 cos 的结果是好的,但我不能总结 xmm0 的这些结果。
-
re:您在链接论坛上的代码:正如 Agner Fog 的调用约定文档所解释的,所有 XMM regs 都是调用破坏的。你不能
movaps到 xmm3 来保护另一个call cos,你必须假设cos破坏 xmm3。所以你应该保留一些堆栈空间并存储在那里,然后在第二个call cos之后addsd xmm0, [rsp]。或者更好的是,找到一个矢量化的cos函数 (sourceware.org/glibc/wiki/libmvec) 并行计算 2 个结果,然后对结果进行水平相加。 (movhlps xmm1, xmm0/addsd xmm0, xmm1)。
标签: linux assembly x86-64 fasm