Link to home
Start Free TrialLog in
Avatar of dwiseman3
dwiseman3Flag for Afghanistan

asked on

PRINT OUT FLAGS REGISTER

This code will not print the flags register correctly. It appears that pushf and popf are getting a static set of bits...not the register flags in effect after the instruction. I have played around with push/pop and pushf/popf using a variety of sequences but I continue to get  results that don't show changes to the flag register after instruction 1-9 is executed. Can someone tell me what is wrong with this code? Thank you.

BIOS_CALL       EQU 21h
STRING_OUT_FN   EQU 09h
CHAR_IN_FN      EQU 01h
CHAR_OUT_FN     EQU 02h
EXIT_TO_DOS_FN  EQU 4Ch
.model small
.stack 100h
.DATA
CRLF             EQU 0Ah,0Dh
HEADER_STR      DB CRLF,"                       AX (Binary)         OF  CF  SF  ZF  PF"
            DB CRLF,"                       ----------------    --  --  --  --  --$"

FLAG_STR      DB "    "
      OF_Disp DB '0', "   "
      CF_Disp DB '0', "   "
      SF_Disp DB '0', "   "
      ZF_Disp DB '0', "   "
      PF_Disp DB '0',"$"

LINE_1_STR      DB CRLF,"1. MOV AX, 8000h       $"
LINE_2_STR      DB CRLF,"2. ADD AX, 0FFFFh      $"
LINE_3_STR      DB CRLF,"3. RCL AX, 1                $"
LINE_4_STR      DB CRLF,"4. AND AX, AFAFh       $"
LINE_5_STR      DB CRLF,"5. CMP AX, 00FFh        $"
LINE_6_STR      DB CRLF,"6. MOV CL, 9               $"
LINE_7_STR      DB CRLF,"7. ROR AX, CL             $"
LINE_8_STR      DB CRLF,"8, MOV CL, 02            $"
LINE_9_STR      DB CRLF,"9, SAR AX, CL            $"
END_PROG_STR      DB CRLF,CRLF, "END OF PROGRAM.",CRLF,"$"

.CODE


MAIN  PROC
      mov     AX,@DATA
      mov     DS,AX
                   ;print the header
      ;
      LEA      DX, HEADER_STR      
      CALL      PRINT_STR

      ;
      ; Execute Line 1
      ;
      LEA      DX, LINE_1_STR
      CALL      PRINT_STR
      MOV      AX, 8000h      
      CALL      PRINT_RESULT
            
      ;
      ; Execute Line 2
      ;
      LEA      DX, LINE_2_STR
      CALL      PRINT_STR
      ADD      AX, 0FFFFh      
      CALL      PRINT_RESULT
      
      ; Execute Line 3
      ;
      LEA      DX, LINE_3_STR
      CALL      PRINT_STR
      RCL AX, 1
      CALL      PRINT_RESULT
      ; Execute Line 4
      ;
      LEA      DX, LINE_4_STR
      CALL      PRINT_STR
      AND AX, 0AFAFH
      CALL      PRINT_RESULT

    ; Execute Line 5
      ;
      LEA      DX, LINE_5_STR
      CALL      PRINT_STR
      CMP AX, 00FFH
      CALL      PRINT_RESULT
      ;
      ; Execute Line 6
      ;
      LEA      DX, LINE_6_STR
      CALL      PRINT_STR
      MOV CL, 9
      CALL      PRINT_RESULT
      
      
      ; Execute Line 7
      ;
      LEA      DX, LINE_7_STR
      CALL      PRINT_STR
      ROR AX, CL
      CALL      PRINT_RESULT
      
      ; Execute Line 8
      ;
      LEA      DX, LINE_8_STR
      CALL      PRINT_STR
      MOV CL , 2
      CALL      PRINT_RESULT
      
      ; Execute Line 9
      ;
      LEA      DX, LINE_9_STR
      CALL      PRINT_STR
      SAR AX, CL
      CALL      PRINT_RESULT
      
      ; Exit to DOS
      ;
      LEA      DX,END_PROG_STR
      CALL      PRINT_STR
      mov     AH,EXIT_TO_DOS_FN
      int     BIOS_CALL

