iret error

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.
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

iret error

Post by suthers »

I'm getting an error in my ISR when it does the iret.
I get:
fetch_raw_descriptor: LDTR.valid=0
This means that my stack frame is probably messed up as Its getting a wrong descriptor.
So i decided to pop the top of the stack into my registers at different points to see if there are changes.
I popped them in the order: eax, ebx, ecx, edx, esi, ebp, edi.
So if I do this at the beginning I get:
EAX=00100459
EBX=00000008
ECX=00010246
EDX=00000034
ESI=0000000a
EBP=001002a4
EDI=00100486

and if I do it at the end I get:

EAX=00100449
EBX=00000008
ECX=00010246
EDX=00000034
ESI=0000000a
EBP=001001a4
EDI=00100476

So there doesn't seem to be much change (weird that there is change later in the stack...)
Anybody know why this happening, couldn't figure it out....
Thanks in advance,

Jules

edit: put registers in order of popping for ease of reading... and a bit of spelling fix...
User avatar
neon
Member
Member
Posts: 1567
Joined: Sun Feb 18, 2007 7:28 pm
Contact:

Post by neon »

You should use iretd instead of iret for 32 bit code.
OS Development Series | Wiki | os | ncc
char c[2]={"\x90\xC3"};int main(){void(*f)()=(void(__cdecl*)(void))(void*)&c;f();}
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Post by suthers »

nasm automatically converts it to iretd if your in 32bit code.
But I still can't see what would cause the iretd to fail...
Anybody?
Thanks in advance,

Jules
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

try the combination of bochs, debugger, and the print-stack command :wink:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Post by suthers »

Weird, the version of bochs I normally use (2.0.2) only prints "Exception: divide by zero" once, as it should, but the new version (2.3.6) I got to be able to do dbg prints it out loads of times, yet theres no loop in the code and only a single divide by zero in the code (and anyway it only ever does the interrupt once because of the LDTR error...).
Thanks, Combuster, that helps allot, it gave me this:

Code: Select all

 | STACK 0x0000 [0xff55]
 | STACK 0x0002 [0xf000]
 | STACK 0x0004 [0xff53]
 | STACK 0x0006 [0xf000]
 | STACK 0x0008 [0xff53]
 | STACK 0x000a [0xf000]
 | STACK 0x000c [0x0053]
 | STACK 0x000e [0xf007]
 | STACK 0x0010 [0x0700]
 | STACK 0x0012 [0x2f00]
 | STACK 0x0014 [0xff53]
 | STACK 0x0016 [0xf000]
 | STACK 0x0018 [0xff53]
 | STACK 0x001a [0xf000]
 | STACK 0x001c [0xff53]
 | STACK 0x001e [0xf000]
If I let it run till error

But that looks like the top off the stack after the iret has removed the top of it...
Anybody see what im doing wrong, ive made sure theres a pop for every push, etc...
Here's the isr's code:

Code: Select all

_isr:
	mov [store_1], eax
	pop eax
	mov [store_2], eax
	mov eax, [store_1]
	pusha
	push es
	push ds
	push fs
	push gs
	mov ax, 0x10
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
	mov eax, _int_handler
	mov ebx, [store_2]
	push ebx
	call eax
	pop eax
	pop gs
	pop fs
	pop ds
	pop es
	popa
	add esp, 4
	sti
	iret

...

SECTION .data

...

store_1 dd 0
store_2 dd 0

Its called by stubs that look like this:

Code: Select all

_isr0:
	cli
	hlt
	push byte 0
	push byte 0
	jmp _isr

_isr1:
	cli
	push byte 0
	push byte 1
	jmp _isr
...

numbered 0 - 31.
and the int handler looks like this:

Code: Select all


