Assembly Int 13h不是';我不在QEMU上工作。程序崩溃了

Assembly Int 13h不是';我不在QEMU上工作。程序崩溃了,assembly,nasm,interrupt,qemu,real-mode,Assembly,Nasm,Interrupt,Qemu,Real Mode,我将循序渐进地介绍如何从stratch构建操作系统。如果有人问我,我可以发布pdf。所以,我有一个“磁盘加载”的调用,它没有任何理由不起作用。我已经检查了每一个参数很多次了,它就是不起作用 这是密码 test.asm ; Read some sectors from the boot disk using our disk_read function [org 0x7c00] mov [BOOT_DRIVE],dl; BIOS stores our boot drive in DL , so i

我将循序渐进地介绍如何从stratch构建操作系统。如果有人问我,我可以发布pdf。所以,我有一个“磁盘加载”的调用,它没有任何理由不起作用。我已经检查了每一个参数很多次了,它就是不起作用

这是密码

test.asm

; Read some sectors from the boot disk using our disk_read function
[org 0x7c00]
mov [BOOT_DRIVE],dl; BIOS stores our boot drive in DL , so it ’s
                    ; best to remember this for later.
mov bp , 0x8000     ; Here we set our stack safely out of the
mov sp , bp         ; way , at 0 x8000

mov bx , 0x9000     ; Load 5 sectors to 0 x0000 (ES ):0 x9000 (BX)
mov dh , 5          ; from the boot disk.
mov dl , [BOOT_DRIVE]
call disk_load

mov dx , [0x9000]   ; Print out the first loaded word , which
call print_hex      ; we expect to be 0xdada , stored
                    ; at address 0 x9000
mov dx , [0x9000 + 512] ; Also , print the first word from the
call print_hex      ; 2nd loaded sector : should be 0 xface
jmp $

%include "print_string.asm" ; Re - use our print_string function
%include "print_hex.asm" ; Re - use our print_hex function
%include "disk_load.asm"
; Include our new disk_load function

; Global variables
BOOT_DRIVE: db 0

; Bootsector padding
times 510-($-$$) db 0
dw 0xaa55

; We know that BIOS will load only the first 512- byte sector from the disk ,
; so if we purposely add a few more sectors to our code by repeating some
; familiar numbers , we can prove to ourselfs that we actually loaded those
; additional two sectors from the disk we booted from.
times 256 dw 0xdada
times 256 dw 0xface
                ; load DH sectors to ES:BX from drive DL
disk_load:
push dx         ; Store DX on stack so later we can recall
                ; how many sectors were request to be read ,
                ; even if it is altered in the meantime
mov ah , 0x02   ; BIOS read sector function
mov al , dh     ; Read DH sectors
mov ch , 0x00   ; Select cylinder 0
mov dh , 0x00   ; Select head 0
mov cl , 0x02   ; Start reading from second sector ( i.e.
                ; after the boot sector )
mov dl, 0x80
int 0x13        ; BIOS interrupt
jc disk_error   ; Jump if error ( i.e. carry flag set )
pop dx          ; Restore DX from the stack
cmp dh , al     ; if AL ( sectors read ) != DH ( sectors expected )
jne disk_error  ; display error message
ret

disk_error:
mov bx,DISK_ERROR_MSG
call print_string
mov dl, ah
call print_hex
jmp $


; Variables
DISK_ERROR_MSG db "Disk read error: ", 0
磁盘加载.asm

; Read some sectors from the boot disk using our disk_read function
[org 0x7c00]
mov [BOOT_DRIVE],dl; BIOS stores our boot drive in DL , so it ’s
                    ; best to remember this for later.
mov bp , 0x8000     ; Here we set our stack safely out of the
mov sp , bp         ; way , at 0 x8000

mov bx , 0x9000     ; Load 5 sectors to 0 x0000 (ES ):0 x9000 (BX)
mov dh , 5          ; from the boot disk.
mov dl , [BOOT_DRIVE]
call disk_load

mov dx , [0x9000]   ; Print out the first loaded word , which
call print_hex      ; we expect to be 0xdada , stored
                    ; at address 0 x9000
mov dx , [0x9000 + 512] ; Also , print the first word from the
call print_hex      ; 2nd loaded sector : should be 0 xface
jmp $

%include "print_string.asm" ; Re - use our print_string function
%include "print_hex.asm" ; Re - use our print_hex function
%include "disk_load.asm"
; Include our new disk_load function

; Global variables
BOOT_DRIVE: db 0

; Bootsector padding
times 510-($-$$) db 0
dw 0xaa55

; We know that BIOS will load only the first 512- byte sector from the disk ,
; so if we purposely add a few more sectors to our code by repeating some
; familiar numbers , we can prove to ourselfs that we actually loaded those
; additional two sectors from the disk we booted from.
times 256 dw 0xdada
times 256 dw 0xface
                ; load DH sectors to ES:BX from drive DL
disk_load:
push dx         ; Store DX on stack so later we can recall
                ; how many sectors were request to be read ,
                ; even if it is altered in the meantime
mov ah , 0x02   ; BIOS read sector function
mov al , dh     ; Read DH sectors
mov ch , 0x00   ; Select cylinder 0
mov dh , 0x00   ; Select head 0
mov cl , 0x02   ; Start reading from second sector ( i.e.
                ; after the boot sector )
mov dl, 0x80
int 0x13        ; BIOS interrupt
jc disk_error   ; Jump if error ( i.e. carry flag set )
pop dx          ; Restore DX from the stack
cmp dh , al     ; if AL ( sectors read ) != DH ( sectors expected )
jne disk_error  ; display error message
ret

disk_error:
mov bx,DISK_ERROR_MSG
call print_string
mov dl, ah
call print_hex
jmp $


; Variables
DISK_ERROR_MSG db "Disk read error: ", 0
我收到了错误信息
磁盘读取错误:0x000C
我知道这意味着
找不到媒体类型(软盘)

既然
print\u string
print\u hex
都很好,我就不发了


我已经检查了每一段代码,对我来说一切都正常。

我发现了错误。我试图从磁盘加载5个扇区,但其中只有3个。

您从未初始化段寄存器。除了CS,它们可以是任何东西。段寄存器是ES:BX,对吗?段寄存器以“s”结尾表示“段”。CS=代码段,DS=数据段,ES=额外段,SS=堆栈段我来看看代码。试着把它修好。如果它不起作用,我会很快在这里更新。ThxSee:还要注意堆栈会向下扩展。谢谢!我对此也感到困惑。顺便说一句,它不应该仍然是3段,而是2段,因为您省略了引导扇区。:-)