Stack corruption problem [Solved]
Posted: Wed Feb 18, 2009 2:57 pm
I have a function that reads x sectors from a disk. It works fine as long as there are no disk errors, and even completes if there are, but for some reason when there is a disk error (in this case disk not ready) and it recovers properly (disk becomes ready, so read is successful) there's stack corruption. Comparing SP before and after looks like something is getting pushed but not popped, but I can't figure out why. Part of it is probably the fact that I've been staring at it for about 3-4 hours now (with breaks every so often). The value that shouldn't be looks to be the value pushed at the commented location below.
Here's the function (real mode):
Registers and stack just before .tryLoop:
Registers and stack at normal 'ret':
This has been driving me crazy, and is keeping me from finishing my 512-byte OS.
Edit:
Note to self: Load destination segment before trying to write there.
I think I was overwriting the IVT, and since I didn't disable interrupts it screwed something up. My OS still crashes, but it finishes the function under the same conditions as before so I'm pretty sure it's something else I screwed up.
Edit 2.0: Turns out said screw up was caused by the program I was calling, not the OS itself. I just have one last feature to implement and my 512-byte OS will be done!
Here's the function (real mode):
Code: Select all
;; Read specified 16-bit LBA to ES:BX
;; ax = LBA
;; bx = offset
;; cl = numSectors
;; es = segment
readDisk:
;; save the sector count
push cx
;; LBA -> CHS
xor dx, dx
div word [BPB_SecPerTrk]
inc dx
mov cl, dl
xor dx, dx
div word [BPB_NumHeads]
mov ch, al
mov dh, dl
sal ah, 6
or ah, cl
mov cl, ah
;; retrieve sector count
pop ax
;; zero error counter
xor ah, ah
.tryLoop:
;; save error counter
;; This seems to be the problematic push
push ax
;; set BIOS parameters
mov ah, 0x02
mov dl, [BPB_DriveNumber]
;; and do the call
int 13h
;; retrieve error counter
pop ax
;; if(error)
jc .readError
;; else
ret
.readError:
;; increment error counter
inc ah
;; check if we've reached 4 tries
and ah, 0x04
;; if not
jz .tryLoop
;; else
returnC:
;; set error flag and return
stc
ret
Code: Select all
ax: 0001
bx: 0000
cx: 0011
dx: 0101
si: 7BEE
di: 0003
sp: 7BF8
Stack:
[7BF8] 7DB5 <-- return Addr
Code: Select all
ax: 0046
bx: 0000
cx: 0011
dx: 0100
si: 7BEE
di: 0003
sp: 7BF6
Stack:
[7BF6] 0001 <-- Shouldn't be here!
[7BF8] 7DB5 <-- return Addr
Edit:
Note to self: Load destination segment before trying to write there.
I think I was overwriting the IVT, and since I didn't disable interrupts it screwed something up. My OS still crashes, but it finishes the function under the same conditions as before so I'm pretty sure it's something else I screwed up.
Edit 2.0: Turns out said screw up was caused by the program I was calling, not the OS itself. I just have one last feature to implement and my 512-byte OS will be done!