2013-12-03 3 views
-1

У меня есть базовый загрузчик, который должен прочитать корневые сектора из FAT12 в формате Floppy в память. (эта часть работает), но после того, как она завершила запись символов на экран. В прошлый раз это произошло потому, что я забыл зарегистрировать POP. Но я тройной проверил, что я POPping каждый реестр назад.16 бит Ассемблер не печатает символ

Я также использовал отладчик BOCHS и в соответствии с этим он просто достигает конца и выполняет команды символа печати.

Я застрял. Я был бы очень рад, если бы кто-нибудь мог взглянуть на мой код.

Это мой код:

org 0x7c00 
bits 16 

start: jmp loader 

;OEM 
TIMES 0Bh-$+start DB 0 
bpbBytesPerSector:  DW 512 
bpbSectorsPerCluster: DB 1 
bpbReservedSectors:  DW 1 
bpbNumberOfFATs:  DB 2 
bpbRootEntries:   DW 224 
bpbTotalSectors:  DW 2880 
bpbMedia:    DB 0xF0 
bpbSectorsPerFAT:  DW 9 
bpbSectorsPerTrack:  DW 18 
bpbHeadsPerCylinder: DW 2 
bpbHiddenSectors:  DD 0 
bpbTotalSectorsBig:  DD 0 
bsDriveNumber:   DB 0 
bsUnused:    DB 0 
bsExtBootSignature:  DB 0x29 
bsSerialNumber:   DD 0xa0a1a2a3 
bsVolumeLabel:   DB "MOS FLOPPY " 
bsFileSystem:   DB "FAT12 " 

;vars 

absoluteSector db 0x00 
absoluteHead db 0x00 
absoluteTrack db 0x00 

;functions 

print: 
    xor bx, bx 
    lodsb 
    cmp al, 00h 
    je print_eof 
    mov ah, 0eh 
    int 10h 
    jmp print 
print_eof: 
ret 


;************************************************; 
; Convert LBA to CHS 
; AX=>LBA Address to convert 
; 
; absolute sector = (logical sector/sectors per track) + 1 
; absolute head = (logical sector/sectors per track) MOD number of heads 
; absolute track = logical sector/(sectors per track * number of heads) 
; 
;************************************************; 

lbachs: 
    xor  dx, dx        ; prepare dx:ax for operation 
    div  WORD [bpbSectorsPerTrack]   ; calculate 
    inc  dl         ; adjust for sector 0 
    mov  BYTE [absoluteSector], dl 
    xor  dx, dx        ; prepare dx:ax for operation 
    div  WORD [bpbHeadsPerCylinder]   ; calculate 
    mov  BYTE [absoluteHead], dl 
    mov  BYTE [absoluteTrack], al 
    ret 

ReadSectors: 
    push ax ;safety 
    push bx ;safety 
    push cx ;safety 
    call lbachs ;change LBA to CHS (floppy) 
    mov ah, 0x02 ;function to read sector from floppy 
    mov al, 0x01 ;read only 1 sector 
    mov ch, [absoluteTrack] ;at track X 
    mov cl, [absoluteSector];at sector X 
    mov dh, [absoluteHead] ;at had X 
    mov dl, 0x00 ;on drive 00 (floppydrive 
    int 0x13 ;execute 
    jnc .succes ;if succeeded goto succes else: 
    mov ah, 0x00 ;reset floppy drive 
    mov bl, 0x00 ;drive 0 
    int 0x13 ;execute 
    pop cx ;pop 
    pop bx 
    pop ax 
    jmp ReadSectors ;retry 
.succes: 
    pop cx ;pop 
    pop bx 
    pop ax 
    add bx, WORD [bpbBytesPerSector] ;next 512 bytes in memory to write sector to 
    inc ax ;next sector 
    LOOP ReadSectors ;and keep looping till cx == 0 
    ret ;return 

;Bootloader 

loader: 

    mov si, msg 
    call print 

    xor cx, cx 
    mov ax, 0x0020  ; 32 byte directory entry 
    mul WORD [bpbRootEntries] ; number of root entrys 
    div WORD [bpbBytesPerSector] ; get sectors used by root directory 
    xchg cx, ax ;;cx=LENGTH in sectors 

    mov al, [bpbNumberOfFATs] ; Get number of FATs (Useually 2) 
    mul WORD [bpbSectorsPerFAT] ; number of FATs * sectors per FAT; get number of sectors 
    add ax, [bpbReservedSectors] ; add reserved sectors 
    ;AX=START as sector in LBA (so needs conversion 

    mov bx, 0x0200 ; load root directory to 7c00:0x0200 
    call ReadSectors 

    mov  cx, [bpbRootEntries]  ; the number of entrys. If we reach 0, file doesnt exist 
    mov  di, 0x0200  ; Root directory was loaded here 
    .LOOP: 
     push cx 
     mov  cx, 11   ; eleven character name 
     mov  si, imageName  ; compare the 11 bytes with the name of our file 
     push di 
    rep cmpsb      ; test for entry match 
     pop  di 
     je  LOAD_FAT   ; they match, so begin loading FAT 
     pop  cx 
     add  di, 32   ; they dont match, so go to next entry (32 bytes) 
     loop .LOOP 
     jmp  FAILURE   ; no more entrys left, file doesnt exist :(

    LOAD_FAT: 

    mov bh, 00h ;page to wwrite to. 
    mov ah, 0eh ;write character 
    mov al, 'Y' ;write the Y character 
    int 10h ;execute 
    jmp EoF ;jump to end of file 

    FAILURE: 

    mov bh, 00h ;page to write to 
    mov ah, 0eh ;write character 
    mov al, 'N' ;write the N character 
    int 10h ;execute 

    EoF: 

    mov bh, 00h ;see above :P 
    mov ah, 0eh 
    mov al, 'D' 
    int 10h 

    cli 
    hlt 

streof db 'DONE....',0x0A, 0x0D, 00h 
msg db 'Hello!', 0x0D, 0x0A, 00h 
msg2 db 'Done reading root directory!', 0x0D, 0x0A, 00h 
succ db 'YES file is found!', 00h 
fil db 'Failed no file found!', 00h 
imageName db "KRNLDR SYS" 

times 510 - ($-$$) db 0 
dw 0xAA55 

http://pastebin.com/rcX7bZLV

Спасибо заранее.

-Tim

PS: (для тех, собирается сказать, что я не должен скопировать код) я только скопировал код «проверить, существует ли файл» от brokenthorn, чтобы увидеть, если я загрузите ROOT правильно.

+0

Не ссылайтесь на код - поставить его прямо в вашем вопросе (и отформатировать его надлежащим образом). – Michael

+0

Не то, чтобы это имело значение, но вы, кажется, не выскакиваете 'cx', когда берется' je LOAD_FAT'. – Michael

+0

Хорошо, как вы сказали. не имеет значения. И поэтому он не исправил это. –

ответ

0

Я исправил его.

После того, как я осмотрел и спросил в irc, я пришел к выводу, что я не установил свои регистры стека правильно. Я изменил org 0x7c00 к org 0 и после перехода к загрузчику (loader:) я вошел стеки правильно, как это:

cli 
mov  ax, 0x07c0 
mov  ds, ax 
mov  es, ax 
mov  fs, ax 
mov  gs, ax 
mov  ax, 0x0000 
mov  ss, ax 
mov  sp, 0xFFFF 
sti 

Я надеюсь, что это помогает те, которые имеют ту же самую проблему!

-Tim

Смежные вопросы