为什么我的汇编程序在执行'int 13h'时会卡住?

Why does my assembly program gets stuck when it's excuting 'int 13h'?

我正在尝试做一个操作系统,我写了两个程序:boot.asm和loader.asm,编译过程非常成功,但是当我使用bochs调试时我的程序,它卡在命令 'int 13h' 处。有人解决这个问题吗?

这是我的代码:

boot.asm:

org 07c00h

...
BPB_SecPerTrk dw 18
BS_DrvNum db 0
...

ReadOneSector:
    push bp
    mov sp, sp
    sub esp, 2
    mov byte [bp-2], cl
    push bx
    mov bl, [BPB_SecPerTrk]
    div bl
    inc ah
    mov cl, ah
    mov dh, al
    shr al, 1
    mov ch, al
    and dh, 1
    pop bx
    mov dl, [BS_DrvNum]
Label_Go_Reading:
    mov ah, 2
    mov al, byte [bp-2]
    int 13h ; the program gets stuck when running this line
    jc Label_Go_Reading
    add esp, 2
    pop bp
    ret
...

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

调试器的输出如下:

<bochs:45> n
Next at t=14041939
(0) [0x000000007ca1] 0000:7ca1 (unk. ctxt): mov al, byte ptr ss:[bp-2] ; 8a46fe
<bochs:46> n
Next at t=14041940
(0) [0x000000007ca4] 0000:7ca4 (unk. ctxt): int 0x13                  ; cd13
<bochs:47> n ;the program gets stuck when executing this line

谁能告诉我为什么程序会卡住以及如何解决这个问题(我想可能之前的代码不能让'int 13h' 运行)

ReadOneSector:
    push bp
    mov sp, sp     <<<<<<<<<<<<<<<<<<<<<<<<<<<<
    sub esp, 2
    mov byte [bp-2], cl

第三行有错字。您要加载 BP 寄存器,而不仅仅是 SP!

上的 nop

下一个解决方案避免将局部变量放入堆栈:

; IN (ax,es:bx,cl)
ReadOneSector:
    push  bp
    mov   ch, 2     ; CH Function number
    mov   bp, cx    ; CL Sector count
    push  bx
    mov   bl, [BPB_SecPerTrk]
    div   bl
    inc   ah
    mov   cl, ah
    mov   dh, al
    shr   al, 1
    mov   ch, al
    and   dh, 1
    pop   bx
    mov   dl, [BS_DrvNum]
Label_Go_Reading:
    mov   ax, bp    ; -> AH function number, AL sector count
    int   13h
    jc    Label_Go_Reading
    pop   bp
    ret

如果这个例程被命名为“读取一个扇区”,那么为什么还有一个参数(在CL中)用于扇区数?
无论如何,对于 reading/writing 多个扇区,最好是 read/write 一个扇区并循环重复(查找 ):

; IN (ax,es:bx,cl)
ReadMultipleSectors:
    pusha
    movzx bp, cl    ; CL Sector count 1+
NextSector:
    push  ax        ; (1)
    push  bx        ; (2)
    mov   bl, [BPB_SecPerTrk]
    div   bl
    inc   ah
    mov   cl, ah
    mov   dh, al
    shr   al, 1
    mov   ch, al
    and   dh, 1
    pop   bx        ; (2)
    mov   dl, [BS_DrvNum]
Label_Go_Reading:
    mov  ax, 0201h
    int  13h
    jc   Label_Go_Reading
    pop  ax         ; (1)
    inc  ax         ; Next sector number
    add  bx, 512    ; Next sector buffer
    dec  bp
    jnz  NextSector
    popa
    ret