GCC ruins stack
Posted: Tue Feb 07, 2012 6:40 pm
I'm trying to compile my kernel, and all worked fine, until I turned on optimization to -O3.
The relevant code is as follows (A lot has been removed to locate the error, so it's not the actual code):
And outportb:
However, this gets compiled to the following:
I've traced the error back to the lines with the question marks. Those shouldn't be there, and I'm not sure how they ever came to be.
It seems like it comes from the outportb(0x20, 0x20) instruction. However, why does this function overwrite the parameters, even though the calling function may still actually use them (one of them happens to be the segment register value, causing a crash)?
I guess I have to specify to GCC that I don't want it to wreck the parameters. How do I do that?
PS: This function is only called from assembly language.
The relevant code is as follows (A lot has been removed to locate the error, so it's not the actual code):
Code: Select all
void outportb(uint16_t port, uint8_t value);
void isr_handler(isr_argument_t regs)
{
if(__LIKELY(regs.int_nr >= IRQ0 && regs.int_nr <= IRQ15)) {
if(regs.int_nr >= IRQ7) {
outportb(0xA0, 0x20);
}
outportb(0x20, 0x20);
}
}
Code: Select all
outportb:
mov dx, word [esp+4] ; dx = port
mov al, byte [esp+8] ; al = value
out dx, al
ret
Code: Select all
push %ebp
mov %esp,%ebp
sub $0x18,%esp
mov 0x2c(%ebp),%eax
lea -0x20(%eax),%edx
cmp $0xf,%edx
ja c0101926 <isr_handler+0x46>
cmp $0x26,%eax
ja c0101910 <isr_handler+0x30>
movl $0x20,0xc(%ebp) ; ?????????????????????
movl $0x20,0x8(%ebp) ; ?????????????????????
leave
jmp c0103100 <outportb>
It seems like it comes from the outportb(0x20, 0x20) instruction. However, why does this function overwrite the parameters, even though the calling function may still actually use them (one of them happens to be the segment register value, causing a crash)?
I guess I have to specify to GCC that I don't want it to wreck the parameters. How do I do that?
PS: This function is only called from assembly language.