NASM组装了bootloader内存问题

时间:2015-06-20 02:27:24

标签: assembly nasm bootloader

我正在用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

程序无法正常运行。按下输入后,它会不断打印相同的字符。这个错误是如何纠正的?

1 个答案:

答案 0 :(得分:3)

当前的问题是,您的prints销毁了bx(因为它设置了blbh),因此您的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:学习使用调试器。