Stack corruption problem [Solved]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
Firestryke31
Member
Member
Posts: 550
Joined: Sat Nov 29, 2008 1:07 pm
Location: Throw a dart at central Texas
Contact:

Stack corruption problem [Solved]

Post by Firestryke31 »

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):

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
Registers and stack just before .tryLoop:

Code: Select all

ax: 0001
bx: 0000
cx: 0011
dx: 0101
si: 7BEE
di: 0003
sp: 7BF8

Stack:
[7BF8] 7DB5 <-- return Addr
Registers and stack at normal 'ret':

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
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!
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
Post Reply