C invalidates my stack-variables

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
tkausl
Posts: 17
Joined: Tue Jul 14, 2015 9:54 pm

C invalidates my stack-variables

Post by tkausl »

Hello,

i am working through the following tutorial: http://www.jamesmolloy.co.uk/tutorial_h ... 20PIT.html

My irq_handler_stub with the following code:

Code: Select all

irq_common_stub:
	pusha

	mov %ds, %ax
	push %eax

	mov $0x10, %ax
	mov %ax, %ds
	mov %ax, %es
	mov %ax, %fs
	mov %ax, %gs

	call irq_handler

	pop %eax
	mov %ax, %ds
	mov %ax, %es
	mov %ax, %fs
	mov %ax, %gs

	popa
	add $8, %esp
	sti
	iret
is working as expected. The irq_handler in c looks like this:

Code: Select all

typedef struct registers
{
   u32int ds;                  // Data segment selector
   u32int edi, esi, ebp, esp, ebx, edx, ecx, eax; // Pushed by pusha.
   u32int int_no, err_code;    // Interrupt number and error code (if applicable)
   u32int eip, cs, eflags, useresp, ss; // Pushed by the processor automatically.
} registers_t;
void irq_handler(registers_t regs){
   if (regs.int_no >= 40)
   {
       outb(0xA0, 0x20);
   }
   outb(0x20, 0x20);
   printf("Got HARDWARE-Interrupt %x\n", regs.int_no);
}
i noticed a problem and a endless stream of #13 interrupts. After debugging a little bit in bochs i found the problem, the irq_handler changes the stack-variables (the passed value):
http://prntscr.com/7t8vru
both mov-instructions above the green marked instruction change the top of the stack, the second stack-value on the right (the red marked) is actually my EAX which was pushed (and will eventually get poped) in assembler, so once the CPU reaches the instruction mov %ax, %ds it will interrupt me because EAX is at this point in time just garbage. How could i fix this problem?
User avatar
thepowersgang
Member
Member
Posts: 734
Joined: Tue Dec 25, 2007 6:03 am
Libera.chat IRC: thePowersGang
Location: Perth, Western Australia
Contact:

Re: C invalidates my stack-variables

Post by thepowersgang »

By passing the registers struct by value, you tell the C compiler that's free to clobber it (it's allowed to by the calling convention).
Instead, push esp and accept a pointer, and this problem will go away.
Kernel Development, It's the brain surgery of programming.
Acess2 OS (c) | Tifflin OS (rust) | mrustc - Rust compiler
Currently Working on: mrustc
tkausl
Posts: 17
Joined: Tue Jul 14, 2015 9:54 pm

Re: C invalidates my stack-variables

Post by tkausl »

thepowersgang wrote:By passing the registers struct by value, you tell the C compiler that's free to clobber it (it's allowed to by the calling convention).
Instead, push esp and accept a pointer, and this problem will go away.
Thanks, thats what i did now and it seems to work. Whats suprising me is that i get exactly one IRQ 0 which is the "Programmable Interrupt Timer Interrupt". I've never set it up nor do i get more than a single interrupt, whats this about?
alexfru
Member
Member
Posts: 1112
Joined: Tue Mar 04, 2014 5:27 am

Re: C invalidates my stack-variables

Post by alexfru »

tkausl wrote:

Code: Select all

	sti
	iret
There shouldn't be sti before iret. iret will re-enable interrupts if needed (because it will restore eflags.if when retrieving eflags from the stack). If you enable interrupts in an ISR, you risk overflowing the stack or running into concurrency issues.
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:

Re: C invalidates my stack-variables

Post by Combuster »

In other words, read the FAQ which has an entry on James Molloy, describing both these issues and a whole slew more. So, please be more careful about doing your research before posting.
"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 ]
cfenollosa
Posts: 2
Joined: Tue Aug 18, 2015 11:01 am

Re: C invalidates my stack-variables

Post by cfenollosa »

tkausl wrote:
thepowersgang wrote:By passing the registers struct by value, you tell the C compiler that's free to clobber it (it's allowed to by the calling convention).
Instead, push esp and accept a pointer, and this problem will go away.
Thanks, thats what i did now and it seems to work. Whats suprising me is that i get exactly one IRQ 0 which is the "Programmable Interrupt Timer Interrupt". I've never set it up nor do i get more than a single interrupt, whats this about?
Hi,

I'm facing the same problem but I'm a bit confused as to how to pass the struct registers_t as a pointer since I still haven't implemented a memory manager. Could you please share your implementation?

Thanks
User avatar
Roman
Member
Member
Posts: 568
Joined: Thu Mar 27, 2014 3:57 am
Location: Moscow, Russia
Contact:

Re: C invalidates my stack-variables

Post by Roman »

cfenollosa wrote:as a pointer since I still haven't implemented a memory manager
A pointer doesn't always point to a location in heap. I don't see any need for a memory manager here.
"If you don't fail at least 90 percent of the time, you're not aiming high enough."
- Alan Kay
User avatar
hgoel
Member
Member
Posts: 89
Joined: Sun Feb 09, 2014 7:11 pm
Libera.chat IRC: hgoel
Location: Within a meter of a computer

Re: C invalidates my stack-variables

Post by hgoel »

I'm not sure how providing direct code examples is looked at here but you can look at IDT_DefaultHandler here for an example of how to make the registers struct be passed as a pointer: https://github.com/himanshugoel2797/Ape ... ster/idt.c

Essentially you push esp onto the stack before calling the handler function and set the handler function to take a pointer to the registers struct
"If the truth is a cruel mistress, than a lie must be a nice girl"
Working on Cardinal
Find me at [url=irc://chat.freenode.net:6697/Cardinal-OS]#Cardinal-OS[/url] on freenode!
cfenollosa
Posts: 2
Joined: Tue Aug 18, 2015 11:01 am

Re: C invalidates my stack-variables

Post by cfenollosa »

hgoel0974 wrote:I'm not sure how providing direct code examples is looked at here but you can look at IDT_DefaultHandler here for an example of how to make the registers struct be passed as a pointer: https://github.com/himanshugoel2797/Ape ... ster/idt.c

Essentially you push esp onto the stack before calling the handler function and set the handler function to take a pointer to the registers struct
Huh, so that was it. For some reason I was obsessed with placing bytes in memory then passing that memory address to the C routine, but as Roman said, it can just point to the stack.

Thanks for your help!
kzinti
Member
Member
Posts: 898
Joined: Mon Feb 02, 2015 7:11 pm

Re: C invalidates my stack-variables

Post by kzinti »

cfenollosa wrote:
hgoel0974 wrote: Huh, so that was it. For some reason I was obsessed with placing bytes in memory then passing that memory address to the C routine, but as Roman said, it can just point to the stack.
The stack *is* in memory...
Post Reply