8086汇编程序始终打印相同的字符串



我已经使用 emu8086 编写了以下程序,并启用了 fasm-syntax。如您所见,程序应该第一次打印"溢出标志未设置",然后在添加设置溢出标志后,它应该打印"溢出标志未设置"。

然而,事实并非如此。相反,程序在任何情况下都会打印"溢出标志集"。我已经逐步完成了这段代码,o_set位于地址 0,o_notset位于地址 13h。 无论在调用 int 21h 和 al 09h 时将 13h 或 0h 放入 dx 中,它都会打印"溢出标志集"。我在这里感到困惑,因为我实际上将它们分配为数据段中的两个独立区域。请注意,跳转逻辑似乎工作正常,问题是无论在 dx 中放置什么,始终打印相同的消息。事实上,如果我在 dx 里面放一个 99,它仍然打印"溢出标志集"。

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

我已经评论了错误和需要修复的事情:

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

您的字符串未正确打印(它们在屏幕上移动(,因为您没有设置 DS(数据段(寄存器。创建 DOS MZ (EXE( 程序时,需要将数据区域的段位置显式移动到 DS data_seg。因为您没有这样做,所以您的字符串是从错误的位置打印的。

我为您的字符串添加了回车符和换行符,以便它们在单独的行上打印。

代码不能依赖于程序启动时清除的溢出标志。您需要使用将清除它的指令。 如果您不介意更改其他标志,test ax, ax会做到这一点。

您的一条jo指令中存在一个错误,当检测到溢出时,它会转到错误的标签。

最新更新