flat assembler
Message board for the users of flat assembler.

Index > OS Construction > GDT and IDT arithmetic

Author
Thread Post new topic Reply to topic
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 09 Dec 2006, 19:09
Hey, I have a question about GDT and IDT arithmetic (actually it can probably be considered a more generalized question than that), but when you subtract labels from one another in ASM, what's really happening? The example I will give you of this is for the GDT descriptor.

Code:
gdt_desc:
        dw gdt_end - gdt - 1
        dd gdt        
    


Also, I recall in RhynOS (My old OS... R.I.P.) That someone directed me to do this before I was to load the GDT Descriptor:

Code:
add dword [gdt_descriptor+2], 600h
    


What I don't understand about this is when you add 2 to the GDT Descriptor, how many units is it going up each time? 2 Bytes? 2 Words? 2 DWords?


Thanks for your time and patience.

-Rhyno


Last edited by rhyno_dagreat on 09 Dec 2006, 22:48; edited 2 times in total
Post 09 Dec 2006, 19:09
View user's profile Send private message Reply with quote
Mac2004



Joined: 15 Dec 2003
Posts: 314
Mac2004 09 Dec 2006, 19:31
Hi Rhyno!

If I understood your question properly the answer is this:

[gdt_descriptor+2] defines the start address where to add. In this case the start address is gdt_descriptor+2 bytes. The size of addition is determined by the prefix dword. So we're adding dword size number (32bit) at gdt_descriptor+2.

I hope this helps you!

regards,
Mac2004
Post 09 Dec 2006, 19:31
View user's profile Send private message Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 09 Dec 2006, 19:39
Thanks Mac! It does, but I still must wonder about the first question about subtracting the labels.
Post 09 Dec 2006, 19:39
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 09 Dec 2006, 20:28
The first word in GPTR is the size of the GDT, the dword after it is the address of the GDT.

Code:
        GDTR:
                .Size           dw (_GDT - GDT)
                .Address        dd GDT

        GDT:
                ; GDT entires here
        _GDT:
    


I honestly don't know why people subtract 1 as well - it always gives me triple fault...

add dword [gdt_descriptor+2], 600h is the same as add dword [GDTR.Address], 600h - this was probably the offset of your kernel.
Post 09 Dec 2006, 20:28
View user's profile Send private message Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 09 Dec 2006, 20:43
Yeah, it was. Thanks! But still, what is the subtraction subtracting? Memory addresses?
Post 09 Dec 2006, 20:43
View user's profile Send private message Reply with quote
cod3b453



Joined: 25 Aug 2004
Posts: 618
cod3b453 09 Dec 2006, 21:03
yes.

Basically, the memory addresses of the labels gdt and _gdt are calculated at compile time once everything else has been "filled in" and then (_gdt - gdt) is evaluated and put in as the value for size.[/code]
Post 09 Dec 2006, 21:03
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 09 Dec 2006, 21:54
rhyno_dagreat wrote:
but when you subtract labels from one another in ASM, what's really happening?

In NASM and FASM syntax the label represents an address (in FASM it can also have some data size attached, but it still can be used juat as an address), so when you substract labels, you substract addresses.

rhyno_dagreat wrote:
What I don't understand about this is when you add 2 to the GDT Descriptor, how many units is it going up each time? 2 Bytes? 2 Words? 2 DWords?

The addresses are alway byte-granular, so if you increment address by 1, you point to the next byte. Adding 2 moves you two bytes forward.


cod3b453 wrote:
I honestly don't know why people subtract 1 as well - it always gives me triple fault...


From the "Intel 80386 Programmer's Reference Manual" (year 1986), section 6.3.1.2:
Quote:
The limit field of descriptors for descriptor tables is used by the
processor to prevent programs from selecting a table entry outside the
descriptor table. The limit of a descriptor table identifies the last valid
byte of the last descriptor in the table. Since each descriptor is eight
bytes long, the limit value is N * 8 - 1 for a table that can contain up to
N descriptors.


...and from the more up-to-date "IA-32 Intel Architecture Software Developer’s Manual", volume 3, section 3.5:
Quote:
The limit value for the GDT is
expressed in bytes. As with segments, the limit value is added to the base address to get the
address of the last valid byte. A limit value of 0 results in exactly one valid byte. Because
segment descriptors are always 8 bytes long, the GDT limit should always be one less than an
integral multiple of eight (that is, 8N – 1).

I guess your triple fault must have been for some other reason.
Post 09 Dec 2006, 21:54
View user's profile Send private message Visit poster's website Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 09 Dec 2006, 22:47
Ah, this all makes sense now!

So say you have the following assembler code:

Code:
jmp Addr1

Addr1: ;Say this is at offset 0x0002 
    mov ax, bx 

Addr2: ;And this is at offset 0x0004
    mov bx, cx

Addr3:
    Addr2 - Addr1 ;Would be equivalent to 0x0004 - 0x0002 = 0x0002?
    ;Which would mean Addr3 points to the same offset as Addr1, right?
    
Post 09 Dec 2006, 22:47
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 09 Dec 2006, 23:19
Perhaps you did mean:
Code:
jmp Addr1

Addr1: ; 0x0002 
    mov ax, bx 

Addr2: ; 0x0004
    mov bx, cx

Addr3 = Addr2 - Addr1 ; equivalent to Addr3 = 0x0004 - 0x0002    
Post 09 Dec 2006, 23:19
View user's profile Send private message Visit poster's website Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 09 Dec 2006, 23:21
Oops, no, I meant:
Code:
jmp Addr1

Addr1: ;Say this is at offset 0x0002 
    mov ax, bx 

Addr2: ;And this is at offset 0x0004
    mov bx, cx

Addr3:
    db Addr2 - Addr1 ;Would be equivalent to 0x0004 - 0x0002 = 0x0002?
    ;Which would mean Addr3 points to the same offset as Addr1, right? 
    
Post 09 Dec 2006, 23:21
View user's profile Send private message Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8359
Location: Kraków, Poland
Tomasz Grysztar 09 Dec 2006, 23:32
Then you've got Addr1 = 0x0002 and Addr3 = 0x0006.
The byte at address 0x0006 (Addr3) holds the value 0x0002, so you might say that byte[Addr3]=Addr1 - did you mean this by saying "points to the same offset as"?
Post 09 Dec 2006, 23:32
View user's profile Send private message Visit poster's website Reply with quote
rhyno_dagreat



Joined: 31 Jul 2006
Posts: 487
Location: Maryland, Unol Daleithiau
rhyno_dagreat 10 Dec 2006, 00:30
Yeah, thanks Tomasz! But while we're on the subject of memory addressing and all, could you check out my 16 bit os thread? I show the code and the changes I've made to it, but it still doesn't work. Basically the second sector starts a new program.
Post 10 Dec 2006, 00:30
View user's profile Send private message Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >
Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.