Linux操作系统下使用FASM使用XMM寄存器求和
使用xmm和fasm-linux进行求和:Linux操作系统下使用FASM使用XMM寄存器求和,linux,assembly,x86-64,fasm,Linux,Assembly,X86 64,Fasm,使用xmm和fasm-linux进行求和: $./fasm file.asm $ gcc -s file.o -o file -lm 结果应该是14,但我得到了7.000000000000000000000000000000000000 这是源代码: format elf64 extrn printf section '.data' writeable align 16 rad dq 7.0 fmt db "%.30lf",0ah,0 section '.text' executable
$./fasm file.asm
$ gcc -s file.o -o file -lm
结果应该是14,但我得到了7.000000000000000000000000000000000000
这是源代码:
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
解决它:
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]
movsd xmm2,[rad]
addsd xmm0,xmm2
mov rax,1
mov rdi,fmt
call printf
mov rsp,rbp
pop rbp
ret
Replay
添加xmm2,xmm0
with添加xmm0,xmm2
以将添加结果存储在xmm0
中,而不是xmm2
中,正如printf
所期望的那样。谢谢。我想我累了,显然结果xmm2将被添加到xmm0中。printf只需要rax和rdi(两个参数)。movsd
load没有错误的依赖关系;对于性能或正确性,不需要在movsd
之前使用px或xmm0、xmm0
。它已经将64位负载扩展到128位。就像正常人一样,只需movsd xmm0,[rad]
/addsd xmm0,xmm0
或addsd xmm0,[rad]
。是的!这是一个步骤:外部cos的结果是可以的,但我不能对xmm0的这些结果求和。re:你在链接论坛上的代码:正如Agner Fog的调用约定文档所解释的,所有的XMM regs都是call clobbered。您不能通过另一个调用cos来安全地保存xmm3,您必须假设cos破坏xmm3。因此,您应该保留一些堆栈空间并存储在那里,然后在第二次调用cos后添加sd xmm0[rsp]。或者更好的方法是找到一个向量化的cos
函数(),它并行计算两个结果,并对结果进行水平相加。(movhlps xmm1,xmm0
/addsd xmm0,xmm1
)。