dwiseman3
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
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
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
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
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
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...
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?
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.
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