segmentation fault

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
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: segmentation fault

Post by yemista »

stlw wrote:
yemista wrote:In that case, how do you load the idtr with a calculated linear offset that includes the base through ds? how can I make idtr 0x00100088 if I cant do it by lidt [ds:idt]?
Open Intel manual and read about LIDT instruction:

Loads the values in the source operand into the interrupt descriptor table register (IDTR). The source operand specifies a 6-byte memory location that contains the base address (a linear address) and the limit (size of table in bytes) of the interrupt descriptor table (IDT).

pseudocode is trivial:
IDTR(Limit) ← SRC[0:15];
IDTR(Base) ← SRC[16:47];

and you decide what do you put in your memory location addressed by [ds:idt].
put there correct linear address as manual requires :)

Stanislav
yea obviously, but the question is why isnt this code generating the correct address?

Code: Select all

_idt:
   %rep  51 
      make_idt_entry         ;(32+16+3) ; exceptions+interrupts+syscall
   %endrep
idt_end:

   
idtp:    dw    idt_end - _idt -1       ; IDT limit
   dd    _idt             ; address of IDT

lidt [idtp]
I also tried this with the same results

Code: Select all

lidt [ds:idtp]
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: segmentation fault

Post by Combuster »

Because you told it to. You told the assembler to assume the file is executed at virtual location 0.
Then you expect that it will magically see the IDT and fill in the correct linear address (which is what the IDTR is expected to contain).

Go back for once and check what numbers are wrong, and what needs to be done to fix those. If we have to go and spoon feed you all your bugfixes then it will get very annoying for us.
"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
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: segmentation fault

Post by yemista »

Yea but shouldnt ds do that for me?
User avatar
Firestryke31
Member
Member
Posts: 550
Joined: Sat Nov 29, 2008 1:07 pm
Location: Throw a dart at central Texas
Contact:

Re: segmentation fault

Post by Firestryke31 »

No. The IDTR does not use DS. It's already been said twice I believe (at least once by me). Only the LIDT instruction uses DS, and that's for the pointer to the structure that gets loaded to the IDTR.
Owner of Fawkes Software.
Wierd Al wrote: You think your Commodore 64 is really neato,
What kind of chip you got in there, a Dorito?
User avatar
yemista
Member
Member
Posts: 299
Joined: Fri Dec 26, 2008 12:31 pm
Location: Boston
Contact:

Re: segmentation fault

Post by yemista »

Look, Im not expecting people to fix everyone of my bugs and there is still something I dont get here. Here is the problem as I see it. I understand idtr does nto use ds to reference memory, and just contains a linear address. It only uses ds during the lidt instruction. So if idt is at 0x88, and ds is 0x00100000, lidt [idt] should effectivley load 0x00100088 into the idtr? Is that correct or am I mistaken in thinking that? However, for some reason, after the lidt instruction, idtr reads 0x00000088. I dont believe anything is wrong with my ds, because when I change it other memory reads fail. idt is located at offset 0x88, and everything seems to be right except for what is actually loaded into idtr. I double checked everything. I also looked at the intel instruction set and i dont think im using the instruction wrong.
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: segmentation fault

Post by Brendan »

Hi,
yemista wrote:Look, Im not expecting people to fix everyone of my bugs and there is still something I dont get here. Here is the problem as I see it. I understand idtr does nto use ds to reference memory, and just contains a linear address. It only uses ds during the lidt instruction. So if idt is at 0x88, and ds is 0x00100000, lidt [idt] should effectivley load 0x00100088 into the idtr? Is that correct or am I mistaken in thinking that?
That's correct (unless you're using a segment override prefix, like "lidt [gs:foo]").
yemista wrote:However, for some reason, after the lidt instruction, idtr reads 0x00000088.
The LIDT instruction loads the base and the limit of the IDT from the address you said. So, if you do:

Code: Select all

    lidt [foo]

foo:
    dd 0x12345678
    dw 256*8 - 1
Then, the IDTR will contain 0x12345678, the CPU will expect to find an IDT (and IDT entries) at 0x12345678, and the IDT limit will be enough for 256 IDT entries.

However, if you do:

Code: Select all

    lidt [foo]

foo:
    dd my_IDT
    dw 256*8 - 1
Then the IDTR will contain whatever the assembler thought "my_IDT" is. If your code is using DS = 0x00100000 and the assembler thinks that "my_IDT" is equal to 0x00000123, then the IDT might be at 0x00100123 but the IDTR will only be 0x00000123. To fix that you'd need to do something like:

Code: Select all

    lidt [foo]

foo:
    dd my_IDT + <whatever_the_code_segment's_base_address_is>
    dw 256*8 - 1

Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
Post Reply