All segments with the same group name must fit into a single physical segment, which is up to 64K long. This allows all segments in a group
to be accessed through the same segment register. The Microsoft C
Compiler defines one group named DGROUP.
The short story is that I've been playing with the OpenWatcom code
generator. I can use it to make a custom object file. The platform
is 32bit x86, though I'm happy to know how things work in 16bit and
64bit modes as well.
The code generator has options I do not fully understand, and I do
not know where I can find information on this subject. To further
complicate matters I'm unsure what questions I should be asking.
When I am defining my own compiler, do the traditional names of object
file segments, _TEXT, _DATA, STACK, _BSS, CONST (to name a few from the
MS manual) any meaning? When I place my code in a _TEXT segment, the disassembler will show a list of the instructions; this does not happen
if I name the segment FOO. Is there any particular reason I want my
code in a _TEXT segment rather than FOO?
The Watcom (at least before OpenWatcom) compilers were the only ones
I knew to generate large model (more than one segment) 32 bit code.
It might be that OS/2 even knows how to load and run it.
(I am pretty sure that Windows and Unix don't.)
[On the 386, all of the segments in a process were mapped into a
single 32 bit paged linear address space, so the total size of all
segments in a program was limited to 4G unless you did pseudo-swapping
of segments in and out of the address space, which I don't think
anyone did.
So not only were they slow, they didn't help. -John]
On Friday, June 19, 2020 at 8:33:34 AM UTC-7, Johann 'Myrkraverk' Oskarsson wrote:
The short story is that I've been playing with the OpenWatcom code
generator. I can use it to make a custom object file. The platform
is 32bit x86, though I'm happy to know how things work in 16bit and
64bit modes as well.
The code generator has options I do not fully understand, and I do
not know where I can find information on this subject. To further
complicate matters I'm unsure what questions I should be asking.
(snip)
The Watcom (at least before OpenWatcom) compilers were the only ones
I knew to generate large model (more than one segment) 32 bit code.
It might be that OS/2 even knows how to load and run it.
(I am pretty sure that Windows and Unix don't.)
In that model, pointers are 48 bit, with a 16 bit segment selector
and 32 bit offset. This would have been another way to get
past the 32 bit barrier without going to 64 bit.
Well, there is a reason not to do it, which is that processors don't
have a segment descriptor cache. Every load of a segment selector
requires a side load of the descriptor, so too much overhead.
In any case, code that you expected to be only in the 16 bit section,
related to segments, should be in there, also. As I noted, it is
OS/2 where this could have been used, so it might only be in the OS/2
object program format. I don't remember now how the OS/2 and Win32
formats differ.
In 16 bit modes, you can have huge data, which allows for a multiple
segment data object, with segment selectors spaced to allow for
appropriate calculation. I believe this is only for dynamically
allocated data, but it might also allow for static allocation
in the object program. I tried to avoid that.
Am 19.06.2020 um 17:22 schrieb Johann 'Myrkraverk' Oskarsson:
When I am defining my own compiler, do the traditional names of object
file segments, _TEXT, _DATA, STACK, _BSS, CONST (to name a few from the
MS manual) any meaning? When I place my code in a _TEXT segment, the
disassembler will show a list of the instructions; this does not happen
if I name the segment FOO. Is there any particular reason I want my
code in a _TEXT segment rather than FOO?
I think that it's not the segment name that enforces special handling
but segment attributes. Eventually these attributes are defined in the various segment groups only, not at segment level?
It depends on the target OS and hardware whether deailed hardware
protection is applied to memory segments. Code segments can be read-only
or execute-only, all others non-execute. Const segments also can/should
be read-only. The same protection schemes can apply to paged memory. A compiler only can assign attributes to memory sections, the use of these attributes depends on the linker and loader for the target platform.
In 16 bit modes, you can have huge data, which allows for a multiple
segment data object, with segment selectors spaced to allow for
appropriate calculation. I believe this is only for dynamically
allocated data, but it might also allow for static allocation
in the object program. I tried to avoid that.
Do you know if group names have any meaning in the modern world? DGROUP seems like a traditional name. The OW disassembler tells me this when I apply it to output from the C compiler, GROUP: 'DGROUP' CONST, CONST2,
_DATA.
This group does not seem to list the _TEXT segment, which is
where the code lives.
AFAIR the starting
segment selector allowed to access at least 512 MB (8 consecutive
segments). This feature did not allow to break the 4GB total limit, but
it allowed for contiguous data areas bigger than 64KB.
DoDi
[Nobody I knew used huge model because it was so very very slow. There
was no way on 16-bit x86 to access more than 64K at a time without runtime segment calculations. -John]
The 16/32 bit address size prefix inverts the default address size, i.e. allows to use 32 bit addresses and offset registers with 16 bit code.
I used 32 bit offsets in 16 bit code with the Borland compilers,
disassembled the generated machine code. I never used the HUGE model.
DoDi
[Oh, running on a 386, sure, that would have worked. -John]
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 293 |
Nodes: | 16 (2 / 14) |
Uptime: | 216:42:31 |
Calls: | 6,621 |
Calls today: | 3 |
Files: | 12,169 |
Messages: | 5,317,616 |