4
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

Hi everyone, i am very new to masm and am taking myself through some online projects i can find and am having trouble with this one, as you can see it unmasks the divide by 0 exception but how can i edit this to mask that same exception? If you can please explain and be as detailed as possible that will help out a ton!

rkhb
  • 14,159
  • 7
  • 32
  • 60
JimBob101
  • 173
  • 9
  • 1
    Set the same bit to 1 instead of clearing it to 0? Use bitwise `OR`. – Jester Mar 26 '16 at 01:26
  • See, im very very noob at this so i dont understand what you mean by that. )= – JimBob101 Mar 26 '16 at 01:28
  • 1
    Learn how [bitwise operators](https://en.wikipedia.org/wiki/Bitwise_operation) work, that's elementary to any programming. Then use `or ctrlWord,100b`. – Jester Mar 26 '16 at 01:31
  • Ok i will read up on that and your saying that replacing the and ctrlWord,1111111111111011b with or ctrlWord,100b? – JimBob101 Mar 26 '16 at 01:33
  • Yes. That `and` is clearing bit #2 (since you used it you should know what it does...). So the counterpart is setting that bit to 1. – Jester Mar 26 '16 at 01:33
  • Ok thanks for your help! Im going to read that link you posted and hopefully be able to figure this out. – JimBob101 Mar 26 '16 at 01:41

1 Answers1

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

The mask bit (ZM) for the zero-divide exception is bit 2 of the FPU control word. It would improve readability if you didn't write a long masking value like "1111111111111011b".
Since bit 2 is represented by the value 4, a more readable way to clear this bit is:

and ctrlWord, not(4)

Some people will even prefer to write and ctrlWord, not(1<<2) since this one still retains reference to the bit number (2 in this case).

Now when adopting this improvement, masking the zero-divide exception becomes a matter of changing the and into an or and dropping the not operator.

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

As an alternative you can also clear or set a bit using btr and bts instructions:

and ctrlWord, not(4)    ---->    btr ctrlWord, 2          ;Clears bit 2
or  ctrlWord, 4         ---->    bts ctrlWord, 2          ;Sets bit 2
Sep Roland
  • 33,889
  • 7
  • 43
  • 76