Question on Assembly?

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.
Post Reply
amirsadig

Question on Assembly?

Post by amirsadig »

could someone describe me the following code, which define gdt describtor :
I have put some question on this code.
######################
gdt: // is that a struct or function or ...... !!!!
; NULL descriptor
   dw 0      ; limit 15:0
   dw 0      ; base 15:0
   db 0      ; base 23:16
   db 0      ; type
   db 0      ; limit 19:16, flags
   db 0      ; base 31:24

; unused descriptor
   dw 0
   dw 0
   db 0
   db 0
   db 0
   db 0

LINEAR_DATA_SEL   equ   $-gdt // what that meaning ?
   dw 0FFFFh
   dw 0
   db 0
   db 92h      ; present, ring 0, data, expand-up, writable
   db 0CFh      ; page-granular (4 gig limit), 32-bit
   db 0

LINEAR_CODE_SEL   equ   $-gdt
   dw 0FFFFh
   dw 0
   db 0
   db 9Ah      ; present,ring 0,code,non-conforming,readable
   db 0CFh      ; page-granular (4 gig limit), 32-bit
   db 0
gdt_end:

gdt_ptr:
   dw gdt_end - gdt - 1
   dd gdt


elsewhere in the source come this code

jmp LINEAR_CODE_SEL:sbat // which value CS has ?

#######

could I access this describtor from C source and how?
Peter_Vigren

Re:Question on Assembly?

Post by Peter_Vigren »

amirsadig wrote: LINEAR_DATA_SEL???equ???$-gdt // what that meaning ?
"LINEAR_DATA_SEL equ $-gdt" means that whereever you use the constant (predefined, not changable) LINEAR_DATA_SEL (for example in Mov Eax,LINEAR_DATA_SEL), the compiler will replace that "label" with a number. This number is the adress that the "label" LINEAR_DATA_SEL is located _minus_ the adress where the GDT (see above) begun. So LINEAR_DATA_SEL will be replaced with the pointer into the GDT where it is described.
amirsadig wrote: jmp LINEAR_CODE_SEL:sbat // which value CS has ?
From what I can tell, that selector has a base of 0 (right me if I'm wrong) and then CS should contain 0...
amirsadig wrote: could I access this describtor from C source and how?
I don't know so I let the C-persons :-) here answer you on that one...
pete.piper

Re:Question on Assembly?

Post by pete.piper »

GDT stands for Global Descriptor Table. The GDT is a data structure used in 386+ processor's protected mode. It holds eight-byte descriptor entries. These descriptors can then be referred to with segment selectors and map a logical address (e.g., 0x10:0x300) to a linear address (e.g., 0x5000). The 0x5000 may or may not be a physical address depending on whether you use paging. Note that there are other types of descriptors like call gates for use by... well... CALLs. Check out the Intel Developer Manuals for in depth descriptions.

In the code you supplied, what follows after "gdt:" is the first eight-byte NULL descriptor. This first descriptor should always be NULL. Remember initializing your C pointers to NULL or 0? This is why you could safely do it.

LINEAR_DATA_SEL: is a data descriptor that points to the base address 0. The next descriptor is nearly the same except it is a code descriptor. One of the aspects of a descriptor is that you can define whether it can be executable (code) or writable (data). If you wanted to create a self-modifying program, you'd need a data and code descriptor that pointed to the same address range.

The "gdt_ptr:" code is used by the L[oad]GDT instruction to load the address of your GDT table (what all the previous code comprises) into the GDTR[egister].

> jmp LINEAR_CODE_SEL:sbat // which value CS has ?

CS will be loaded with the code selector that was previouly defined (base address 0). Thus, the linear address would simply be "sbat."

> could I access this describtor from C source and how?

This type of thing is assembler/compiler-dependent. You can usually count on a C compiler to prefix variables in object code with an underscore, though. You'll also need to use extern and global-like keywords in your C and assembly code.

I just gave you a brief introduction, here. You have a lot of reading ahead of you <smile>. I'd suggest the NASM documentation (http://sourceforge.net/projects/nasm/) and the Intel Developer Manuals (http://developer.intel.com).

Pete
anubis

Re:Question on Assembly?

Post by anubis »

The gdt table has been described by the code and its just simple data allocation.

q1. why LINEAR_DATA_SEL equ $-gdt?

->now if we want to point to the LINEAR_DATA segment than we have to know its offset in the gdt table. So we do this to know the segment descriptor's offset in GDT.

q2. jmp LINEAR_CODE_SEL:sbat ?

-->in simple real modethe segment address goes into CS but in Protected mode the selector of the segment goes into CS.

-->in GDT
Null selector =0000h
unused selector=0008h
linear_data_sel =0010h
linear_code_sel =0018h

--> only the top 13 bits of the above selectors are loaded in index field of CS

-->thus due to jmp CS selector <bit15-3>=11(top 13 bits of linear_code_sel)
<bit2-0>=00(no ldt,rpl=0)
thus we load 0x18 in CS(0000 0000 0001 1000)

-->the required descriptor information is then queried and the subsequent segment described by the descriptor is loaded and cpu jumps to the offset :sbat in the segment.

-->one way i know of accessing segments in C is using inline assembly.
:D ;D ::)
amirsadig

Re:Question on Assembly?

Post by amirsadig »

thank you for your reply and your details.

So I have understand that GDT must be define at the beginning of the kernel initialization, but could I change it or add new entry in table at run time, for exambles when I try to load module.

I have read also in Intel Developer Manual that there is also LDT for users application, should I also define it at boot time or can I define it in run time.

there is Gate Descriptor which let the user Application to call Kernel Service, that Theaory which I know but I don't know how users application could called that gate, which they did not know his selector.

again, thank you for your help.
Peter_Vigren

Re:Question on Assembly?

Post by Peter_Vigren »

The GDT should be loaded before entering Protected Mode and can be reloaded at runtime by setting up a new GDT and then load it. The LDT is optional and can be loaded at any time (after you have entered protected mode).
anubis

Re:Question on Assembly?

Post by anubis »

--> It is possible to have a dummy GDT just to go into protected mode, then reinitialize the GDT again in protected mode. You can see that as an example in linux0.0.1 code.

-->LDT can be defined after switching to PM. Its not necessary to define it at boot time.

-->Gate descriptors :-To say in brief its just a way that low privelege job like applications can access high privelege jobs like hardware.
There are 4 kinds of gate descriptors
1.Call
2.Trap
3.Interrupt
4.Task.

For example you are calling a system service via a call instuction its just like a usual call but this "call" has strict type checking, has an entry point for the procedure and a privelege level of the entry point. Only after a successful privelege level checking the call is executed. More about other gate descriptors can be found in the INTEL 386 Manual.

;D ;)
anubis

Re:Question on Assembly?

Post by anubis »

Peter_Vigren wrote: From what I can tell, that selector has a base of 0 (right me if I'm wrong) and then CS should contain 0...
I think if CS was in real mode it would contain the base address. But as we are in Protected Mode so CS would contain the selector ie 0018h and the descriptor would be loaded invisibly. ::) ;D :D
crazybuddha

Re:Question on Assembly?

Post by crazybuddha »

anubis wrote:
Peter_Vigren wrote: From what I can tell, that selector has a base of 0 (right me if I'm wrong) and then CS should contain 0...
I think if CS was in real mode it would contain the base address. But as we are in Protected Mode so CS would contain the selector ie 0018h and the descriptor would be loaded invisibly.

which is also what "LINEAR_DATA_SEL equ $-gdt " comes out to be in this case.
Post Reply