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

Time:03-11

I'm trying to make an operating system and I've written two programs: boot.asm and loader.asm, the compilation process was very success, but when I'm using bochs to debug my program, it gets stuck at the command 'int 13h'.Did anyone has a solution to this problem?

Here's my code:

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

Here's the debugger's output:

<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

Can anyone tell me why does the program gets stuck and how to solve this problem(I think maybe the code before can't let 'int 13h' run)

CodePudding user response:

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

There's a typo in the third line. You want to load the BP register, not just nop on SP!

Next solution avoids putting a local variable on the stack:

; 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

If this routine is named "Read One Sector", then why is there even a parameter (in CL) for the number of sectors?
Anyway, for reading/writing several sectors it's probably best to read/write a single sector and repeat that in a loop (look up multitrack problem):

; 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
  • Related