2015-06-20 3 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 (потому что он устанавливает 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: Научитесь использовать отладчик.

+0

Почему pusha/popa необходим в считывателе символов? Не прерывайте ли программные прерывания все регистры? Не mov ax, 1000h; int 16h; ret делать то же самое? – Gene

+0

@Gene это не нужно, но я не коснулся этой части кода. Я не оптимизировал его, просто исправил ошибки. – Jester

+0

@Jester Что-то вроде [Bochs] (http://bochs.sourceforge.net/)? – motoku