CS, DS, and SS Segments Together?

  • Follow


    I understand that 16 Bits use far pointer when CS, DS, and SS segments
are limited to 64KB.  Someone mentioned that CS, DS, and SS segments can be
combined into one single segment that uses near pointer.  I believe that it
means to be tiny model for *.COM under MS-DOS only.  I think that CS, DS,
and SS segments are NEVER COMBINED together.  It is always that CS segment
is as the first paragraph, SS segment is as the second paragraph, and SS
segment is as the third paragraph.  Lets say, CS segment has 20KB, SS
segment has 1KB, and DS segment has 4KB.  The total single segment equals to
25KB.
    It is the same example for FLAT model that uses 32 Bits so CS, SS, and
DS segments are 4GB.  I suspect that CS segment uses 100MB, SS segment uses
1MB, and DS segment uses 1GB.  The total single segment is 1.101GB.  Do you
realize that word concept, "Combine CS, SS, and DS segments into one single
segment"?  It is not proper quote, but it is like first, second, and third
paragraph so they use NEAR pointer to point one of three paragraph.  Does it
make sense?
    It is not possible to allocate three segments of 4GB.  Lets say 12GB
total -- one 4GB for CS segment, one 4GB for SS segment, and one 4GB for DS
segment using FAR pointer that supports 32 Bits.  No such beyond FLAT model
uses FAR pointer.  It might be ideal for huge database, but Windows XP can
only limit 2GB for data and another 2GB for kernel and OS commands.
    Can you tell how HeapAlloc function by Windows XP allocate memory?  Do
you think that Windows XP allocates free memory before it begins to create
DS segment so it can point to DS segment?
    Suppose -- Pentium III & IV supports 64GB memory, but 4GB memory must be
swapped at all times.  DS segment has only 16 bits.  How can I point DS
segment to between 20 Bits and 36 Bits linear address?  Lets say, DS is
D000H times 10H that equals to D0000H.  It may be between 0KB and 1MB, but
how can it be done beyond 1MB.  It might sound like D000 times 10000H that
equals to D0000000 for 4GB.
    Please explain everything you can, but I am sure that Matt Taylor will
answer that question.  Matt Taylor, do you have great knowledge of Intel CPU
and how it works?  How long have you been experiencing with this? -- 
Curious --  Thanks...


-- 
Bryan Parkoff


0
Reply Bryan 10/24/2003 3:42:54 AM

Bryan Parkoff wrote:

> ...  DS segment has only 16 bits.  How can I point DS
> segment to between 20 Bits and 36 Bits linear address?  Lets say, DS is
> D000H times 10H that equals to D0000H.  It may be between 0KB and 1MB, but
> how can it be done beyond 1MB.  It might sound like D000 times 10000H that
> equals to D0000000 for 4GB.

In protected mode, the value in segment registers is used as an index 
into a descriptor table (containing "base" and "limit", among other 
things), not multiplied by 16 like in real mode...

Best,
Frank




0
Reply Frank 10/24/2003 8:53:09 PM


Hello!

Bryan Parkoff <nospam@nospam.com> wrote:

>     I understand that 16 Bits use far pointer when CS, DS, and SS
> segments are limited to 64KB.  Someone mentioned that CS, DS, and SS
> segments can be combined into one single segment that uses near
> pointer.  I believe that it means to be tiny model for *.COM under
> MS-DOS only.  I think that CS, DS, and SS segments are NEVER COMBINED
> together.

Why not? It obviously depends on the meaning of "combined".

>            It is always that CS segment is as the first paragraph, SS
> segment is as the second paragraph, and SS segment is as the third
> paragraph.  Lets say, CS segment has 20KB, SS segment has 1KB, and DS
> segment has 4KB.  The total single segment equals to 25KB.

You mean (assuming SS segment is 4 kB large):

     60kB   uuuu
     ...
     28kB   uuuu
DS-> 24kB   dddd
SS-> 20kB   ssss
     16kB   cccc
     12kB   cccc
      8kB   cccc
      4kB   cccc
CS->  0kB   cccc

(c = Code, s = Stack, d = Data)

Suppose you want to "combine" all three segments in such a way that
you'll be able to address them by using only *one* segment register.
As you see, you can do it: Use CS as your base, and you will be able
to address stack and data relative to it, e.g.

  SS:0000+x == CS:4400+x
  DS:0000+x == CS:4800+x


