我正在用nasm编写一个bootloader。目前它被设计为输出欢迎字符串,然后在显示时记录击键,在找到回车键时打印存储的击键,最后停止。
bits 16
org 0x7C00
start: jmp main
bgetkey: pusha
mov ax, 0
mov ah, 10h
int 16h
mov [.buf], ax
popa
mov ax, [.buf]
ret
.buf dw 0
prints: mov ah, 0x0e
mov al, [si]
cmp al, 0
jz print_end
mov bh, 0x00
mov bl, 0x07
int 0x10
inc si
jmp prints
print_end: ret
main: mov ax, 0x0000 ; set register a
mov ds, ax ;
mov bx, mem
add bx, word 1
mov word [mem], bx
mov si, welcome ; set and prints
call prints ;
type: mov si, qbuf ; set prints ptr
call bgetkey ; capture input
mov [qbuf], al ; set char to sz
call prints ; call print str
mov bx, [mem] ; put chr in mem
cmp bx, stop ; compare loader
je oom ; end and memory
mov byte [bx], al
add bx, byte 1
mov [mem], bx ;
cmp byte [qbuf], 0x0D ; cmpr enter key
jne type ; continue next
mov si, newline ; print newline
call prints ;
mov bx, mem
printmem: cmp byte [bx], 0x00 ; check for zero
je halt ; halt the cpu
mov cl, [bx]
mov byte [qbuf], cl ; buffer and cpy
mov si, qbuf ; pointer to si
call prints ; print the char
inc bx
jmp printmem ; jump beginning
oom: mov si, outomem ; no more memory
call prints ; print message
halt: mov si, halting ; cpu is halting
call prints ; print last msg
hlt ; halt the cpu
welcome db "bootloader", 0x0A, 0x0D, 0x00
newline db 0x0A, 0x00
outomem db "out of memory", 0x0A, 0x0D, 0x00
halting db "halting", 0x00
qbuf dw 0, 0
mem db 0
times 0200h - 2 - ($ - $$)db 0
stop dw 0xAA55
程序无法正常运行。按下输入后,它会不断打印相同的字符。这个错误是如何纠正的?
答案 0 :(得分:3)
当前的问题是,您的prints
销毁了bx
(因为它设置了bl
和bh
),因此您的printmem
循环需要bx
被保存起来。
但是,它也会破坏al
,因此您的输入循环也不会在内存中存储正确的值,也可以。
此外,虽然您希望mem
成为mem + 2
的指针,但它实际上是指向mem + 1
的指针,因此您使用输入覆盖指针。此外,您从mem
而不是mem + 2
开始打印。
最后,您的输入不会被您正在检查的零点终止,它会被0x0D
(输入)终止。
工作版可以是:
bits 16
org 0x7C00
start: jmp main
bgetkey: pusha
mov ax, 0
mov ah, 10h
int 16h
mov [.buf], ax
popa
mov ax, [.buf]
ret
.buf dw 0
prints: pusha
.loop:
mov ah, 0x0e
mov al, [si]
cmp al, 0
jz print_end
mov bh, 0x00
mov bl, 0x07
int 0x10
inc si
jmp .loop
print_end: popa
ret
main: mov ax, 0x0000 ; set register a
mov ds, ax ;
mov bx, mem
add bx, word 2 ; point to after the pointer :)
mov word [mem], bx
mov si, welcome ; set and prints
call prints ;
type: mov si, qbuf ; set prints ptr
call bgetkey ; capture input
mov [qbuf], al ; set char to sz
call prints ; call print str
mov bx, [mem] ; put chr in mem
cmp bx, stop ; compare loader
je oom ; end and memory
mov byte [bx], al
add bx, byte 1
mov [mem], bx ;
cmp byte [qbuf], 0x0D ; cmpr enter key
jne type ; continue next
mov si, newline ; print newline
call prints ;
mov bx, mem+2 ; start from after the pointer
printmem: cmp byte [bx], 0x0D ; check for end
je halt ; halt the cpu
mov cl, [bx]
mov byte [qbuf], cl ; buffer and cpy
mov si, qbuf ; pointer to si
call prints ; print the char
inc bx
jmp printmem ; jump beginning
oom: mov si, outomem ; no more memory
call prints ; print message
halt: mov si, halting ; cpu is halting
call prints ; print last msg
hlt ; halt the cpu
welcome db "bootloader", 0x0A, 0x0D, 0x00
newline db 0x0A, 0x00
outomem db "out of memory", 0x0A, 0x0D, 0x00
halting db "halting", 0x00
qbuf dw 0, 0
mem db 0
times 0200h - 2 - ($ - $$)db 0
stop dw 0xAA55
PS:学习使用调试器。