【发布时间】:2018-01-29 00:04:39
【问题描述】:
我对汇编还很陌生,这是我的第一门编程语言。
我对这条线路有疑问:fldcw [sp]。它会导致构建错误:error A2031: must be index or base register
我知道:
sp 是 16 位堆栈指针
esp 是 32 位堆栈指针
-
我正在尝试了解如何使用 FPU 控制字。 我使用 Skylake 处理器。
我的所有信息都在:http://www.website.masmforum.com/tutorials/fptute/fpuchap3.htm#fstcw
当我用 sp 替换 esp 时,它构建得很好。
我是否误解了指南? 什么可能导致此错误?
.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
【问题讨论】:
-
sp是堆栈指针的低 16 位。您应该在 32 位代码中使用esp。[sp]无论如何都不是有效的 16 位寻址。看起来链接页面中有错字。 -
eww,为什么该代码使用
oldcw的静态存储位置,但使用堆栈将新的从 EAX 反弹到 x87 单元?将两者都放在堆栈上(在不同的地方)会更有意义,因为它们都不需要超过函数。