MAIN ENDP

 
PRINT_STR PROC

      PUSH       AX      ; preserve AX
      PUSH      BX      ; preserve BX
      PUSH      CX      ; preserve CX
      PUSHF            ; preserve flags

      
      MOV      AH, STRING_OUT_FN      
      int      BIOS_CALL

      POPF            ; Restore flags
      POP       CX      ; Restore CX
      POP       BX      ; Restore BX
      POP       AX      ; Restore AX
      RET

PRINT_STR ENDP


PRINT_RESULT PROC

      CALL      PRINT_AX_BIN
      CALL      PRINT_FLAGS

      RET

PRINT_RESULT ENDP


PRINT_AX_BIN  PROC
      
      
      PUSHF
      PUSH AX
      PUSH BX
      PUSH CX
      
      MOV      CX, 16                  
      MOV BX, AX
      
BINARY_PRINT_LOOP:
      
      MOV DL,'0'      
      ROL BX, 1
      
      JNC  PRINT1
      MOV DL,'1'
      PRINT1:
      MOV      AH, CHAR_OUT_FN
      INT      BIOS_CALL
      
      LOOP      BINARY_PRINT_LOOP
      
      
      POP CX
      POP BX
      POP AX
      POPF
    RET
PRINT_AX_BIN ENDP

PRINT_FLAGS PROC

      PUSH      AX
      PUSH      BX
      PUSH      CX
      PUSHF  
      POP       BX
      
      MOV            CX,'10'
            
      Test_CF:
      TEST       BX,0001H
      JC            Test_PF
      MOV            CF_Disp,CH
      
      Test_PF:
      TEST      BX,0004H
      JP            TEST_ZF
      MOV            PF_Disp,CH
      
      Test_ZF:
      TEST      BX,0040H
      JZ            Test_SF
      MOV            ZF_Disp,CH
      
      Test_SF:
      TEST      BX,0080H
      JS            Test_OF
      MOV            SF_Disp,CH
      
      Test_OF:
      TEST      BX,0800H
      JO            Test_done
      MOV            OF_Disp,CH
   
      Test_done:      
      PUSH BX
      POPF
      POP CX
      POP      BX
      POP      AX
                  
      LEA          DX,FLAG_STR
      CALL      PRINT_STR
      RET
PRINT_FLAGS ENDP

END MAIN  
ASKER CERTIFIED SOLUTION
Avatar of maques
maques

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
@maques: The TEST instruction modifies: CF, OF, PF, SF, ZF
    REF: http://www.cs.tut.fi/~siponen/upros/intel/instr/test.html

Now, why not use LAHF, it will be easier to test flags:

PUSH      AX
LAHF
Test_CF:
      TEST       AH,1
      JC            Test_PF
      MOV            CF_Disp,CH
     
      Test_PF:
      TEST      BX,0004H
      JP            TEST_ZF
      MOV            PF_Disp,CH
     
      Test_ZF:
      TEST      BX,0040H
      JZ            Test_SF
      MOV            ZF_Disp,CH
     
      Test_SF:
      TEST      BX,0080H
      JS            Test_OF
      MOV            SF_Disp,CH
     
      Test_OF:
      TEST      BX,0800H
      JO            Test_done
      MOV            OF_Disp,CH
   
      Test_done:
POP AX
Sorry, I accidentally submitted too early.

PUSH      AX
LAHF //LOAD FLAGS INTO AH
      Test_CF:
      TEST          AH,1h
      JZ            Test_PF
      MOV           CF_Disp,CH
     
      Test_PF:
      TEST          AH,4H
      JZ            TEST_ZF
      MOV           PF_Disp,CH
     
      Test_ZF:
      TEST          AH,20H
      JZ            Test_SF
      MOV           ZF_Disp,CH
     
      Test_SF:
      TEST          AH,80H
      JZ            Test_done
      MOV           SF_Disp,CH
   
POP AX
Avatar of maques
maques

LAHF could be fine. However, the script originally had two major problems and I tried to change as less as possible...
Otherwise the whole thing could be rewritten a bit differently...
Pushing the flags to the stack requires a pop from the stack (in my opinion an unnecessary step if you can load them directly into a register).

Also, you should check your bitmasks, the zero flag should be AND 40h.
dwiseman3, do you have any comments about our suggestions?
Avatar of dwiseman3

ASKER

an appology,Brian, for not replying...I got waylayed on another project. Maques solved the biggest part of my problem. The initialization  enabled me to output results that helped me work through the rest of the problem. Then, I moved on to another project. The finer corrections that you mention all appear to make sense, though.