>     It is the same example for FLAT model that uses 32 Bits so CS,
> SS, and DS segments are 4GB.  I suspect that CS segment uses 100MB,
> SS segment uses 1MB, and DS segment uses 1GB.  The total single
> segment is 1.101GB.  Do you realize that word concept, "Combine CS,
> SS, and DS segments into one single segment"?  It is not proper
> quote, but it is like first, second, and third paragraph so they use
> NEAR pointer to point one of three paragraph.  Does it make sense?

You can have a single 4GB segment and yet addressing all code, stack,
and data. See above. You have to adjust the offsets, of course, because
the absolute address will change. But you say FLAT model, so all segment
selectors (CS, DS, SS) will describe the same linear address range
anyway (only with different types and access rights).

>     It is not possible to allocate three segments of 4GB.

What do you mean by "allocate"? And do you mean three *different*
segments? Ignoring some features of some modern Pentium processors,
you only have a linear address space of 4GB anyway. Why do you want
three different (?) segments describing the same linear address space?

>                                                            Lets say
> 12GB total -- one 4GB for CS segment, one 4GB for SS segment, and one
> 4GB for DS segment using FAR pointer that supports 32 Bits.  No such
> beyond FLAT model uses FAR pointer.  It might be ideal for huge
> database, but Windows XP can only limit 2GB for data and another 2GB
>     for kernel and OS commands. Can you tell how HeapAlloc function
> by Windows XP allocate memory?  Do
> you think that Windows XP allocates free memory before it begins to
> create DS segment so it can point to DS segment?

I think you talk about paging. Yes, with paging you can have a *virtual*
address space bigger than 4GB. But the processor (again excluding
some extensions) cannot address more than 4GB *linear* address space.
As you are talking about Windows (XP): Windows imposes a limit of
2GB (or 3GB, when specially configured) of virtual address space
with regard to your applications. I'm not aware of any API which allows
you to allocate memory in another "linear address range" (being called
"memory context" under Windows, btw.)

>     Suppose -- Pentium III & IV supports 64GB memory, but 4GB memory
> must be swapped at all times.

By the way, these are the "exceptions" are mentioned above.

>                                DS segment has only 16 bits.

What do you mean? In 32-Bit protected mode, DS is a selector that
points to a descriptor which contains a 32-bit virtual base address
and a 20-Bit segment size (which can be multiplied by 4096, resulting
in a 32-Bit segment size).

>                                                              How can
> I point DS segment to between 20 Bits and 36 Bits linear address?

I don't know the 36-Bit case, but because of the 32-Bit base address
the 32-Bit case is not a problem. Suppose

  MOV EAX, DWORD PTR DS:[EBX]

DS = selector to following descriptor:
  base (32-Bit) = 00000000h
  size (32-Bit) = FFFFFFFFh   (==> 4GB)

In combination with 32-Bit offset in EBX, you can address every byte
in the whole 4GB (=32 Bit) linear address range.


Regards,
  Christoph



0
Reply Christoph 10/24/2003 9:47:17 PM

"Bryan Parkoff" <nospam@nospam.com> wrote in message
news:2d1mb.3346$%x5.2960@twister.austin.rr.com...
>     I understand that 16 Bits use far pointer when CS, DS, and SS segments
> are limited to 64KB.  Someone mentioned that CS, DS, and SS segments can
be
> combined into one single segment that uses near pointer.  I believe that
it
> means to be tiny model for *.COM under MS-DOS only.  I think that CS, DS,
> and SS segments are NEVER COMBINED together.  It is always that CS segment
> is as the first paragraph, SS segment is as the second paragraph, and SS
> segment is as the third paragraph.  Lets say, CS segment has 20KB, SS
> segment has 1KB, and DS segment has 4KB.  The total single segment equals
to
> 25KB.

This is partly true. In real mode, segments are always 64 KB. It is possible
to have overlapping regions, too. For example, you can set ds = 0, cs = 10h,
and ss = 9000h. The second 256 bytes of ds are the first 256 bytes in cs.
Neither cs nor ds overlap with ss.

A far pointer is simply a segment and a pointer into that segment. Together
they form a 20-bit address in real-mode. This allows an application to
address up to 1 MB. It is also necessary if the application has more than 64
KB of data. Each segment only gives you up to 64 KB, so if you have more
than that you need multiple segments.

