8086 汇编程序总是打印相同的字符串
8086 assembly program always prints the same string
我使用启用了 fasm 语法的 emu8086 编写了以下程序。如您所见,程序应该第一次打印 "Overflow flag not set" ,然后在添加设置溢出标志后,它应该打印 "Overflow flag not set."
然而,事实并非如此。在任何情况下,该程序都会打印 "overflow flag set"。我已经逐步执行了这段代码,o_set 位于地址 0,o_notset 位于地址 13h。 无论在调用 int 21h 和 al 09h 时将 13h 还是 0h 放入 dx,它都会打印 "overflow flag set." 我在这里很困惑,因为我确实分配了它们作为数据段中的两个独立区域。请注意,跳转逻辑似乎工作正常,问题是无论在 dx 中放置什么,总是打印相同的消息。事实上,如果我在 dx 中放入一个 99,它仍然会打印 "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
我已经评论了错误和需要修复的地方:
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。因为您没有这样做,所以您的字符串是从错误的位置打印的。
我在您的字符串中添加了回车符 return 和换行符,以便它们打印在不同的行上。
您的代码不能依赖程序启动时清除的溢出标志。您需要使用将清除它的指令。 test ax, ax
如果您不介意它改变其他标志,就可以解决问题。
您的一个 jo
指令中存在一个错误,当检测到溢出时它转到了错误的标签。
我使用启用了 fasm 语法的 emu8086 编写了以下程序。如您所见,程序应该第一次打印 "Overflow flag not set" ,然后在添加设置溢出标志后,它应该打印 "Overflow flag not set."
然而,事实并非如此。在任何情况下,该程序都会打印 "overflow flag set"。我已经逐步执行了这段代码,o_set 位于地址 0,o_notset 位于地址 13h。 无论在调用 int 21h 和 al 09h 时将 13h 还是 0h 放入 dx,它都会打印 "overflow flag set." 我在这里很困惑,因为我确实分配了它们作为数据段中的两个独立区域。请注意,跳转逻辑似乎工作正常,问题是无论在 dx 中放置什么,总是打印相同的消息。事实上,如果我在 dx 中放入一个 99,它仍然会打印 "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
我已经评论了错误和需要修复的地方:
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。因为您没有这样做,所以您的字符串是从错误的位置打印的。
我在您的字符串中添加了回车符 return 和换行符,以便它们打印在不同的行上。
您的代码不能依赖程序启动时清除的溢出标志。您需要使用将清除它的指令。 test ax, ax
如果您不介意它改变其他标志,就可以解决问题。
您的一个 jo
指令中存在一个错误,当检测到溢出时它转到了错误的标签。