Page 1 of 1
invalid opcode
Posted: Thu Jul 10, 2003 8:37 pm
by Tyler Southwick
hi
i'm a newbie os programmer. i've mostly just copied and pasted code, but i think that i got a working gdt and idt. at least int0 works (divide by zero). but, when i try to add an interrupt for the timer, but i get an invalid opcode message (from my idt). i know that the timer isr is being called becuase i have it print a character to the screen each time its called, and the character is being printed. i don't know why i'm getting an invalid opcode message. please help
Re:invalid opcode
Posted: Fri Jul 11, 2003 3:00 am
by Carnac
What does the code of your interrupt handler look like?
Re:invalid opcode
Posted: Fri Jul 11, 2003 11:04 am
by tyler s
this is the isr handler:
Code: Select all
[extern _timer_isr]
[global _irq0]
_irq0:
pusha
push ds
push es
push fs
push gs
mov eax,0x10 ; Data segment
mov ds,eax
mov es,eax
cld
call _timer_isr ;
pop gs
pop fs
pop es
pop ds
popa
iret
and it calls timer_isr() from a c file:
Code: Select all
void timer_isr()
{
kprintf("d");
outportb(0x20, 0x20);
outportb(0xA0, 0x20);
}
i have it print a 'd' each time the isr is called to let me know if its being called. i then enable the timer irq with:
if i enable the irq, the 'd' is printed, but i also get an invalid opcode message. if it is never enabled, nothing happens.
Re:invalid opcode
Posted: Fri Jul 11, 2003 11:34 am
by slacker
i used to get an invalid opcode with my isr--first of all make sure you push/pop 32BIT registers and i also got the exception when i pushed/popped fs/gs registers or some reason
Re:invalid opcode
Posted: Fri Jul 11, 2003 10:15 pm
by Carnac
Well I'm not sure how this line assembles:
mov ds, eax
The assembler should throw a big tantrum about that, as ds is a 16bit register, and eax is a 32bit register.
Make sure that your stack isn't being clobbered and blowing up the return address on the stack.
Re:invalid opcode
Posted: Sat Jul 12, 2003 3:54 am
by Tim
No, that's fine. It has the same effect as MOV DS, AX but it saves one prefix byte.
Re:invalid opcode
Posted: Sat Jul 12, 2003 4:54 am
by Carnac
It must be some hacky NASM/MASM/whatever throwback then, coz opcode prefixes should have no effect on a segment register load.
Re:invalid opcode
Posted: Sat Jul 12, 2003 5:12 am
by Carnac
In fact, if the assembler was putting in opcode prefixes before a 'mov ds, ax', I'd probably be trading that assembler in for a better model.
I'd definitely be trading it in if
(a) It was putting in opcode prefixes before the segment load
(b) If it didn't throw up an error when trying to load a 32bit register into a 16bit segment register
Re:invalid opcode
Posted: Sat Jul 12, 2003 6:29 am
by Tim
In 32-bit code, an O16 prefix is required before any instruction that uses a 16-bit register. This includes MOV DS, AX. No prefix is required before MOV DS, EAX because EAX is a 32-bit register, and it's valid to assign a 32-bit register to a segment register (only the bottom 16 bits are used).
Re:invalid opcode
Posted: Sat Jul 12, 2003 6:35 am
by Carnac
I think the difference between:
mov ds, ax
and
mov ds, eax
Is simply the fact that the assembler has looked at the 'eax' and just assumed that the programmer meant 'ax', without throwing up a warning or error. If you assembled both of those lines of code in an assembler that actually parsed it, it would very most definitely generate exactly the same code. I very much doubt it would put in a prefix.
Most assemblers should really throw a tantrum about a mov ds, eax instruction.
Re:invalid opcode
Posted: Sat Jul 12, 2003 7:09 am
by Tim
Intel Volume 2 is the authority on this. According to the section on MOV (and I wish I could copy and paste this, but Craprobat Reader won't let me):
-- No O16 prefix is necessary in 32-bit mode
-- Some assemblers insert it anyway if you write "MOV DS, AX"
-- CPU treats this instruction as if it had no prefix, but there may be one clock overhead to decode the prefix
NASM apparently assembles "MOV DS, AX" and "MOV DS, EAX" the same way, without any prefix, although you can add an O16 manually if you want. I don't have MASM installed currently so I can't easily check that.
Re:invalid opcode
Posted: Sat Jul 12, 2003 7:22 am
by Curufir
Just as another avenue of investigation:
Let's say you switch to protected mode but fail to load FS and GS with decent selectors. Now you hit the interrupt and the value of FS/GS get pushed fine because it's just a value, but the pop is taking those pushed values and treating them as selectors. Unless they were initialised to something (Even if it's the null selector) then they're unlikely to contain a good reference into the GDT. So perhaps it's a problem with selector loading and the error is just not explaining what's going on clearly.
Just speculating of course, I've never had the problem, but then again I set everything to known values after a switch to pmode.
Re:invalid opcode
Posted: Sat Jul 12, 2003 9:07 am
by Carnac
You would assume that you'd get a GP fault (which, he possibly is, if his GP fault handler is screwy/not initialised properly) if you tried loading up an invalid FS/GS selector due to the POP FS/POP GS.
What does the GP Fault handler look like, and is its vector initialised correctly?