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

时间:2018-03-17 02:05:09

标签: assembly x86 emu8086

我使用启用了fasm语法的emu8086编写了以下程序。正如您所看到的,程序应该在第一次打印“溢出标志未设置”,然后在添加设置溢出标志之后,应该打印“溢出标志未设置”。

但是,这不是正在发生的事情。该程序在任何情况下都会打印“溢出标志设置”。我已经完成了这个代码,o_set在地址0,o_notset在地址13h。 无论13h或0h是否在21h时被调到dx,调用al 09h,它会打印“溢出标志设置。”我在这里很困惑,因为我确实将它们分配为两个数据段中的单独区域。请注意,跳转逻辑似乎工作正常,问题是无论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

1 个答案:

答案 0 :(得分:3)

我评论了错误并需要修复的事情:

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)程序时,您需要明确地将数据区data_seg的段位置移动到 DS 。因为你没有这样做,你的字符串是从错误的位置打印出来的。

我在字符串中添加了回车符和换行符,因此它们会在不同的行上打印。

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

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