2015-06-20 17 views
0

我正在用nasm編寫引導程序。目前,它設計用於輸出歡迎字符串,然後在顯示時記錄擊鍵,在找到回車鍵時打印存儲的擊鍵,最後停止。NASM組裝的引導程序內存問題

   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

'mov [mem],cx'對我來說看起來很有趣。你打算在那裏做'bx'嗎? –

+0

你忘了指定一個堆棧段和一個堆棧指針。 –

+0

@FrankKotler是的,我打算把'bx' – motoku

回答

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:學習如何使用調試器。

+0

爲什麼char *讀者需要pusha/popa?不要軟件中斷保存所有寄存器?不要mov ax,1000h; int 16h; ret做同樣的事情? – Gene

+0

@Gene這不是必需的,但我沒有觸及代碼的那部分。我沒有優化它,只是修復了錯誤。 – Jester

+0

@Jester像[Bochs](http://bochs.sourceforge.net/)? – motoku