; 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