void int_handler(int err_code)
{
	k_printf(exception_messages[err_code], 0x04);
	return;
};
everything compiles/assembles/links with no errors/warnings (except compile warning: "warning: division by zero", but that's done on purpose to trigger an interrupt).
Can't see what I'm doing wrong...
Anybody see what's wrong with it?
Thanks in advance,

Jules

P.S. Sorry for dumping so much code... (But there's been worse...) :wink:

edit: changed Dex to Combuster, I always get confused because you use a picture of dexter from the cartoon dex's lab as your avatar, sorry... :oops:

second edit: thanks for the tip Combuster, that can be really useful
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Is that the stack before the iret, or after? If it's from before, why are you running code in 16-bit mode?
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Post by suthers »

Its from after an I'm definitely in 32bit protected mode.
Still can't figure out what's wrong and I can't find a doc on the structure of the LDTR(though if I looked carefully in the Intel manuals i'll probably find it...), so I'm not quite sure why I'm getting an LDTR invalid error...
Thanks in advance,

Jules
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

Does this still crash ?.

Code: Select all

_isr:
	mov [store_1], eax
	pop eax
	mov [store_2], eax
	mov eax, [store_1] 
	pusha
	push es
	push ds
	push fs
	push gs
	mov ax, 0x10
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
   mov eax,esp
   push eax
	mov eax, _int_handler
	mov ebx, [store_2]
	call eax
	pop eax
	pop gs
	pop fs
	pop ds
	pop es
	popa
	add esp, 4
	iret
or this:

Code: Select all

_isr:
   pop eax
	mov [store_1], eax
	pop eax
	mov [store_2], eax
	mov eax, [store_1] 
	pusha
	push es
	push ds
	push fs
	push gs
	mov ax, 0x10
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
   mov eax,esp
   push eax
	mov eax, _int_handler
	mov ebx, [store_2]
	call eax
	pop eax
	pop gs
	pop fs
	pop ds
	pop es
	popa
	iret
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Post by suthers »

Whats the point in that, all it does is passes the a pointer to the place where the contence of gs is on the stack to the function, which is not what I want to do, I'm passing the interrupt number to the function...
Thanks in advance,

Jules

P.S. Now that I look at it your trying to see whats wrong with the stack frame, so i'll try and see what happens and i'll post as soon as I do the test...
User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

I am not in C at all, but this is a commone C int stub

Code: Select all

_isr:
	pusha
	push es
	push ds
	push fs
	push gs
	mov ax, 0x10
	mov ds, ax
	mov es, ax
	mov fs, ax
	mov gs, ax
   mov eax,esp
   push eax
	mov eax, _int_handler
	call eax
	pop eax
	pop gs
	pop fs
	pop ds
	pop es
	popa
	add esp, 8
	iret
I was only try to workout what's going wrong in the stack, but do not shoot the messenger.
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Post by Candy »

Code: Select all

_isr:
	mov [store_1], eax
	pop eax
	mov [store_2], eax
	mov eax, [store_1]
        // pusha until popa
	add esp, 4
	sti
	iret
Why do you do a pop eax, and then at the end add 4 to esp as well? That's going to mess up your stack.
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Post by suthers »

Thanks, I've managed to fix it.
@Candy: Thanks for the post, it allowed me to figure out what was wrong, I was still adding 4 to esp on top of pushing because I add stuff to the stack in the isr (as you probably figured out, that was the common part of the isr that... I was pushing a byte and for some reason adding 4, (Yah I'm pretty stupid sometimes...) so changing it to 1 fixed it.
Thanks,

Jules

edit: Oh and fixing this uncovered a series off other bugs... :cry:
User avatar
suthers
Member
Member
Posts: 672
Joined: Tue Feb 20, 2007 3:00 pm
Location: London UK
Contact:

Post by suthers »

Oh and another weird thing, if I leave out -finline-functions in as an option, my isr works (Though now I suspect it doesn't return it to the right adress), but it produces loads of errors (probably because it doesn't return to the right address). But if I leave in, I still get the LDTR not valid error, anybody got an explanation for this?
Thanks in advance,

Jules
User avatar
Ryu
Posts: 13
Joined: Sun Dec 03, 2006 8:58 am

Post by Ryu »

I noticed this besides whats already mentioned.

Code: Select all

_isr0: 
   cli 
   hlt <--- debugging???
   push byte 0 
   push byte 0 
   jmp _isr
The most obvious thing you might want to check is the local descriptor table if it is utilised properly and that LDTR is properly set.
"Our ambition should be to rule ourselves,
the true kingdom for each one of us;
and true progress is to know more,
and be more, and to do more."
~Oscar Wilde
User avatar
kmcguire
Member
Member
Posts: 120
Joined: Tue Nov 09, 2004 12:00 am
Location: United States
Contact:

Post by kmcguire »

suthers wrote:Thanks, I've managed to fix it.
@Candy: Thanks for the post, it allowed me to figure out what was wrong, I was still adding 4 to esp on top of pushing because I add stuff to the stack in the isr (as you probably figured out, that was the common part of the isr that... I was pushing a byte and for some reason adding 4, (Yah I'm pretty stupid sometimes...) so changing it to 1 fixed it.
Thanks,

Jules

edit: Oh and fixing this uncovered a series off other bugs... :cry:
I am still lost at how you were pushing a byte? You pushed sixty-four bits of data onto the stack inside the ISR stub as two zeros..

The pop eax and add esp, 4 looked correct. I can not find a instruction for pushing a immediate eight byte value in the 80386 instruction set while only incrementing the stack pointer by one. It increments it by four even though you only push one byte.
Post Reply