Interrupt Error Code and the Stack

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
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Interrupt Error Code and the Stack

Post by mark3094 »

I've been looking at Brans Kernel Development Tutorial (http://www.osdever.net/bkerndev/Docs/isrs.htm), and for the dummy error code, a BYTE is being pushed:

Code: Select all

_isr1:
    cli
    push byte 0
    push byte 1
    jmp isr_common_stub
I was looking in the Intel Manual 3A, section 6.13, and it appears that the error code is 32 bits, not 8.

In this case, why push a byte, not a DWORD?
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: Interrupt Error Code and the Stack

Post by Combuster »

Because it only requires a byte to push more than one. There is no such thing as adding one byte to the stack with that opcode, it's always two/four/eight depending on operating 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
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: Interrupt Error Code and the Stack

Post by mark3094 »

ah... I see...

Makes perfect sense now


Thankyou for you insight
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: Interrupt Error Code and the Stack

Post by Nessphoro »

But I recommend to change that to push dword, because later you might have some problems.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Interrupt Error Code and the Stack

Post by Gigasoft »

I'm glad I stopped using NASM. I've been using MASM for a while, then switched over to JWASM. It saves a lot of typing, "push byte" being an example. However, this seems like it was written a very long time ago, and since then the -Ox option has been introduced in NASM, which takes care of "push byte ..." and "add dword [...],byte ..." for you.
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: Interrupt Error Code and the Stack

Post by mark3094 »

Thankyou for your help. I'll look at changing those BYTEs to DWORDs.

Would passing control to a C function like this be suitable?:

Code: Select all

void isr(unsigned char isr, unsigned int err) {
/* Code in here */
}
I think I saw somewhere that using pointers was good (but I can't find it now, so I can't be sure what they were doing)

...
since then the -Ox option has been introduced in NASM, which takes care of "push byte ..." and "add dword [...],byte ..."
I had a look at NASMs -Ox option (http://www.nasm.us/doc/nasmdoc2.html#section-2.1.22), but I don't see how it relates to PUSH with BYTE, DWORD, etc...
Was it just a problem with older versions of NASM that has since been fixed?
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: Interrupt Error Code and the Stack

Post by mark3094 »

berkus wrote:Which problems exactly?
I did find that when I was pushing larger numbers for higher interrupts (eg, > 128), NASM didn't like using BYTE.
Not surprising really. Not really a big problem though.
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: Interrupt Error Code and the Stack

Post by mark3094 »

I have another question...

I have tried to fill the IDT with empty ISRs, the same as shown earlier in this thread.

I can add in the 31 descriptors, and then use inline assembly to initiate one of the interrupts, say int 31.
The interrupt handler prints '31' to the screen as it should.

If I add a lot more empty ISRs, it will eventually get to a point where it will stop working.
For example, if I add 213 descriptors, then using inline assembly to initiate int 31, nothing will happen.
This is odd, as I'm not even trying to use interrupt 213, but it's still causing problems.

Could it be a problem where the table is too big or something? If I miss a few earlier ISR's, interrupt 213 works fine...

Code to add descriptors:

Code: Select all

void idt_entries(uword i, udword base, uword selector, ubyte flags) {
	idt[i].lowoffset = base & 0xFFFF;
	idt[i].selector = selector;
	idt[i].reserved = 0;
	idt[i].flags = flags;
	idt[i].highoffset = (base >> 16) & 0xFFFF;
}
Adding descriptors to the IDT:

Code: Select all

	idtr.limit = (sizeof((udword)idt) * IDTDESCRIPTORS) - 1;
	idtr.base = (udword)&idt;

	idt_entries (0, (udword)isr0, 0x08, 0x8e);
	idt_entries (1, (udword)isr1, 0x08, 0x8e);
	idt_entries (2, (udword)isr2, 0x08, 0x8e);
        ...
Sample ISR:

Code: Select all

_isr213:
	CLI
	PUSH	BYTE 0
	PUSH	DWORD 213
	JMP	isrhandler

isrhandler:
	MOV	EAX, _isr
	CALL	EAX
	ADD	ESP, 8
	IRET
    
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: Interrupt Error Code and the Stack

Post by Combuster »

Your ISRs don't preserve registers.
"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
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: Interrupt Error Code and the Stack

Post by Nessphoro »

NASM 2.09, if you pass a a value larger than 128 to "push byte" it will overflow the signed boundary - and it becomes 0xFFFFFF7F- when viewing the interrupt number in the ISR.
Gigasoft
Member
Member
Posts: 856
Joined: Sat Nov 21, 2009 5:11 pm

Re: Interrupt Error Code and the Stack

Post by Gigasoft »

Just use the damn -Ox option, and save yourself the trouble of typing "byte" or "dword" every time.

Or better yet, get a decent assembler, such as JWASM.
User avatar
mark3094
Member
Member
Posts: 164
Joined: Mon Feb 14, 2011 10:32 pm
Location: Australia
Contact:

Re: Interrupt Error Code and the Stack

Post by mark3094 »

Combuster wrote:Your ISRs don't preserve registers.
would a simple pusha and popa be suitable to preserve registers?

eg:

Code: Select all

isrhandler:
   PUSHA
   MOV   EAX, _isr
   CALL   EAX
   POPA
   ADD   ESP, 8
   IRET
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: Interrupt Error Code and the Stack

Post by Nessphoro »

test.asm:4: warning: signed byte value exceeds bounds
test.asm:5: warning: signed byte value exceeds bounds

Yes, but now if you printf that value on interrupt - you'll get a very funny value.
User avatar
Owen
Member
Member
Posts: 1700
Joined: Fri Jun 13, 2008 3:21 pm
Location: Cambridge, United Kingdom
Contact:

Re: Interrupt Error Code and the Stack

Post by Owen »

I believe it is sign extended - so it should be correct as long as you only read the lower byte (and the assembler is sane)
User avatar
Nessphoro
Member
Member
Posts: 308
Joined: Sat Apr 30, 2011 12:50 am

Re: Interrupt Error Code and the Stack

Post by Nessphoro »

Just test it via real code guys.

You'll see.

Since the value is over the sign limit it will be negative, so the unsigned int (byte IS extended to dword) for that will have 0xFFFFFF80 stored in it (if 0x80 was pushed), which proves that 0x80!=0xFFFFFF80, which in fact will trash your ISR at the part where you chose what to do with that interrupt (IRQ,Syscall,etc)
Post Reply