>     It is the same example for FLAT model that uses 32 Bits so CS, SS, and
> DS segments are 4GB.  I suspect that CS segment uses 100MB, SS segment
uses
> 1MB, and DS segment uses 1GB.  The total single segment is 1.101GB.  Do
you
> realize that word concept, "Combine CS, SS, and DS segments into one
single
> segment"?  It is not proper quote, but it is like first, second, and third
> paragraph so they use NEAR pointer to point one of three paragraph.  Does
it
> make sense?

The flat 32-bit memory model actually sets the base of cs, ds, ss, and es to
0 and the limit to 4 GB. Each segment is 4 GB in size, but they all overlap.
A segment is just a set of permissions, a base address, and a length
(limit). All memory references are translated through a segment either
implicitly or explicity. When you execute mov al, [ecx] the processor adds
ds.base + ecx and accesses that address. This is called a linear address.

In a flat memory model, ds, cs, es, and ss all have the same base and limit.
The following code works in a flat memory model but breaks when ss != ds:

mov ecx, esp
mov eax, [esp]
mov edx, [ecx]
cmp eax, edx ; this may not be true!

We did not specify segments for these memory references, so the CPU adds
them implicitly. The esp and ebp registers always use ss, and other
registers use ds. If ds.base and ss.base are not equal, then [ecx] and [esp]
are not equal.

When you load a segment value in real mode, the CPU sets the base address to
the segment value * 16. The limit value is normally left at 64 KB. (The
limit can be changed if you enter protected mode.)

>     It is not possible to allocate three segments of 4GB.  Lets say 12GB
> total -- one 4GB for CS segment, one 4GB for SS segment, and one 4GB for
DS
> segment using FAR pointer that supports 32 Bits.  No such beyond FLAT
model
> uses FAR pointer.  It might be ideal for huge database, but Windows XP can
> only limit 2GB for data and another 2GB for kernel and OS commands.

The other problem is that segments only have 4-byte base pointers. The CPU
truncates the linear address to 32-bits, so after the segment translation
the program can still only access 4 GB.

>     Can you tell how HeapAlloc function by Windows XP allocate memory?  Do
> you think that Windows XP allocates free memory before it begins to create
> DS segment so it can point to DS segment?

The segments don't have to point to valid memory. Windows XP, Linux, and
every other robust operating system out there use something called paging.
The OS provides tables to the CPU called page tables. These tables control
whether the memory is valid to access, whether it can be written, and
whether it can be accessed outside of the OS kernel itself.

After the CPU computes the linear address, it does a paging translation. The
cr3 register holds a pointer to a table called the page directory. The 10
most significant bits in the linear address (bits 22-31) are used to index
this table. The page directory entry holds a 20-bit pointer to what's called
a page table. The lower 12 address bits of the page table are always 0, and
the 20 bits provided from the page directory entry are the upper 20 bits of
the page table's address. The CPU then takes bits 12-21 of the linear
address and does the same thing with the page table. Finally, it adds bits
0-11 of the linear address to the address it read from the page table entry.
This resulting address is the physical address.

Here's the algorithm written in C-like pseudocode:
void *translate_lin_addr(void *p, pagetbl *dir)
{
 int addr = (int) p; // pointer is 32-bits
 int physaddr;
 pagetbl *tbl;

 tbl = (pagetbl *)(dir[addr >> 22] << 12);
 physaddr = tbl[(addr >> 12) & 1023] << 12;
 physaddr |= addr & 1023);

 return (void *) physaddr;
}

The entries also have permission bits. The OS will initialize all of the
pages to "not present" which causes the CPU to generate an exception when
they are accessed. When you allocate memory, the OS will allocate physical
memory and change the state of the page to "present." The minimum amount of
memory that can be allocated is called a page of memory. Look at the
GetSystemInfo() API. One of the fields in the SYSTEM_INFO structure is
dwPageSize. On x86, this is 4 KB.

The heap functions use VirtualAlloc to allocate pages of memory. Out of this
memory they will allocate smaller blocks of any size (like 5 bytes for
example). This makes allocation more efficient. If VirtualAlloc were used to
allocate memory for everything, allocating 5 bytes would require you to
allocate 4,096, and you would waste the remaining 4,091 bytes.

