屏蔽除以 0 异常程序集 masm

Masking divide by 0 exception assembly masm

TITLE Unmasking an Exception    (Exceptions.asm)

; This program shows how to mask (set) and unmask (clear) the divide by zero
; exception flag.

INCLUDE Irvine32.inc

.data
ctrlWord WORD ?
val1 DWORD 1
val2 REAL8 0.0

.code
main PROC
finit       ; initialize FPU (divide by zero is masked)

; By unmasking, we enable the divide by zero exception.

fstcw   ctrlWord                ; get the control word
and ctrlWord,1111111111111011b  ; unmask Divide by 0
fldcw   ctrlWord                ; load it back into FPU

fild    val1
fdiv    val2                        ; divide by zero
fst val2

exit
main ENDP
END main

大家好,我是 masm 的新手,正在浏览一些我能找到的在线项目,但在使用这个项目时遇到了问题,正如您所看到的,它揭示了除以 0 的异常,但我该如何编辑它掩盖同样的例外?如果可以,请解释并尽可能详细,这将大有帮助!

fstcw   ctrlWord                ; get the control word
and ctrlWord,1111111111111011b  ; unmask Divide by 0
fldcw   ctrlWord                ; load it back into FPU

除零异常的屏蔽位 (ZM) 是 FPU 控制字的位 2。如果你不写像“1111111111111011b”这样的长掩码值,它会提高可读性。
由于位 2 由值 4 表示,清除该位的更易读的方法是:

and ctrlWord, not(4)

有些人甚至更喜欢写 and ctrlWord, not(1<<2) 因为这个仍然保留对位号的引用(在这种情况下为 2)。

现在,当采用此改进时,屏蔽零除异常变成了将 and 更改为 or 并删除 not 运算符的问题.

and ctrlWord, not(4)    ---->    or ctrlWord, 4

作为替代方案,您还可以使用 btrbts 指令清除或设置位:

and ctrlWord, not(4)    ---->    btr ctrlWord, 2          ;Clears bit 2
or  ctrlWord, 4         ---->    bts ctrlWord, 2          ;Sets bit 2