我做了一个程序,它可以比较用户输入和字符串。第一次输入ping
时,它成功地完成了比较,并返回pong
,但第二次它没有输出任何内容。第三次它再次开始工作,然后第四次它再次停止工作。可能是什么问题呢?下面是相关代码:
key_press:
mov ah, 0x00
int 0x16
cmp al, 0x21
jge compare
jl other_chars
jmp key_press
compare:
cmp al, 0x7e
jl print
print:
pusha
mov ah, 0x0e
int 0x10
popa
mov [si], al
inc si
jmp key_press
other_chars:
cmp ah, 0x1C
je enter
cmp ah, 0x39
je space
cmp al, 0x8
je backspace
jmp key_press
enter:
pusha
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
popa
mov di, reserved
mov bx, ping_command
jmp loop1
loop1:
cmp di, si
je middle_loop1
cmp byte [bx], 0
je go_back_loop1
mov ch, [di]
cmp ch, [bx]
jne go_back_loop1
; pusha
; mov ah, 0x0e
; mov al, [di]
; int 0x10
; popa
inc di
inc bx
jmp loop1
go_back_loop1:
mov si, reserved
mov bx, ping_command
jmp key_press
middle_loop1:
mov bx, pong
pusha
jmp print_ping
print_ping:
cmp byte [bx], 0
je go_back_print_ping
mov ah, 0x0e
mov al, [bx]
int 0x10
inc bx
jmp print_ping
go_back_print_ping:
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
popa
jmp key_press
这是完整的代码:
org 0x7c00
bits 16
init:
mov ah, 0x0e
mov bx, string
mov si, reserved
jmp loop
loop:
mov al, [bx]
cmp al, 0
je key_press
int 0x10
inc bx
jmp loop
key_press:
mov ah, 0x00
int 0x16
cmp al, 0x21
jge compare
jl other_chars
jmp key_press
compare:
cmp al, 0x7e
jl print
print:
pusha
mov ah, 0x0e
int 0x10
popa
mov [si], al
inc si
jmp key_press
other_chars:
cmp ah, 0x1C
je enter
cmp ah, 0x39
je space
cmp al, 0x8
je backspace
jmp key_press
enter:
pusha
mov ah, 0x0e
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
popa
mov di, reserved
mov bx, ping_command
jmp loop1
loop1:
cmp di, si
je middle_loop1
cmp byte [bx], 0
je go_back_loop1
mov ch, [di]
cmp ch, [bx]
jne go_back_loop1
; pusha
; mov ah, 0x0e
; mov al, [di]
; int 0x10
; popa
inc di
inc bx
jmp loop1
go_back_loop1:
mov si, reserved
mov bx, ping_command
jmp key_press
middle_loop1:
mov bx, pong
pusha
jmp print_ping
print_ping:
cmp byte [bx], 0
je go_back_print_ping
mov ah, 0x0e
mov al, [bx]
int 0x10
inc bx
jmp print_ping
go_back_print_ping:
mov al, 0x0a
int 0x10
mov al, 0x0d
int 0x10
popa
jmp key_press
space:
pusha
mov ah, 0x0e
mov al, ' '
int 0x10
popa
mov byte [si], ' '
inc si
jmp key_press
backspace:
pusha
mov ah, 0x0e
int 0x10
mov al, ' '
int 0x10
mov al, 0x8
int 0x10
popa
dec si
jmp key_press
halt:
hlt
jmp halt
reserved resb 256
ping_command db "ping", 0
pong db "pong", 0
string db "Hello, World!", 0
times 510-($-$$) db 0
dw 0xAA55
1条答案
按热度按时间tyu7yeag1#
在 * 函数 *
go_back_print_ping
中,jmp key_press
应更改为jmp go_back_loop1
,以便将si
设置回reserved
。X
只是一个垃圾值,不管它是什么。si
直接指向“ping”的“g”之后的第一个字节,即X
。di
将不断递增,直到等于si
。在这种情况下会发生什么?我们将得到一个je middle_loop1
。如果您遵循middle_loop1
的代码序列,您会注意到,在任何时间点si
都不会被设置回reserved
。因此,在第二次/第四次/偶数次运行中,这是
reserved
之后内存区域的状态si
继续递增,将我们写入的第二个ping
放在第一个之后。现在,
di
将继续递增,但我们实际上是在比较上次写入的第一个ping,在这种情况下,cmp byte [bx], 0
在di
等于si
之前为真,使程序跳到go_back_loop1
,这一次将si
设置回reserved
,但它不会打印任何内容,并将程序置于这样一种状态,即即使运行,bug也会继续发生。实际上有多种方法可以解决这个问题,除了我建议的方法,还有其他问题。拿一张纸,了解所有寄存器的状态,看看会发生什么,这是一个非常有趣的练习,我认为这是理解问题的最好方法。祝你的项目好运。