【问题标题】:16 bit Assembly not printing character16 位汇编不打印字符
【发布时间】:2013-12-20 02:12:08
【问题描述】:

我有一个基本的引导加载程序,它应该将根扇区从 FAT12 格式化软盘读取到内存中。 (该部分有效)但在实现之后它停止将字符写入屏幕。上次它这样做是因为我忘了弹出一个寄存器。 但我已经三重检查了我是否将每个寄存器都 POP 回来。

我也使用过 BOCHS Debugger,据此它刚刚到达末尾并执行打印字符命令。

我现在被困住了。如果有人能看一下我的代码,我会非常高兴。

这是我的代码:

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

提前致谢。

-蒂姆

PS: (对于那些会说我不应该复制代码的人) 我只从brokenthorn复制了“检查文件是否存在”代码,以查看我是否正确加载了ROOT。

【问题讨论】:

  • 不要链接到代码 - 将其直接放在您的问题中(并正确格式化)。
  • 没关系,但是当je LOAD_FAT 被占用时,您似乎不会弹出cx
  • 就像你说的那样。应该没关系。所以它没有修复它。
  • 这不是您的问题,但请检查“重置驱动器”。应该是dl
  • 弗兰克·科特勒,确实如此。但不能解决问题。谢谢你。

标签: assembly x86 16-bit fat


【解决方案1】:

我修好了。

在 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

希望对遇到同样问题的朋友有所帮助!

-蒂姆

【讨论】:

    猜你喜欢
    • 2021-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多