Reputation: 2527
I've coded the below program using emu8086 with fasm-syntax enabled. As you can see, the program should print "Overflow flag not set" the first time around and then after the addition sets the overflow flag, it should then print "Overflow flag not set."
However, this is not what is happening. The program instead prints "overflow flag set" in any case. I've stepped through this code and o_set is at address 0, o_notset is at address 13h. No matter whether 13h or 0h are placed into dx at the time int 21h with al 09h is called, it prints "overflow flag set." I'm confused here because I do in fact assign them as two separate areas in the data segment. Note that the jump logic seems to be working fine, the problem is that regardless of what is placed in dx, the same message is always printed. In fact, if I put a 99 inside of dx, it still prints "overflow flag set."
format MZ
entry code_seg:start
stack 256
segment data_seg
o_set db "Overflow flag set $"
o_notset db "Overflow flag not set $"
segment code_seg
start:
push bp
mov bp, sp
mov cl, 99
jo of_flag_set
push o_notset
call printf
add sp, 2
add cl, 98
jo of_flag_set
jmp endme
of_flag_set:
push o_notset
call printf
add sp, 2
endme:
mov sp, bp
pop bp
mov ah, 0h
int 20h
; Need to put offset to msg on stack prior to call. Stack cleaned up by callee
printf:
push bp
mov bp, sp
mov dx, [bp+4] ;cant pop the retn addr into dx
mov ah, 09h
int 21h
mov sp, bp
pop bp
ret
Upvotes: 1
Views: 287
Reputation: 47573
I've commented the things that were wrong and needed fixing:
format MZ
entry code_seg:start
stack 256
segment data_seg
; Add carriage reurn and line feed to ut output on seprate lines.
o_set db "Overflow flag set", 13, 10, "$"
o_notset db "Overflow flag not set", 13, 10, "$"
segment code_seg
start:
push bp
mov bp, sp
mov ax, data_seg ; We must set up the DS register by pointing
; at the segment with our data
mov ds, ax
test ax, ax ; Make sure overflow flag is cleared
; Not guaranteed when our program starts
mov cl, 99
jo of_flag_set ; You jumped to the wrong label when overflow was set
push o_notset
call printf
add sp, 2
add cl, 98
jo of_flag_set
jmp endme
of_flag_set:
push o_set
call printf
add sp, 2
endme:
mov sp, bp
pop bp
mov ah, 0h
int 20h
; Need to put offset to msg on stack prior to call. Stack cleaned up by callee
printf:
push bp
mov bp, sp
mov dx, [bp+4] ;cant pop the retn addr into dx
mov ah, 09h
int 21h
mov sp, bp
pop bp
ret
Your string didn't print properly (they were shifted on the screen) because you didn't setup the DS (Data segment) register. When creating DOS MZ (EXE) programs you need to explicitly move the segment location of your data area data_seg
to DS. Because you didn't do this your strings were being printed from the wrong locations.
I added carriage return and line feed to your strings so they print on separate lines.
Your code can't rely on the overflow flag being cleared when the program starts. You need to use an instruction that will clear it. test ax, ax
will do the trick if you don't mind it altering other flags.
There was a bug in one of your jo
instructions where it went to the incorrect label when overflow was detected.
Upvotes: 3