My question isn't about the fact that BX was used as a return value rather than placing it at a global memory location or on the stack. I observed this code being posted recently in a comment. The code was for a real-mode mouse handler using the BIOS. Two small functions that save/restore the state of the FLAGS register were as follows:
EFLAGS_IF equ 0x200 ; Bit mask for IF flag in FLAGS register
; Function: save_if_flag
; save the current state of the Interrupt Flag (IF)
;
; Inputs: None
; Returns: BX = 0x200 if interrupt flag is set, 0 otherwise
save_if_flag:
pushf
pop bx ; Get FLAGS into BX
and bx, EFLAGS_IF ; BX=0 if IF is clear, BX=0x200 if set
ret
; Function: restore_if_flag
; restore Interrupt Flag (IF) state
;
; Inputs: BX = save Interrupt Flag state
; Clobbers: None
; Returns: EFLAGS IF flag restored
restore_if_flag:
test bx, bx ; Is saved Interrupt Flag zero?
jz .if_off ; If zero, then disable interrupts & finish
sti ; Otherwise enable interrupts
ret ; We're finished
.if_off:
cli ; Disable interrupts
ret
I'd like to understand why the restore_if_flag function does this:
restore_if_flag:
test bx, bx ; Is saved Interrupt Flag zero?
jz .if_off ; If zero, then disable interrupts & finish
sti ; Otherwise enable interrupts
ret ; We're finished
.if_off:
cli ; Disable interrupts
ret
Rather than simply using POPF like this:
restore_if_flag:
push bx
popf
ret
Why explicitly save/restore the interrupt flag using STI/CLI rather than simply restoring the previous FLAGS register with POPF?


pushfandpopfuse to get copy and pasted like cookie cutter code that ended up in code running via DOS extenders - that code ended up not working properly and many of the work around (hacks) are not always successful. As for DOS extenders, it was the reason I referenced DPMI in the answer. - Michael Petch