在x86组件中将64位常量移动到内存

问题描述:

我正在使用Intel x64程序集NASM编译器,试图将“0x4000000000000000”常量移动到内存中,ieee 754标准中的double值应该等于2.0。在x86组件中将64位常量移动到内存

我正在使用的代码是:

%define two 0x4000000000000000 

section .text 

foo: 

push rbp 
mov rbp, rsp 

mov QWORD [rdi], two 

pop rbp 
ret 

编译,这将引发

警告:签署DWORD立即超过界限。

当我在C++中打印值时,它显示“0”而不是“2”。

我已经发现获得正确的价值的一种方式,那就是:

mov r9, 0x4000000000000000 
mov [rdi], r9 

但我想知道是否有实现这一目标而无需使用寄存器的一种方式。

的方式,即时编译代码与此脚本:

#!/bin/bash 
nasm -f elf64 -g -F dwarf vvp_asm.asm -o vvp_asm.o 
g++ -c -m64 -std=c++11 main.cpp -o main.o 
g++ -o main -m64 vvp_asm.o main.o 
+1

这是推荐的方法,但如果你绝对坚持要避免注册,那么当然可以将它存储在两个部分。 – Jester

没有指令

mov r/m64, imm64 

你可以使用

mov dword [rdi], 0 
    mov dword [rdi+4], 0x40000000 

and qword [rdi], 0 
    mov byte [rdi+7], 0x40 

它只有8个字节(如果有的话)。

+0

作品!谢谢! –

+0

您在最后一个版本中省略了字节大小说明符。如果优化代码大小,你可以使用'和r/m64,imm8',但这会吸引性能。 'mov qword [rdi],0' /'mov byte [rdi + 7],0x40'(这比你的第一个选项小,但速度相同)只有几个字节。 –

+0

不同于'mov r64,imm64' /'mov r/m64,r64',如果您立即执行64位加载,任何多部分选项都会产生存储转发失速。你会认为像'mov eax,1','shl rax,40'或'xor eax,eax' /'bts rax,40'而不是10字节mov imm64这样做会更有效率,但是几乎没有代码大小的保存。 –