2017-08-21 5 views
0

アセンブリにかなり新しいです&これは私の最初のプログラミング言語です。(fldcw [sp])アセンブリコードでWordの問題を制御します

私はこの行についての質問があります:fldcw [sp]。これは、ビルドエラーが発生します。エラーA2031:

spは16ビットスタックポインタ

はESP 32ビットスタックポインタ

です:でなければならないインデックスまたはベースレジスタ

を私がいることを承知しています

-

私はFPUコントロールワードの利用について学びたいと考えています。 私はSkylakeプロセッサを使用しています。私はそれがうまく構築し、SPでESPを交換した場合http://www.website.masmforum.com/tutorials/fptute/fpuchap3.htm#fstcw

すべての私の情報はで得られます。

私はガイドを誤解していますか? このエラーの原因は何ですか?

.386 
.model flat, stdcall 
option casemap :none 

includelib \masm32\lib\msvcrt.lib 
sprintf proto C :vararg 
includelib \masm32\lib\user32.lib 
MessageBoxA proto :ptr,:ptr,:ptr,:DWORD 
includelib \masm32\lib\kernel32.lib 
ExitProcess proto :dword 

.data 
    _title db "Result",13,10,0 
    $interm db "%0.4f","+","%0.5f",13,10,0 
    oldcw dw ? 



.code 
main PROC 
LOCAL szBuf[9]:byte 




    fstcw oldcw  ;get the current Control Word to retain all setting bits 
        ;not related to the rounding control (RC) bits 
    fwait  ;to insure the storage instruction is completed 
    mov ax,oldcw 
; and ax,0F3FFh ;clears only the RC bits, leaving all other bits unchanged 
        ;not necessary here because both bits will be set 
    or ax,0C00h ;this will set both bits of the RC field to the truncating mode 
        ;without affecting any of the other field's bits 
    push eax  ;use the stack to store the modified Control Word in memory 
    fldcw [sp]  ;load the modified Control Word 



    fldcw oldcw  ;restore the previous Control Word 
    pop eax  ;clean-up the stack 
        ;this could also retrieve a 16-bit or 32-bit integer 
        ;possibly returned by the "other FPU instruction(s)" 

Finished: 


    invoke sprintf, addr szBuf, offset $interm, eax, edx 
    invoke MessageBoxA, 0, addr szBuf, offset _title, 0 
    invoke ExitProcess, 0 



main ENDP 
END main 
+1

'sp'はスタックポインタの下位16ビットです。 32ビットコードで 'esp'を使うべきです。とにかく '[sp]'は有効な16ビットアドレッシングではありません。リンクされたページの誤字のように見えます。 – Jester

+0

eww、なぜそのコードは 'oldcw'に静的な格納場所を使用していますが、スタックを使ってEAXからx87ユニットに新しいものをバウンスするのはなぜですか?どちらの関数も関数の寿命を延ばす必要がないため、両方のスタックを(異なる場所で)スタックに配置する方が理にかなっています。 –

答えて

1

16ビットモードでは、[sp]は有効なメモリオペランドではありません。のみ、次のメモリオペランドが、それぞれがオプションの変位持つ、有効です。しかし

push bp  ; establish stack frame 
mov bp,sp  ; dito 
fstcw oldcw 
fwait 
mov ax,oldcw 
or ax,0C00h 
push ax 
fldcw [bp-2] ; load control word from stack 
leave   ; tear down stack frame 

[bx] 
[bx+si] 
[bx+di] 
[bp] 
[bp+si] 
[bp+di] 
[si] 
[di] 
[addr16] 

はあなたのコードを修正するために、私はあなたがスタックフレームを設定し、取り組むbp -relativeを使用することをお勧めします32ビットモードの場合は、代わりに32ビットスタックポインタespを参照してください。あなたが16ビットモードになっているか、何をしているのかを正確に知っていない限り、メモリオペランドに16ビットレジスタを使用しないでください。

fstcw oldcw 
fwait 
mov ax,oldcw 
or ax,0C00h 
push eax 
fldcw [esp] ; load control word from stack 
pop eax  ; restore stack 
関連する問題