; CIS-77
;
; ADD_SUB_EFLAGS.ASM
;
; Program inputs two 16-bit signed integers, then
; computes the sum and difference of lower bytes
; and displays the CPU status flags.
;
INCLUDE IO.H ; header file for input/output
.386 ; Tells MASM to use Intel 80386 instruction set.
.MODEL FLAT ; Flat memory model
option casemap:none ; Treat labels as case-sensitive
.CONST ; Constant data segment
TXT_ENTER BYTE "- - - - - - - - - Please enter two numbers - - - - - - - - - - - -", 0
TXT_OP1 BYTE "OP1> ", 0
TXT_OP2 BYTE "OP2> ", 0
TXT_SUM BYTE " SUM> ", 0
TXT_DIFF BYTE "DIFF> ", 0
ENDL BYTE 13, 10, 0
OVERFLOW BYTE "*** Bad format, please retry!", 0
TXT_EFLAGS BYTE "S Z - a - p V C EFLAGS: Sign Zero AuxCarry Parity oVerflow Carry",
13, 10,
13, 10,
"7 6 5 4 3 2 * 0 (*) oVerflow is 11th bit of EFLAGS", 0
TXT_LINE BYTE "__________________________________________________________________", 0
TXT_UNSIG BYTE " Unsigned: ", 0
TXT_BIN BYTE " Binary: ", 0
.STACK 100h ; (default is 1-kilobyte stack)
.DATA ; Begin initialised data segment
bit_buffer BYTE 32 dup(' '), 0 ; output buffer
inp_buffer BYTE 8 DUP (?) ; input buffer
.CODE ; Begin code segment
_main PROC ; Main entry point into program
program_top:
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Input operand one:
;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@:
output ENDL
output TXT_LINE
output ENDL
output TXT_ENTER
output ENDL
output TXT_OP1 ; Please enter a number...
input inp_buffer, 8 ; Read zero to 6 ASCII characters
atoi inp_buffer ; Convert string to 2's complement number
jno @F ; Check the overflow flag
; Handle input error:
output OVERFLOW ; print error message
output ENDL ; print new line
jmp @B ; back to the prompt
@@:
; Success: result of conversion is in AX
xor edx, edx ; set EDX to zero
mov dl, al ; store first operand in DL
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Input operand two:
;;;;;;;;;;;;;;;;;;;;;;;;;;;
@@:
output TXT_OP2 ; Please enter a number...
input inp_buffer, 8 ; Read zero to 6 ASCII characters
atoi inp_buffer ; Convert string to 2's complement number
jno @F ; Check the overflow flag
; Handle input error:
output OVERFLOW ; print error message
output ENDL ; print new line
jmp @B ; back to the prompt
@@:
; Success: result of conversion is in AX
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Compute the sum:
;;;;;;;;;;;;;;;;;;;;;;;;;;;
push eax ; Preserve EAX
push edx ; Preserve EDX
output TXT_LINE
output ENDL
output TXT_SUM ; uncomment to show sum
add dl, al ; compute sum in DL
lahf ; load flags into AH
jno @F ; Check the overflow flag
or ah, 2 ; set 2nd bit in AH (indicates overflow)
jmp display_sum
@@:
and ah, 11111101y ; clear 2nd bit in AH (indicates no overflow)
display_sum:
call show_dx
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Compute the difference:
;;;;;;;;;;;;;;;;;;;;;;;;;;;
pop edx ; Restore EDX
pop eax ; Restore EAX
output TXT_LINE
output ENDL
output TXT_DIFF ; uncomment to show diff
sub dl, al ; compute difference in DL
lahf ; load flags into AH
jno @F ; Check the overflow flag
or ah, 2 ; set 2nd bit in AH (indicates overflow)
jmp display_diff
@@:
and ah, 11111101y ; clear 2nd bit in AH (indicates no overflow)
display_diff:
call show_dx
jmp program_top
ret
_main ENDP
show_dx PROC
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Display DX and flags
;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Input: DX = value to display, AH = STATUS FLAGS to display
movsx dx, dl ; sign-extend DL into DX
itoa inp_buffer, dx ; Convert 16-bit signed integer to string
output inp_buffer ; print result
output TXT_UNSIG
movzx dx, dl ; zero-extend DL into DX
itoa inp_buffer, dx ; Convert 16-bit signed integer to string
output inp_buffer ; print result
push eax
mov ah, dl
call ah_2_bit_buffer ; Prepare bit buffer
output TXT_BIN
output bit_buffer ; show bits
pop eax
output ENDL ; print new line
output ENDL
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Display lower byte of EFLAGS from AH
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
call ah_2_bit_buffer ; Prepare bit buffer
output bit_buffer ; show flags
output ENDL
output TXT_EFLAGS ; show labels
output ENDL
ret
show_dx ENDP
ah_2_bit_buffer PROC
mov ecx, 8 ; number of bits to display
mov esi, OFFSET bit_buffer
next_bit:
shl ah, 1 ; shift high bit into Carry flag
mov BYTE PTR [esi], '0' ; display zero by default
jnc next_byte ; if no Carry, advance to next byte
mov BYTE PTR [esi], '1' ; otherwise display 1
next_byte:
inc esi ; next buffer position
inc esi ; next buffer position
loop next_bit ; shift another bit to left
; Display bits
mov BYTE PTR [esi], 0 ; add null char
ret
ah_2_bit_buffer ENDP
END _main ; Marks the end of the module and sets the program entry point label