2017-02-11 4 views
1

私はfloat(3.25)と整数(2)という2つの数値を追加すると仮定しているこのコードを持っています。NASMに2つの整数、浮動小数点数を追加するには?

EDITED:

extern _printf, _scanf 
global _main 
section .bss 
    num1: resb 4 
section .data 
    format_num: db "%f", 10, 0 
section .text 
_main: 

    mov dword [num1], __float32__(3.25) 
    add num1, 2 

    sub esp, 8 
    fld dword [num1] 
    mov dword [num1], eax 
    fstp qword [esp] 
    push format_num 
    call _printf 
    add esp, 12 

ret 

私が手出力は次のようになります。

test.asm:11:error: invalid combination of opcode and operands

私は期待して出力されている:

5.250000

+0

ここに何かを保存する前にnum1から0を読み込んだ後、スタックにその0を配置します。あなたは浮動小数点ロードとストアbtwでそれを行う必要はありません。 – harold

+0

@harold質問を編集しました、ありがとう、別のエラーがあります。 –

+0

OKこれで定数に追加しようとしています – harold

答えて

2

x87 FPUのチュートリアルは、Stackoverflowの範囲を超えていますが、MASM forumsにお勧めします。もう1つの良い情報源はIntel Instruction Set Referenceです。特に、Fで始まるほとんどの関数は、x87浮動小数点ユニット(FPU)関連の命令です。

通常、浮動小数点値を整数に加算することはできません。彼らは2つの異なる表現です。あなたができることは、整数を浮動小数点値に変換してから浮動小数点計算を行うことです。特に、FIで始まる命令は、整数メモリオペランドを浮動小数点に変換する浮動小数点演算です。

は猫を肌には多くの方法がありますが、あなたは上記にリンクされているFPUのチュートリアルを確認した場合、あなたは1つの単純な方法は、これを行うためにあることを実現することができる:

sub esp, 8   ; Allocate space on stack to store integer 
mov dword [esp], 2 ; Move the 32-bit integer value onto stack temporarily 
fild dword [esp]  ; Load integer 2 from stack into top of FPU stack at st(0) 
        ; Converting it to 2.0 in the process 
mov dword [esp], __float32__(3.25) 
        ; Move 3.25 onto stack temporarily 
fadd dword [esp]  ; Add 3.25 to st(0). Result in st(0). So st(0)=5.25 
fstp qword [esp]  ; Store 64-bit double to stack for printf and pop FPU stack. 

むしろストア値にグローバル変数を使用するよりもメインメモリに一時的にx87 FPUをロード/操作するための一時的なステージング領域として確保したスタック領域を使用しました。

SSE2命令セット(32ビットモードのX86-64プロセッサを含む)をサポートするCPUを使用している場合は、他にもオプションがあります。 1つは、SIMD命令とレジスタを使用して32ビットおよび64ビットの浮動小数点演算を行うことです。

  • cvtsi2sd:あなたのようないくつかの有用な指示を見つける命令セット・リファレンスを使用して倍精度FP値をスカラーするダブルワード整数に変換
  • cvtss2sd:スカラ倍精度FP値
  • にスカラ単精度FP値を変換
  • addsd:スカラ倍精度浮動小数点が
  • movsd値追加:スカラ倍精度浮動小数点を移動バリュー

スカラー単精度FP値は32ビットのfloat型です。スカラ倍精度は64ビットの倍精度です。

sub esp, 8 
mov dword [esp], 2  ; Load integer 2 (32-bit signed value) onto stack temporarily 
cvtsi2sd xmm0, [esp] ; Convert 2 on stack to 64-bit float and store in XMM0 
mov dword [esp], __float32__(3.25) 
         ; Load 32-bit float value of 3.25 onto stack 
cvtss2sd xmm1, [esp] ; Load 32-bit single and convert it to 64-bit double. Store in XMM1 
addsd xmm0, xmm1  ; Add 64-bit float in XMM0 and XMM1 store XMM0 
movsd qword [esp], xmm0 ; Move 64-bit float back onto stack to be printed by printf 
+0

マイケルに感謝します。素晴らしい説明です。 :) –

+0

'fld1' +' faddp'はそれより前のサンプルコードよりも高速ですが、もっと速く(もっと明白な)方法は 'fld'で定数2.0をロードすることです。バイナリ内のスペースはわずかしか消費されません。 –

1

ソリューションです:

extern _printf 
global _main 
section .bss 
    num1: resb 4 
    num2: resb 4 
section .data 
    format_float: db "The result is %f", 10, 0 
_main: 

    mov dword [num1], 2 
    mov dword [num2], __float32__(3.25) 

    sub esp, 8 
    fild dword [num1] 
    fadd dword [num2] 
    fstp qword [esp] 
    push format_float 
    call _printf 
    add esp, 12 

ret 
私が手

出力は次のようになります。

5.250000

fildは、fadd、2つの浮動小数点数を追加することができ、ST0に2.0000000として2をプッシュします。結果は浮動小数点数です。 int + float = float

申し訳ありませんが、私の英語は悪いです。

関連する問題