【问题标题】:Can't move 64-bit immediate values in assembler无法在汇编程序中移动 64 位立即数
【发布时间】:2016-06-09 21:47:04
【问题描述】:

我是 64 位汇编编码的新手。所以我尝试了一些简单的程序:

c 程序:

#include <stdio.h>

extern double bla();
double x=0;
int main() {
    x=bla();
    printf(" %f",x);
    return 0;
 }

组装:

   section .data
   section .text 
   global bla

   bla:
   mov rax,10
   movq xmm0,rax 
   ret

结果总是 0.0 而不是 10.0 但是当我没有立即制作它时,它可以正常工作

  #include <stdio.h>


 extern double bla(double y);
 double x=0;
 double a=10;
 int main() {
   x=bla(a);
   printf("add returned %f",x);
   return 0;
 }


 section .data
 section .text 
 global bla


 bla:
  movq rax,xmm0
  movq xmm0,rbx ;xmm0=0 now
  movq xmm0,rax ;xmm0=10 now
 ret

在 64 位寄存器中加载立即数是否需要不同的指令?

【问题讨论】:

  • 底部的示例似乎只工作,但已损坏。第一个汇编代码中的代码将整数值 10 移动到 rax,然后您尝试将 rax 中的整数值移动到 xmm0。问题是 movq 不会将通用寄存器中的整数转换为双精度并将其保存到 xmm0。您需要使用类似CVTSI2SD 的指令来转换寄存器中的整数值并将其存储在xmm0 中。这应该工作bla: ; mov eax, 10 ; cvtsi2sd xmm0,rax ; ret
  • 该示例将整数值 10 移动到 EAX(自动零扩展到 RAX),但您也可以这样做 mov rax, 10cvtsi2sd xmm0,rax 将 RAX 中的标量整数转换为双精度标量(单个浮点双精度)并将其存储在 xmm0 中。
  • 还有另一种选择。您可以让 NASM 在汇编时将 10.0 转换为 64 位浮点常量 (10.0) 并将其存储在 64 位通用寄存器中。可以像这样直接移动到 XMM 寄存器:bla: ; mov rax,__float64__(10.0) ; movq xmm0, rax ; ret

标签: gcc nasm


【解决方案1】:

这里的问题是 OP 试图使用以下代码将 10 移动到浮点寄存器中:

mov rax,10
movq xmm0,rax 

这是行不通的,因为 movqxmm0 假定源的位模式已经采用浮点格式 - 当然不是:它是一个整数.

@Michael Petch 的建议是使用 (NASM) 汇编器的浮点转换器,如下所示:

mov rax,__float64__(10.0)
movq xmm0,rax 

然后产生预期的输出。

【讨论】:

    猜你喜欢
    • 2012-05-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-05
    • 2015-06-14
    相关资源
    最近更新 更多