Set means flag value = 1
and Unset means flag value = 0
Now I understand there are several ways to set and unset flags in MASM, as follows:
test al,0 ; set Zero flag
and al,0 ; set Zero flag
or al,1 ; clear Zero flag
Same goes for Sign flag
:
or al,80h ; set Sign flag
and al,7Fh ; clear Sign flag
To set the Carry flag
, we use the STC instruction; to clear the Carry flag, we use CLC:
stc ; set Carry flag
clc ; clear Carry flag
To set the Overflow flag
, we add two positive values that produce a negative sum. To clear the Overflow flag
, we OR an operand with 0:
mov al,7Fh ; AL = +127
inc al ; AL = 80h (-128), OF=1
or eax,0 ; clear Overflow flag
The Overflow
and Carry
flags operations are self-understood and easy to grasp, but I find it hard to understand the mathematics behind setting the Zero/Sign
flags. Any help is appreciated!
Thanks!
The whole point of using the flags is that they are a side effect of other operations - and you can test the result after the operation has occurred.
So, for example, you can count down from 10
to 0
without explicitly testing for zero:
mov cx, 10
Again:
; Do some stuff, not changing cx
dec cx
jnz Again ; Go back to Again if not zero
The "Do some stuff" happens ten times, because dec
affects the Z
flag.
The reason that stc
and clc
exist is to help with multi-digit arithmetic. The C
flag is used to keep track of "Carries" out of previous arithmetic, so that you can factor them into future operations:
op1 dd 0x12345678 ; 32-bit value
op2 dd 0x9abcdef0 ; 32-bit value
mov ax,[op1+0] ; Get low word of op1
mov dx,[op1+2] ; Get high word of op1
add ax,[op2+0] ; Add in low word of op2
adc dx,[op2+2] ; Add in high word of op2 - WITH CARRY!
Because of these kinds of operations, you may need to pre-load C
with 0
or 1
before starting on the algorithm. Hence clc
and stc
- and why no other (arithmetic) flags have a "set" or "clear" op-code.
Note that there are other, non-arithmetic flags:
D
(direction) flag controls the direction of string instructions such as STOS
and MOVS
.
Thus there are cld
and std
instructions.I
(interrupt) flag controls whether interrupts are enabled or not.
Thus there are cli
and sti
instructions.