2017-09-24 4 views
3

私はインテルx64アセンブリ、NASMコンパイラを使用して、 "0x4000000000000000"定数をメモリに移動しようとしています(ieee 754標準のdoubleは2.0になります)。x86アセンブリ内のメモリに64ビット定数を移動する

私が使用しているコードは次のとおりです。署名DWORD即時の範囲を超える:

%define two 0x4000000000000000 

section .text 

foo: 

push rbp 
mov rbp, rsp 

mov QWORD [rdi], two 

pop rbp 
ret 

はこれをコンパイルする

警告がスローされます。

私がC++で値を印刷すると、 "2"ではなく "0"が表示されます。

は、私はすでに正しい値を得るための方法、見つけた:

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

これは推奨される方法ですが、登録を避けることを絶対に要求する場合は、もちろん2つの半分に格納することができます。 – Jester

答えて

7

あなたは

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

または

and qword [rdi], 0 
    mov byte [rdi+7], 0x40 
を使用することができます何の指示

mov r/m64, imm64 

はありません3210

はわずか8バイトです(問題がある場合)。

+0

作品!ありがとうございました! –

+0

最後のバージョンで 'byte'サイズ指定子を省略しました。 code-sizeを最適化するには、 'とr/m64、imm8'を使うことができますが、それはパフォーマンスのためにはうまくいくでしょう。 'mov qword [rdi]、0' /' movバイト[rdi + 7]、0x40'(これはあなたの最初のオプションよりも小さいが、ほぼ同じ速度)のほんの2バイトです。 –

+0

'mov r64、imm64' /' mov r/m64、r64'と違って、マルチパートオプションは、あなたが64ビットロードを直ちに実行するとstore-forwarding stallを生成します。 10バイトのimm64の代わりに 'mov eax、1'、 'shl rax、40'や 'xor eax、eax' /' bts rax、40 'のようなことをする方が効率的だと思うでしょうコードサイズの節約はほとんどありません。 –

関連する問題