BIOS阅读部门

Jer*_*ov2 2 boot x86 assembly bios nasm

我已经考虑过为了学习而制作一个小操作系统,现在我正在使用bootloader.我希望能够用来int 0x13从软盘驱动器读取扇区,将它们放入内存,然后跳转到该代码.这是我到目前为止:

org 0x7c00
bits 16

main:
    call setup_segments

    mov ah, 2      ; function
    mov al, 1      ; num of sectors
    mov ch, 1      ; cylinder
    mov cl, 2      ; sector
    mov dh, 0      ; head
    mov dl, 0      ; drive
    mov bx, 0x1000 ;
    mov es, bx     ; dest (segment)
    mov bx, 0      ; dest (offset)
    int 0x13       ; BIOS Drive Interrupt

    jmp 0x1000:0   ; jump to loaded code

times 510 - ($-$$) db 0 ; fluff up program to 510 B
dw 0xAA55               ; boot loader signature




LoadTarget: ; Print Message, Get Key Press, Reboot

jmp new_main

Greeting: db "Hello, welcome to the bestest bootloader there ever was!", 0
Prompt:   db "Press any key to reboot...", 0

Println:
    lodsb ; al <-- [ds:si], si++

    or al, al    ; needed for jump ?
    jz PrintNwl  ; if null is found print '\r\n'
    mov ah, 0x0e ; function
    mov bh, 0    ; page number ?
    mov bl, 7    ; text attribute ?
    int 0x10     ; BIOS Interrupt
    jmp Println

PrintNwl: ; print \r\n
    ; print \r
    mov ah, 0x0e ; function
    mov al, 13   ; char (carriage return)
    mov bh, 0    ; page number ?
    mov bl, 7    ; text attribute ?
    int 0x10

    ; print \n
    mov ah, 0x0e ; function
    mov al, 20   ; char (line feed)
    mov bh, 0    ; page number ?
    mov bl, 7    ; text attribute ?
    int 0x10

    ret          ; return

GetKeyPress:
    mov si, Prompt ; load prompt
    call Println   ; print prompt

    xor ah, ah     ; clear ah
    int 0x16       ; BIOS Keyboard Service

    ret            ; return

setup_segments:
    cli ;Clear interrupts
    ;Setup stack segments
    mov ax,cs
    mov ds,ax
    mov es,ax
    mov ss,ax
    sti ;Enable interrupts

    ret

new_main:
    call setup_segments

    mov si, Greeting ; load greeting
    call Println     ; print greeting

    call GetKeyPress ; wait for key press

    jmp 0xffff:0     ; jump to reboot address

times 1024 - ($-$$) db 0 ; fluff up sector
Run Code Online (Sandbox Code Playgroud)

我想在LoadTarget进入地址后加载扇区0x1000:0,然后跳转到它.到目前为止,我只是得到一个空白屏幕.我觉得这个bug是介于main而行times 510 - ($-$$) db 0.也许我只是没有得到正确的寄存器值?请帮忙!谢谢

Fif*_*nik 5

您应该将第一个替换为call setup_segments执行该工作的实际指令.同样,Jester指出在更改SS寄存器时始终更新SP寄存器.

目前你正在读取气缸1.它应该是气缸0.

换行符的代码是10(不是你写的20).

PrintNwl中的两个BIOS调用都不需要BL寄存器,因为CR和LF都是不可显示的ascii.

  • 哇我简直不敢相信我搞砸了'\n'字符了!我知道它是10,我不知道为什么我放20.我也会修复其他的错误,谢谢! (2认同)