为什么我的汇编程序在执行'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
我正在尝试做一个操作系统,我写了两个程序: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
!
下一个解决方案避免将局部变量放入堆栈:
; 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