So, anyway, the point of all this is that the ds segment does not point to
valid memory. Windows XP will add a bunch of pages for system DLLs and then
go into user mode and execute the loader. Certain linear addresses are
legal, but others are not, and that is entirely controlled by the page
tables under Windows.

>     Suppose -- Pentium III & IV supports 64GB memory, but 4GB memory must
be
> swapped at all times.  DS segment has only 16 bits.  How can I point DS
> segment to between 20 Bits and 36 Bits linear address?  Lets say, DS is
> D000H times 10H that equals to D0000H.  It may be between 0KB and 1MB, but
> how can it be done beyond 1MB.  It might sound like D000 times 10000H that
> equals to D0000000 for 4GB.

This is only true of classical real mode. "Unreal" mode and 32-bit protected
mode allow you to access up to 4 GB of memory. The problem with accessing
more than 4 GB is that you need pointers that are larger than 32-bits, but
the CPU's registers themselves are only 32-bits wide.

Though the CPU can access up to 64 GB of memory, an application is still
limited to 4 GB. The page tables change slightly to allow the CPU to
generate a 36-bit physical address from a 32-bit linear address. There are
two competing mechanisms to do this. They are called PAE (Physical Address
Extensions) and PSE36 (Page Size Extensions 36-bit).

>     Please explain everything you can, but I am sure that Matt Taylor will
> answer that question.  Matt Taylor, do you have great knowledge of Intel
CPU
> and how it works?  How long have you been experiencing with this? -- 
> Curious --  Thanks...

For a while I worked on an operating system, so I spent a lot of time
learning about what the CPU could do and how it worked. Nowadays I mostly
spend my time working on an emulator/debugger, a disassembler/assembler, or
compiler-related projects. I know the x86 architecture fairly well, though
most of the other regular posters here have more experience than I do; it
was only 3 years ago that I worked on my operating system, and 5 years ago I
was completely ignorant of assembly.

-Matt


0
Reply Matt 10/25/2003 12:48:51 AM

"Bryan Parkoff" <nospam@nospam.com> wrote:
>
>    I understand that 16 Bits use far pointer when CS, DS, and SS segments
>are limited to 64KB.  Someone mentioned that CS, DS, and SS segments can be
>combined into one single segment that uses near pointer.  I believe that it
>means to be tiny model for *.COM under MS-DOS only.  I think that CS, DS,
>and SS segments are NEVER COMBINED together.  It is always that CS segment
>is as the first paragraph, SS segment is as the second paragraph, and SS
>segment is as the third paragraph.  Lets say, CS segment has 20KB, SS
>segment has 1KB, and DS segment has 4KB.  The total single segment equals to
>25KB.

No, you are confusing several concepts here, and they are important
concepts.

When you are writing a program, you create one or more code segments, and
one or more data segments.  Those segments exist only in the binary files.
When the program is loaded into memory, the linker or the operating system
loaders can combine all the code segments together into one segment,
pointed to by CS.  It can combine all of the data segments together into
one segment, pointed to by DS.  In tiny model, it can combine the code
segments, data segments, and stack segment together into one big segment.
In that case, CS, DS, and SS will all be the same number.  In that sense,
they ARE combined.

You need to separate the concept of "code segments" from the value of CS.

>    It is the same example for FLAT model that uses 32 Bits so CS, SS, and
>DS segments are 4GB.  I suspect that CS segment uses 100MB, SS segment uses
>1MB, and DS segment uses 1GB.  The total single segment is 1.101GB.  Do you
>realize that word concept, "Combine CS, SS, and DS segments into one single
>segment"?  It is not proper quote, but it is like first, second, and third
>paragraph so they use NEAR pointer to point one of three paragraph.  Does it
>make sense?

No, this is wrong in exactly the same way.  Your program might have 100MB
in a code section, 1MB in a stack section, and 1GB in a data section.
Those sections will all be loaded into memory when your program loads, at
separate addresses.  However, CS, DS, and SS all point to address 0 and
span all of memory.  You can access any byte in any of the sections using
ANY of the three segment pointers.

	mov	eax, 00401234h
	mov	edx, cs:[eax]
	mov	edx, ds:[eax]
	mov	edx, ss:[eax]

Those three statements are all perfectly valid, and the will all read
EXACTLY the same piece of memory.

>    Can you tell how HeapAlloc function by Windows XP allocate memory?  Do
>you think that Windows XP allocates free memory before it begins to create
>DS segment so it can point to DS segment?

Remember that the DS selector starts at 0 and goes to FFFFFFFF.  It isn't
limited to the data sections of the current program.

For HeapAlloc, Windows reserves a big chunk of the address space for the
heap when the process starts.  It allocates small pieces out of that chunk.

>    Suppose -- Pentium III & IV supports 64GB memory, but 4GB memory must be
>swapped at all times.  DS segment has only 16 bits.  How can I point DS
>segment to between 20 Bits and 36 Bits linear address?

In protected mode, the number in the DS register is an index into a system
table (the GDT or LDT).  Each entry in those tables is a descriptor, which
contains the 32-bit starting address and the 32-bit length of the segment.
In Windows, the descriptors for CS, DS, and SS start at 0 and run for 4GB.

You can only access 4GB at a time.  To get at the additional memory, you
have to use special tricks with the page tables.
-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

0
Reply Tim 10/25/2003 6:05:48 AM

The Windows Heap* functions or C lib ?

"Matt Taylor" <para@tampabay.rr.com> a �crit dans le message de news:
TLjmb.29880$ox6.649801@twister.tampabay.rr.com...
> The heap functions use VirtualAlloc to allocate pages of memory. Out of
this
> memory they will allocate smaller blocks of any size (like 5 bytes for
> example). This makes allocation more efficient. If VirtualAlloc were used
to
> allocate memory for everything, allocating 5 bytes would require you to
> allocate 4,096, and you would waste the remaining 4,091 bytes.
>
> -Matt
>
>



0
Reply Marc 10/25/2003 9:16:51 AM

    It is Windows' HeapAlloc function.

-- 
Bryan Parkoff
"Marc Bassini" <marc.bassini@wanadoo.fr> wrote in message
news:bndf23$9e9$1@news-reader1.wanadoo.fr...
> The Windows Heap* functions or C lib ?
>
> "Matt Taylor" <para@tampabay.rr.com> a �crit dans le message de news:
> TLjmb.29880$ox6.649801@twister.tampabay.rr.com...
> > The heap functions use VirtualAlloc to allocate pages of memory. Out of
> this
> > memory they will allocate smaller blocks of any size (like 5 bytes for
> > example). This makes allocation more efficient. If VirtualAlloc were
used
> to
> > allocate memory for everything, allocating 5 bytes would require you to
> > allocate 4,096, and you would waste the remaining 4,091 bytes.
> >
> > -Matt
> >
> >
>
>
>


0
Reply Bryan 10/25/2003 7:07:29 PM

Tim,

    Now, I understand.  Let says if HeapAlloc starts to allocate memory
before the start address will be $00480068, will DS segment point to
$00480068 (I know that it always starts at $0).  Maybe, it will be second DS
segment since first CS, DS, and SS segment are already starts at $0.  After
the compiler and linker are done, DS segment starts at $0 and second DS
segment starts at $00480068 will be together as single DS segment.  Does it
make sense.
    Is it safe for me to write byte, word, and dword to $00480068?  Look an
example below.

    mov dword ptr [00480068], 44332211h

or

    mov    ds:[00480068], 44332211h

    Are both the same?

    I do not prefer to write .DATA segment under MASM 6.14 so I can write
global variables by using mov DS:00000000, 44332211h and second global
variable will be mov DS:00000004, and third global variable will be mov
DS:0000008.  All of them are DWORD.  Is it just the practice for writing
that way?
    It is the same that I don't create .STACK segment so I would use mov
SS:xxxxxxxx, xxxxxxxx.

    The reason is that I am doing this because I use debugging to read my
code after it is already compiled and linked.  It helps me to understand by
reading CS, DS, and SS segment where it starts.


-- 
Bryan Parkoff
"Tim Roberts" <timr@probo.com> wrote in message
news:sp3kpvo41hn0og8mvepotntifuod52ao45@4ax.com...
> "Bryan Parkoff" <nospam@nospam.com> wrote:
> >
> >    I understand that 16 Bits use far pointer when CS, DS, and SS
segments
> >are limited to 64KB.  Someone mentioned that CS, DS, and SS segments can
be
> >combined into one single segment that uses near pointer.  I believe that
it
> >means to be tiny model for *.COM under MS-DOS only.  I think that CS, DS,
> >and SS segments are NEVER COMBINED together.  It is always that CS
segment
> >is as the first paragraph, SS segment is as the second paragraph, and SS
> >segment is as the third paragraph.  Lets say, CS segment has 20KB, SS
> >segment has 1KB, and DS segment has 4KB.  The total single segment equals
to
> >25KB.
>
> No, you are confusing several concepts here, and they are important
> concepts.
>
> When you are writing a program, you create one or more code segments, and
> one or more data segments.  Those segments exist only in the binary files.
> When the program is loaded into memory, the linker or the operating system
> loaders can combine all the code segments together into one segment,
> pointed to by CS.  It can combine all of the data segments together into
> one segment, pointed to by DS.  In tiny model, it can combine the code
> segments, data segments, and stack segment together into one big segment.
> In that case, CS, DS, and SS will all be the same number.  In that sense,
> they ARE combined.
>
> You need to separate the concept of "code segments" from the value of CS.
>
> >    It is the same example for FLAT model that uses 32 Bits so CS, SS,
and
> >DS segments are 4GB.  I suspect that CS segment uses 100MB, SS segment
uses
> >1MB, and DS segment uses 1GB.  The total single segment is 1.101GB.  Do
you
> >realize that word concept, "Combine CS, SS, and DS segments into one
single
> >segment"?  It is not proper quote, but it is like first, second, and
third
> >paragraph so they use NEAR pointer to point one of three paragraph.  Does
it
> >make sense?
>
> No, this is wrong in exactly the same way.  Your program might have 100MB
> in a code section, 1MB in a stack section, and 1GB in a data section.
> Those sections will all be loaded into memory when your program loads, at
> separate addresses.  However, CS, DS, and SS all point to address 0 and
> span all of memory.  You can access any byte in any of the sections using
> ANY of the three segment pointers.
>
> mov eax, 00401234h
> mov edx, cs:[eax]
> mov edx, ds:[eax]
> mov edx, ss:[eax]
>
> Those three statements are all perfectly valid, and the will all read
> EXACTLY the same piece of memory.
>
> >    Can you tell how HeapAlloc function by Windows XP allocate memory?
Do
> >you think that Windows XP allocates free memory before it begins to
create
> >DS segment so it can point to DS segment?
>
> Remember that the DS selector starts at 0 and goes to FFFFFFFF.  It isn't
> limited to the data sections of the current program.
>
> For HeapAlloc, Windows reserves a big chunk of the address space for the
> heap when the process starts.  It allocates small pieces out of that
chunk.
>
> >    Suppose -- Pentium III & IV supports 64GB memory, but 4GB memory must
be
> >swapped at all times.  DS segment has only 16 bits.  How can I point DS
> >segment to between 20 Bits and 36 Bits linear address?
>
> In protected mode, the number in the DS register is an index into a system
> table (the GDT or LDT).  Each entry in those tables is a descriptor, which
> contains the 32-bit starting address and the 32-bit length of the segment.
> In Windows, the descriptors for CS, DS, and SS start at 0 and run for 4GB.
>
> You can only access 4GB at a time.  To get at the additional memory, you
> have to use special tricks with the page tables.
> -- 
> - Tim Roberts, timr@probo.com
>   Providenza & Boekelheide, Inc.
>


0
Reply Bryan 10/25/2003 7:24:07 PM

"Marc Bassini" <marc.bassini@wanadoo.fr> wrote in message
news:bndf23$9e9$1@news-reader1.wanadoo.fr...
> The Windows Heap* functions or C lib ?
<snip>

All operating systems that use paging (Linux, Windows, BSD, etc.) allocate
pages of memory to the application. A memory page is the minimum unit that
can be allocated because memory is added to the process's address space
through the page tables, and the minimum size that can be represented is 1
memory page.

On Windows, I believe the global/local legacy memory functions use the Win32
heap functions. The heap functions actually call RtlHeapXYZ (XYZ = name of
particular function like Allocate or Free), at least on NT. The RtlHeap
functions call virtual memory functions.

The C runtime malloc/realloc/free are a bit convoluted. They do make calls
to the Win32 heap functions, but they also implement some of the heap logic
themselves. I once asked why malloc() did not map 1:1 onto HeapAlloc() and
was told that the CRT uses a thread-local heap for performance, but reading
the code I do not see this anywhere. (BTW, if you have a copy of Visual C++
then you also have a copy of the C Runtime source!)

The C++ new and delete operators are analagous to malloc() and free() and
are probably implemented the same way; in either case, they will eventually
fall back to the virtual memory allocation functions.

-Matt


0
Reply Matt 10/26/2003 2:39:23 AM

"Bryan Parkoff" <nospam@nospam.com> wrote:
>
>    Now, I understand.  Let says if HeapAlloc starts to allocate memory
>before the start address will be $00480068, will DS segment point to
>$00480068 (I know that it always starts at $0).  Maybe, it will be second DS
>segment since first CS, DS, and SS segment are already starts at $0.  After
>the compiler and linker are done, DS segment starts at $0 and second DS
>segment starts at $00480068 will be together as single DS segment.  Does it
>make sense.

I think you're getting it here, but you are only going to cause confusion
if you keep referring to everything as segments.  Especially in the Win32
world, the chunks in an executable file to be loaded are called "sections".
Your data SECTION will be loaded somewhere in memory, although you access
it using the DS register.

>    Is it safe for me to write byte, word, and dword to $00480068?  Look an
>example below.
>
>    mov dword ptr [00480068], 44332211h
>or
>    mov    ds:[00480068], 44332211h
>
>    Are both the same?

Yes; in fact, they will compile to exactly the same instruction.  Remember
that DS: is assumed by default.  EVERY access to memory in an x86 uses one
of the segment registers.

>    I do not prefer to write .DATA segment under MASM 6.14 so I can write
>global variables by using mov DS:00000000, 44332211h and second global
>variable will be mov DS:00000004, and third global variable will be mov
>DS:0000008.  All of them are DWORD.  Is it just the practice for writing
>that way?

Absolutely not!  As I said above, DS: starts at 0.  If you write this:
    mov    eax, ds:[00000000h]
you have fetched the word at linear address 0, which will ordinarily be the
16:16 address of the DOS-mode vector for INT 0.  The first word of YOUR
data segment is at some larger address in memory, which you CAN NOT KNOW at
assembly time.

Use the .data directive.  You will only hurt yourself if you do not.

>    It is the same that I don't create .STACK segment so I would use mov
>SS:xxxxxxxx, xxxxxxxx.

You do not need to create a .stack section; the operating system will
create one for you.

>    The reason is that I am doing this because I use debugging to read my
>code after it is already compiled and linked.  It helps me to understand by
>reading CS, DS, and SS segment where it starts.

In Win32 (and in Linux), the segment descriptors in the CS, DS, and SS
registers will all start at linear address 0.  Always.  When you link your
program, you tell the linker where you want the program to start (the
preferred load address); by default it is 00400000.  By using the linker's
load map, you can tell where in memory your code and data sections will be
loaded.  You can use that in your debugger to locate your code.
-- 
- Tim Roberts, timr@probo.com
  Providenza & Boekelheide, Inc.

0
Reply Tim 10/27/2003 2:57:13 AM

Hi
You write:
Remember that the DS selector starts at 0 and goes to FFFFFFFF. It
isn't
limited to the data sections of the current program.
My question is: why should I give a limit of FFFFFFFF if I know that my
data segment needs only 200 bytes ?
Thanks in advance
Regards,
xyoavx

0
Reply xyoavx 1/2/2005 7:26:13 PM


xyoavx wrote:

> Hi
> You write:
> Remember that the DS selector starts at 0 and goes to FFFFFFFF. It
> isn't
> limited to the data sections of the current program.
> My question is: why should I give a limit of FFFFFFFF if I know that my
> data segment needs only 200 bytes ?
> Thanks in advance
> Regards,
> xyoavx

it really depends on what you want to do.  For example giving it a large
limit lets you access *all* memory, including things like the lower 640K
(which is sometimes useful when programming in DPMI) or the video memory,
or lets you modify things in the code area, all without changing
selectors.  But if you want to make sure your programs works within the
designed limitations, or are designing an OS where you want tasks insulated
from each other, then it makes sense to limit DS to what is needed.

David

0
Reply David 1/2/2005 9:13:13 PM

"xyoavx" <spamtrap@crayne.org> wrote in message 
news:1104685938.201884.44330@c13g2000cwb.googlegroups.com...
> Hi
> You write:
> Remember that the DS selector starts at 0 and goes to FFFFFFFF. It
> isn't
> limited to the data sections of the current program.
> My question is: why should I give a limit of FFFFFFFF if I know that my
> data segment needs only 200 bytes ?

Because there isn't any purpose to doing that when you are using paging. If 
your data section is loaded at 4KB then accessing memory at 8KB will cause 
an exception. (Remember, 0KB or NULL is typically reserved as an error 
return from memory allocation functions.)

There is, instead, very good reason *not* to change the limit of DS. A large 
amount of code expects ds.base == 0 and ds.limit == 4GB. Calling into shared 
libraries means they will have to change the value of DS. Unfortunately it's 
not as simple as recompiling the code to handle this, but even if it were, 
most programs would run much slower because they spent so much time changing 
DS.

Even if your program does not load any share libraries (which is impossible 
on Windows), this still won't work. Newer x86 processors support a few 
special instructions for making OS calls. These instructions are used for 
making *fast* system calls. The caveat is that they assume the segment 
registers all have a base of 0 and limit of 4GB. Changing the limit of DS 
will not work with these fast system call instructions.

-Matt 

0
Reply Matt 1/2/2005 9:29:06 PM

David Lindauer wrote:
> xyoavx wrote:
>
> > Hi
> > You write:
> > Remember that the DS selector starts at 0 and goes to FFFFFFFF. It
> > isn't
> > limited to the data sections of the current program.
> > My question is: why should I give a limit of FFFFFFFF if I know
that my
> > data segment needs only 200 bytes ?
> > Thanks in advance
> > Regards,
> > xyoavx
>
> it really depends on what you want to do.  For example giving it a
large
> limit lets you access *all* memory, including things like the lower
640K
> (which is sometimes useful when programming in DPMI) or the video
memory,
> or lets you modify things in the code area, all without changing
> selectors.  But if you want to make sure your programs works within
the
> designed limitations, or are designing an OS where you want tasks
insulated
> from each other, then it makes sense to limit DS to what is needed.
> 
> David

0
Reply xyoavx 1/2/2005 9:41:29 PM

Hi David
Thnks a lot
Regards,
xyoavx

0
Reply xyoavx 1/2/2005 9:41:32 PM

Hi Matt
Thanks a lot for your profound answer. Wherefrom did you get this
information ?
(books, articles, websites etc). I've never found such information,
although I read many books & articles.
Thanks in advance
Regards,
xyoavx
Matt wrote:
> "xyoavx" <spamtrap@crayne.org> wrote in message
> news:1104685938.201884.44330@c13g2000cwb.googlegroups.com...
> > Hi
> > You write:
> > Remember that the DS selector starts at 0 and goes to FFFFFFFF. It
> > isn't
> > limited to the data sections of the current program.
> > My question is: why should I give a limit of FFFFFFFF if I know
that my
> > data segment needs only 200 bytes ?
>
> Because there isn't any purpose to doing that when you are using
paging. If
> your data section is loaded at 4KB then accessing memory at 8KB will
cause
> an exception. (Remember, 0KB or NULL is typically reserved as an
error
> return from memory allocation functions.)
>
> There is, instead, very good reason *not* to change the limit of DS.
A large
> amount of code expects ds.base == 0 and ds.limit == 4GB. Calling into
shared
> libraries means they will have to change the value of DS.
Unfortunately it's
> not as simple as recompiling the code to handle this, but even if it
were,
> most programs would run much slower because they spent so much time
changing
> DS.
>
> Even if your program does not load any share libraries (which is
impossible
> on Windows), this still won't work. Newer x86 processors support a
few
> special instructions for making OS calls. These instructions are used
for
> making *fast* system calls. The caveat is that they assume the
segment
> registers all have a base of 0 and limit of 4GB. Changing the limit
of DS
> will not work with these fast system call instructions.
> 
> -Matt

0
Reply xyoavx 1/3/2005 10:28:28 PM

"xyoavx" <spamtrap@crayne.org> wrote in message 
news:1104789645.609475.163050@c13g2000cwb.googlegroups.com...
> Hi Matt
> Thanks a lot for your profound answer. Wherefrom did you get this
> information ?
> (books, articles, websites etc). I've never found such information,
> although I read many books & articles.
[...]

The best source of information is probably the Intel manuals themselves.

-Matt 

0
Reply Matt 1/4/2005 4:55:51 AM

16 Replies
306 Views

(page loaded in 0.132 seconds)

Similiar Articles:


















7/29/2012 6:46:40 PM


Reply: