Segment, Base Address, PM, ...

  • Follow


Sometime ago, I asked here about Segment Base Address. I was answered that in Flat Mode, segment base address is always zero and segment size is 
always ?2^32. It helped me to solve my problem but let me completely confused about how protected mode works. Few days ago, I found at
      http://spiff.tripnet.se/~iczelion/files/win32des.zip
a piece of code showing descriptors elements value where Base Address was NOT NULL. I think I see where I was confused :

In flat mode, the "Segment base address" and the "Segment Descriptor base address" are two different things.
If in flat mode, when Addressing memory, there are no segment register used in building the linear address but in the DESCRIPTORS, the segmentation 
still exists ... and it's rather confusing :).

In NASM the keyword SECTION can be used instead of SEGMENT ; I now know why :).
Talking about "Section Descriptor" would be less confusing ? (for guys like me :)

Am I right ? My guess is YES :)

Jacques

0
Reply Erdemal 12/11/2004 8:05:27 PM

On Sat, 11 Dec 2004 20:05:27 +0000 (UTC), Erdemal
<spamtrap@crayne.org> wrote in comp.lang.asm.x86:

> Sometime ago, I asked here about Segment Base Address. I was answered that in Flat Mode, segment base address is always zero and segment size is 
> always ?2^32. It helped me to solve my problem but let me completely confused about how protected mode works. Few days ago, I found at
>       http://spiff.tripnet.se/~iczelion/files/win32des.zip
> a piece of code showing descriptors elements value where Base Address was NOT NULL. I think I see where I was confused :
> 
> In flat mode, the "Segment base address" and the "Segment Descriptor base address" are two different things.
> If in flat mode, when Addressing memory, there are no segment register used in building the linear address but in the DESCRIPTORS, the segmentation 
> still exists ... and it's rather confusing :).

No, on 16 and 32 bit x86 processors, every memory access uses one of
the segment registers.  Always.  The logical address (example, mov
eax, [ebx + 2]) is always added to the segment register base, which in
this case would be the DS segment unless an override is used.  The
result of the addition of the logical address plus the segment base is
the linear address, which then might use the page tables to be
translated to a physical address.

> In NASM the keyword SECTION can be used instead of SEGMENT ; I now know why :).
> Talking about "Section Descriptor" would be less confusing ? (for guys like me :)
> 
> Am I right ? My guess is YES :)

If you mean is there any mode of operation of an x86 processor where
any memory reference does not use a segment base, then you are wrong
about any instructions that programmers can write.

There are memory references that do not involve segment registers,
such as accessing the page tables through CR3, but they are
automatically generated by the processor, not based on logical
addresses generated in program code.

> Jacques

Logical addresses are always added to a segment base to produce linear
addresses.  In SMM mode, V86 mode, real mode, and 16 and 32 bit
protected modes.

-- 
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++
http://www.contrib.andrew.cmu.edu/~ajo/docs/FAQ-acllc.html

0
Reply Jack 12/11/2004 8:37:49 PM


Erdemal  <spamtrap@crayne.org> wrote:
>
>Sometime ago, I asked here about Segment Base Address. I was answered 
>that in Flat Mode, segment base address is always zero and segment size is 
>always ?2^32. It helped me to solve my problem but let me completely 
>confused about how protected mode works. Few days ago, I found at
>      http://spiff.tripnet.se/~iczelion/files/win32des.zip
>a piece of code showing descriptors elements value where Base Address 
>was NOT NULL. I think I see where I was confused :

It is POSSIBLE to set the base address of a selector to a non-zero value in
protect mode.  The point others have made is that, in every modern 32-bit
operating system for the x86, that feature is not used.  The base address
is set to 0.

(* Nit-picky exception: Windows keeps thread-specific data in a small data
structure, and FS: points to the base of that structure.)
-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

0
Reply Tim 12/12/2004 4:55:25 AM

> protect mode.  The point others have made is that, in every modern 32-bit
> operating system for the x86, that feature is not used.  The base address
> is set to 0.
> (* Nit-picky exception: Windows keeps thread-specific data in a small data
> structure, and FS: points to the base of that structure.)
Nit-picky exception 2: for older applications (e.g. DOS, DPMI and 16-bit
Windows applications), base addresses are set as required for those 
applications.
However, this depends on the 'emulator'. Some (WoW, VMware, DOSEMU)
use the 80386 (compatible) hardware features (task descriptors, virtual 8086 
tasks)
to create a compatible environment for that application wich allows full 
speed
emulation of the application. Other (portable) emulators also emulate the 
CPU.
This is much slower, but not a big problem for many Windows applications as 
most
time is spent in system functions and idle state.

H 


0
Reply Herman 12/12/2004 10:07:23 AM

"Erdemal" <spamtrap@crayne.org> wrote in message 
news:41bac317$0$961$4d4efb8e@read.news.be.uu.net...
> Sometime ago, I asked here about Segment Base Address. I was answered that 
> in Flat Mode, segment base address is always zero and segment size is 
> always ?2^32. It helped me to solve my problem but let me completely 
> confused about how protected mode works. Few days ago, I found at
>      http://spiff.tripnet.se/~iczelion/files/win32des.zip
> a piece of code showing descriptors elements value where Base Address was 
> NOT NULL. I think I see where I was confused :

"Flat mode" is not strictly a mode of the CPU. It is a contract between the 
OS and applications that for any pointer p, [es:p], [cs:p], [ss:p], and 
[ds:p] all point to the same memory. In 16-bit mode C programs, you had to 
qualify pointers as being "near" or "far", and memory models were used to 
select a default for when you didn't specify. Far pointers had 2 additional 
bytes to hold the segment value. Flat mode means that all of your pointers 
are always near because all segments are equivalent. There are other 
complexities also such as near/far calls which flat mode completely does 
away with.

> In flat mode, the "Segment base address" and the "Segment Descriptor base 
> address" are two different things.
> If in flat mode, when Addressing memory, there are no segment register 
> used in building the linear address but in the DESCRIPTORS, the 
> segmentation still exists ... and it's rather confusing :).

Conceptually this is true. However, in x86, segmentation is applied to 
*every* memory access, unconditionally. To implement flat mode, all segment 
descriptors available to programs are set up so that the base is 0 and limit 
is 4GB. Since 0 is the identity element for addition, this effectively 
"turns off" the base address part of segmentation. The 4GB value in the 
segment limit "turns off" the range check because the computed pointer will 
always be smaller.

> In NASM the keyword SECTION can be used instead of SEGMENT ; I now know 
> why :).
> Talking about "Section Descriptor" would be less confusing ? (for guys 
> like me :)

A "section" in an executable no longer corresponds to a segment which is 
probably part of the motivation for the name change. My history is not clear 
enough to really comment on this, though.

-Matt 

0
Reply Matt 12/13/2004 12:10:53 AM

Matt wrote :

Thanks to all for your replies.

> 
> "Flat mode" is not strictly a mode of the CPU. It is a contract between the 
> OS and applications that for any pointer p, [es:p], [cs:p], [ss:p], and 
> [ds:p] all point to the same memory. In 16-bit mode C programs, you had to 
> qualify pointers as being "near" or "far", and memory models were used to 
> select a default for when you didn't specify. Far pointers had 2 additional 
> bytes to hold the segment value. Flat mode means that all of your pointers 
> are always near because all segments are equivalent. There are other 
> complexities also such as near/far calls which flat mode completely does 
> away with.
> 

Yes !

> 
>>In flat mode, the "Segment base address" and the "Segment Descriptor base 
>>address" are two different things.
>>If in flat mode, when Addressing memory, there are no segment register 
>>used in building the linear address but in the DESCRIPTORS, the 
>>segmentation still exists ... and it's rather confusing :).
> 

OK : segment registers CS,DS,ES,... are still used to build the ?linear address but the value used is 0

> 
> Conceptually this is true. However, in x86, segmentation is applied to 
> *every* memory access, unconditionally. To implement flat mode, all segment 
> descriptors available to programs are set up so that the base is 0 and limit 
> is 4GB. Since 0 is the identity element for addition, this effectively 
> "turns off" the base address part of segmentation. The 4GB value in the 
> segment limit "turns off" the range check because the computed pointer will 
> always be smaller.
> 

This is where you send me back to confusion !

When I run the following software http://spiff.tripnet.se/~iczelion/files/win32des.zip on my Windows computer, it displays the contents of the GDT, 
LDT and descriptors. And there, in the segment descriptors, the base address is never 0, nor the limit 4GB.

In Example :
table   selector   base_address  limit   true_limit    my comments
---------------------------------------------------------------------------------------------
GDT         0043       00000400  002FF     000002FF    I have a guess on what that segment is
GDT         011B       8246D000  00FFF     00000FFF    Randomly choosen
GDT         0353       82E17000  00FFF     00000FFF    The last one in GDT
LDT         0018       80004000  0BFFF     0000BFFF    "OUR LDT" application button selection
LDT         374F       80DCA700  0109F     0000109F    Randomly choosen
LDT         6237       87E6DB20  00A1F     00000A1F    The last one in LDT
---------------------------------------------------------------------------------------------

So it seems that the segment descriptor base address found in the descriptors and the segment base address of a piece of code are two different things 
and have different values.

The problem for me was(is?) that if all segment descriptors base address are Zero and if all segment descriptors limit are 4GB, how can the processor 
make a difference between two different segment of protected code.

Rewriting the last two paragraphs using the word "section" instead of "segment", when it's about a piece of protected code and using the 
words"segment" when it's about a segment register of the CPU, makes it a bit easier to understand.

======= 2 paragraphs rewritten =======
So it seems that the section descriptor base address found in the descriptors and the segment base address of a piece of code are two different things 
and have different values.

The problem for me was(is?) that if all section descriptors base address are Zero and if all section descriptors limit are 4GB, how can the processor 
make a difference between two different section of protected code.
======================================

Am I stubborn ? I would like to sort that out once for all :)

Jacques

0
Reply Erdemal 12/13/2004 11:25:56 PM

Erdemal  <spamtrap@crayne.org> wrote:
>
>This is where you send me back to confusion !
>
>When I run the following software http://spiff.tripnet.se/~iczelion/files/win32des.zip on my Windows computer, it displays the contents of the GDT, 
>LDT and descriptors. And there, in the segment descriptors, the base address is never 0, nor the limit 4GB.
>
>In Example :
>table   selector   base_address  limit   true_limit    my comments
>---------------------------------------------------------------------------------------------
>GDT         0043       00000400  002FF     000002FF    I have a guess on what that segment is
>GDT         011B       8246D000  00FFF     00000FFF    Randomly choosen
>GDT         0353       82E17000  00FFF     00000FFF    The last one in GDT
>LDT         0018       80004000  0BFFF     0000BFFF    "OUR LDT" application button selection
>LDT         374F       80DCA700  0109F     0000109F    Randomly choosen
>LDT         6237       87E6DB20  00A1F     00000A1F    The last one in LDT
>---------------------------------------------------------------------------------------------

Looks to me like that must be a 16-bit application, because the segments
used by 32-bit apps are not even included.  The 16-bit world uses
segmentation to a great degree.  The 32-bit world does not.

Here is the GDT on Windows XP Service Pack 2, as displayed by the excellent
tools included in the book "Windows 2000 Internals":

// w2k_mem.exe
// SBS Windows 2000 Memory Spy V1.00
// 08-27-2000 Sven B. Schreiber
// sbs@orgon.com

Loading "SBS Windows 2000 Spy Device" (w2k_spy) ...
Driver: "C:\Apps\W2KInternals\w2k_spy.sys"
Opening "\\.\w2k_spy" ...

SBS Windows 2000 Spy Device V1.00 ready

GDT information:
----------------

001 : Sel = 0008, Base = 00000000, Limit = FFFFFFFF, DPL0, Type = CODE -ra
002 : Sel = 0010, Base = 00000000, Limit = FFFFFFFF, DPL0, Type = DATA -wa
003 : Sel = 0018, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = CODE -ra
004 : Sel = 0020, Base = 00000000, Limit = FFFFFFFF, DPL3, Type = DATA -wa
005 : Sel = 0028, Base = 80042000, Limit = 000020AB, DPL0, Type = TSS32 b
006 : Sel = 0030, Base = FFDFF000, Limit = 00001FFF, DPL0, Type = DATA -wa
007 : Sel = 0038, Base = 7FFDD000, Limit = 00000FFF, DPL3, Type = DATA -wa
008 : Sel = 0040, Base = 00000400, Limit = 0000FFFF, DPL3, Type = DATA -w-
00A : Sel = 0050, Base = 80550B80, Limit = 00000068, DPL0, Type = TSS32 a
00B : Sel = 0058, Base = 80550BE8, Limit = 00000068, DPL0, Type = TSS32 a
00C : Sel = 0060, Base = 00022F30, Limit = 0000FFFF, DPL0, Type = DATA -wa
00D : Sel = 0068, Base = 000B8000, Limit = 00003FFF, DPL0, Type = DATA -w-
00E : Sel = 0070, Base = FFFF7000, Limit = 000003FF, DPL0, Type = DATA -w-
00F : Sel = 0078, Base = 80400000, Limit = 0000FFFF, DPL0, Type = CODE -r-
010 : Sel = 0080, Base = 80400000, Limit = 0000FFFF, DPL0, Type = DATA -w-
011 : Sel = 0088, Base = 00000000, Limit = 00000000, DPL0, Type = DATA -w-
014 : Sel = 00A0, Base = 867EA940, Limit = 00000068, DPL0, Type = TSS32 a
01C : Sel = 00E0, Base = F78BF000, Limit = 0000FFFF, DPL0, Type = CODE cra
01D : Sel = 00E8, Base = 00000000, Limit = 0000FFFF, DPL0, Type = DATA -w-
01E : Sel = 00F0, Base = 804D8B28, Limit = 0003CF7B, DPL0, Type = CODE ---
01F : Sel = 00F8, Base = 00000000, Limit = 0000FFFF, DPL0, Type = DATA -w-
020 : Sel = 0100, Base = F762C040, Limit = 0000FFFF, DPL0, Type = DATA -wa
021 : Sel = 0108, Base = F762C040, Limit = 0000FFFF, DPL0, Type = DATA -wa
022 : Sel = 0110, Base = F762C040, Limit = 0000FFFF, DPL0, Type = DATA -wa

Closing the spy device ...


8 and 10 are the kernel-mode CS and DS/ES/SS.  18 and 20 are the user-mode
CS and DS/ES/SS, although the actual selectors are 1B and 23.  As you can
see, all four start at 0 and run throughout memory.  One of the others is
the LDT, one points to the page tables, one points to the thread-specific
area.

>So it seems that the segment descriptor base address found in the 
>descriptors and the segment base address of a piece of code are two different 
>things and have different values.

No, they aren't.  You're just using the wrong tool.

>The problem for me was(is?) that if all segment descriptors base address 
>are Zero and if all segment descriptors limit are 4GB, how can the processor 
>make a difference between two different segment of protected code.

No one said that ALL of the segment descriptors ave a base address of 0.
However, to answer your question, it doesn't.  All of memory is available
as either code or data at all times.  All of the code and data sections for
the DLLs in any given process are all simultaneously accessible.
-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

0
Reply Tim 12/14/2004 6:24:18 AM

Matt wrote:
> 
> "Erdemal" <spamtrap@crayne.org> wrote in message
> > In NASM the keyword SECTION can be used instead of SEGMENT ; I now know
> > why :).
> > Talking about "Section Descriptor" would be less confusing ? (for guys
> > like me :)
> 
> A "section" in an executable no longer corresponds to a segment which is
> probably part of the motivation for the name change. My history is not clear
> enough to really comment on this, though.

Nasm has had "segment" and "section" as aliases for each other since
0.91, anyway. I used to call 'em all "segment", but came to realize that
it only makes sense to call 'em that in 16-bit MZ executables. In that
case, "segment data" really *is* in a different segment than "segment
code", and you must take steps to assure that a segment *register*
points to your "data segment" before you can access data. (and you need
a "segment stack stack" - the first "stack" is just a name, and could be
anything, the second "stack" is a "property" of the segment, and is
required if dos is going to load ss. The example in the manual shows ss
being loaded "by hand" - "mov ax, stack"/"mov ss, ax". etc. - I don't
know why, dos *does* this for you.)

In a .com file, you can have "segment .text", "segment .data", and
"segment .bss"... Nasm moves ".data" after ".text" and ".bss" after
that, but they're all in the same segment. When dos loads a .com file,
it chooses what segment to load the file into, and sets all segment
registers to point to that segment. In this case, it's probably less
confusing to call 'em "section .text", etc. A 32-bit app, for most OSen
(Wolfgang's KeySys may be an exception), can be considered "like a .com
file, only bigger"...

In a 32-bit app, cs and ds won't have the same value - they point to
different descriptors (one with bits set for "code" and one with "data"
- duh), but the base should be 0, and the limit 0FFFFFFFFh for both
(except fs in Windows). The "base" of the descriptor table - where it
lives in memory - will be non-zero... I don't know what Iczelion is
showing Erdemal that's causing the confusion, but I agree that "section"
is a less confusing name to use :)

Best,
Frank

P.S. "stubborn"? You'd better be! ("persistant" might sound nicer, but
you'll never get anywhere if you give up easy! :)

0
Reply Frank 12/16/2004 10:16:56 AM

Let's be fair with Iczelion : I BUILD that table picking randomly some segments, just to show that in some segment descriptors, base address and 
limits were not always 0 and 2^32 !

 >I a previous message, Erdemal wrote :
 >In Example :
 >table   selector   base_address  limit   true_limit    my comments
 >---------------------------------------------------------------------------------------------
 >GDT         0043       00000400  002FF     000002FF    I have a guess on what that segment is
 >GDT         011B       8246D000  00FFF     00000FFF    Randomly choosen
 >GDT         0353       82E17000  00FFF     00000FFF    The last one in

Let's be fair with Iczelion ! *I BUILD* that table picking randomly some segments descriptors, just to show that in some segments, descriptors base 
address is not always zero and limits 2^32 !

Frank wrote :
> 
> In a 32-bit app, cs and ds won't have the same value - they point to
> different descriptors (one with bits set for "code" and one with "data"
> - duh), but the base should be 0, and the limit 0FFFFFFFFh for both
> (except fs in Windows). The "base" of the descriptor table - where it

In fact it's all about "words" and precise language : "the base of the descriptor table" is ambiguous, this is the linear address of the first byte of 
the descriptor table (the thing you get using LGDT ... IIRC). You probably meant, the base address that can be found in the descriptor of a segment :)
And you do much better than me on that point.

> lives in memory - will be non-zero... I don't know what Iczelion is
> showing Erdemal that's causing the confusion, but I agree that "section"
> is a less confusing name to use :)
> 

I would like to get your reactions on this :
In PM, the segment descriptor table values are only used to "protect" pieces of code and are never used to build addresses to read, write or run code ?
In PM, how would you proceed to build a segment with a base address differen of 0, as done in 16 bit  cs:ax or ds:ax ?

Thanks all for your replies.

Jacques

0
Reply Erdemal 12/16/2004 6:28:04 PM

8 Replies
217 Views

(page loaded in 0.098 seconds)

Similiar Articles:













7/28/2012 10:03:35 AM


Reply: