扇区 1 无 BIOS 输出

问题描述 投票:0回答:1

我需要知识和进一步的澄清(要么是写在文档中,我很难通过谷歌搜索或使用 GitHub 存储库来找到)转到所需的部门(就我而言)它是扇区 1),因为由于缺乏对正确顺序/代码排列的理解,我仍然无法使其完全发挥作用。

代码如下:

org 0x7c00
bits 16

mov ah, 0x02 ; reading
mov al, 0x1
mov ch, 0x0
mov cl, 0x1 ; sector 1
mov dh, 0x0
mov dl, 0x00 ; from floppy (.img)
int 13h

jc error ; error handling for the wrong/absent position
jmp 0x0200 ; trying to jump to the address

error:
  mov bx, [errorline]
  mov ah, 0x0e
  printerr:
    mov al, [bx]
    cmp al, 0
    je end
    inc bx
    jmp printerr

end:
  cli
  hlt
  jmp $

errorline:
  db "Couldn't go and execute from sector 1", 0

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

;outside the boot sector

jmp target

target:
  mov bx, [targetline]
  mov ah, 0x0e
  printtarg:
    mov al, [bx]
    cmp al, 0
    je end
    int 0x10
    inc bx
    jmp printtarg

end:
  cli
  hlt
  jmp $

targetline:
  db "Success.", 0

;end of the sector 1 code
times 0x400-($-$$) db 0

我几天来一直在努力解决这个问题(定义扇区1以便去打印一些东西。),并且仍在寻求更有经验的人的建设性解释和直接解决方案。最好有完整的代码,我将不胜感激您的帮助

x86 virtualbox nasm bootloader osdev
1个回答
0
投票

此 NASM 代码中存在一些问题

  • 未设置段寄存器
  • 未通过设置 SS:SP 提供足够的堆栈
  • 没有为 BIOS.ReadSector 函数指定地址
  • 没有意识到扇区号是从 1 开始的(而不是像磁头和柱面那样从 0 开始)
  • 在需要加载地址本身的情况下加载消息的第一个字符
  • 忘记了
    int 10h
    来实际执行BIOS.Teletype功能
  • 使用硬编码
    mov dl, 0x00
    ,而不是信任 BIOS 将在 0x7C00 处传递给引导加载程序的 DL 值
  • 在引导扇区上使用错误的签名,这应该会导致 BIOS 无法识别
  • 重新定义end标签。 NASM没有抱怨过这个吗?

改进后的代码

org 0x7c00
bits 16

XOR AX, AX
MOV DS, AX
MOV ES, AX
MOV SS, AX
MOV SP, 0x7C00

MOV BX, 0x7E00            ; Full pointer is ES:BX
mov ah, 0x02              ; BIOS.ReadSector
mov al, 0x1
mov ch, 0x0
mov cl, 0x2               ; Sector 1 is executing already! We need sector 2
mov dh, 0x0               ; BIOS gave us DL
int 13h
jc  error
jmp target                ; Corresponds to address 0x7E00

error:
  mov bx, errorline       ; This loads the address itself
  mov ah, 0x0E            ; BIOS.Teletype
  printerr:
    mov al, [bx]
    cmp al, 0
    je  end
    int 10h               ; Actually invoking BIOS
    inc bx
    jmp printerr

end:
  cli
  hlt
  jmp end

errorline:
  db "Couldn't go and execute from sector 2", 0

times 510-($-$$) db 0
dw 0xAA55                 ; In memory first byte is 55h, second byte is AAh  

;outside the boot sector
; HERE STARTS SECTOR 2

target:
  mov bx, targetline      ; This loads the address itself
  mov al, [bx]            ; First char is non-zero for sure
  printtarg:
    mov ah, 0x0E          ; BIOS.Teletype
    int 0x10
    inc bx
    mov al, [bx]
    cmp al, 0             ; Efficient loops have their loop condition below
    jne printtarg
    jmp end               ; Sector 1 is still there, so re-use some of its code
                          ; Could have doen the same for the printing of course!
targetline:
  db "Success.", 0

;end of the sectors 1 and 2 code
times 1024-($-$$) db 0    ; No signature needed here

它只是打印一个杂项符号(≡)。如果有任何不必要的代码行导致该问题,您可以指出要删除哪一行。代码行号是可选的,以便更好地说明。

上面的完整代码应该可以解决问题。注意我在程序中添加的尾部注释。

© www.soinside.com 2019 - 2024. All rights reserved.