Mail Archives: djgpp/1998/01/04/17:31:03

Date: Sun, 4 Jan 1998 14:29:05 -0800 (PST)
Message-Id: <>
Mime-Version: 1.0
To: =?iso-8859-1?Q?=22S=E9rgio_Vale_e_Pace=22?= <space AT gold DOT com DOT br>,
djgpp AT delorie DOT com
From: Nate Eldredge <eldredge AT ap DOT net>
Subject: Re: dos_ds

At 03:41  1/4/1998 -0200, Sérgio Vale e Pace wrote:
>Somebody out there can tell-me how exactly dos_ds is defined and how it
`_dos_ds' (note leading underscore) is a selector which can be used to
access conventional memory (as with `movedata'). It is actually a macro
which expands to the ridiculously long name of a field in an info structure.
>I took a look on the DJGPP sources but seems like dos_ds uses the fat DS
>is that correct?
Currently, it's similar to that. Its limit is set to -1 when it is
allocated. However, it has been realized that this will not work on systems
like Windows NT. The limit will be changed to something more reasonable in
the next version, or so I understand.
>And another thing, can somebody tell-me how exactly fat DS works, I
>already understand what I need to do to use it, bu I don't understand
>why do this make it work, and how to calculate a real memory pointer
>using fat DS. What see in the mail-archives for screen access look
>pretty strange for me.
The 386 has a 4GB address space. However, each segment has a base address
within that, and a limit, above which access is disallowed. Each program
sees itself running starting at virtual address zero. The Fat DS trick sets
the limit of the DS segment to -1, or 0xFFFFFFFF in two's complement
arithmetic. This means that the DS segment wraps all the way around the 4GB
address space and any memory can be accessed relative to it. Since your
program normally dereferences pointers relative to DS, you can now access
any memory.
Since the base of DS does not change, all your program's pointers can stay
where they are. But conventional memory, for instance, will seem to be at
some huge address. This is where the _djgpp_conventional_base (I think
that's what it's called) variable comes in. Since the base of DS *can*
change somewhat when sbrk() is called, this variable stores where
conventional memory currently apprears to be. By adding some real-mode
linear address to this, you can make a pointer to anywhere in conventional
memory you want. The real-mode style segment/offset translation is not
automatic, so you have to calculate it yourself:
linear_address = (segment << 4) + offset;
The canonical example is video memory, which in real mode is considered to
be at 0xA000:0000. This translates to a linear address of 0xA0000, which one
can add to _djgpp_conventional_base and write video memory quite nicely.

Of course you must be careful doing this, because overwriting DOS or other
important things living in conventional memory is depressingly easy with Fat
DS on.

Nate Eldredge
eldredge AT ap DOT net

- Raw text -

  webmaster     delorie software   privacy  
  Copyright © 2019   by DJ Delorie     Updated Jul 2019