seg keyword

40 views
Skip to first unread message

Paul Edwards

unread,
Nov 19, 2022, 2:23:06 PM11/19/22
to
I have code like this:

extrn int0:proc

public handler0

mov bx, 0
push bx
pop es
cli
mov bx, offset handler0
mov es:[0h], bx
mov bx, seg handler0
mov es:[02h], bx


handler0 proc
push bp
push ax


as86 uses 16-bit a.out format, and I'm not sure it can
handle a reference to just "seg". ie half of an address
being fixed up (I think that's what it does).

Is there a better way of writing this code, more in line
with the simple a.out format?

Is it:

addr0 dd handler0

And then do an les of that?

Thanks. Paul.

Alexei A. Frounze

unread,
Nov 19, 2022, 5:08:16 PM11/19/22
to
On Saturday, November 19, 2022 at 11:23:06 AM UTC-8, Paul Edwards wrote:
> I have code like this:
...
> mov bx, offset handler0
> mov es:[0h], bx
> mov bx, seg handler0
> mov es:[02h], bx
...
> as86 uses 16-bit a.out format, and I'm not sure it can
> handle a reference to just "seg". ie half of an address
> being fixed up (I think that's what it does).
>
> Is there a better way of writing this code, more in line
> with the simple a.out format?
>
> Is it:
>
> addr0 dd handler0
>
> And then do an les of that?

I don't recall the a.out format supporting segmentation.

I found my way around the similar problem with the ELF
format by simply using 32-bit physical addresses,
which are then decomposed into 16-bit segment and
16-bit offset pairs whenever necessary.

Alex

Paul Edwards

unread,
Nov 19, 2022, 8:19:35 PM11/19/22
to
On Sunday, November 20, 2022 at 6:08:16 AM UTC+8, Alexei A. Frounze wrote:

> > Is it:
> >
> > addr0 dd handler0
> >
> > And then do an les of that?

> I don't recall the a.out format supporting segmentation.
>
> I found my way around the similar problem with the ELF
> format by simply using 32-bit physical addresses,
> which are then decomposed into 16-bit segment and
> 16-bit offset pairs whenever necessary.

How do I use a 32-bit physical address?

Is it like above?

Thanks. Paul.

Alexei A. Frounze

unread,
Nov 19, 2022, 11:05:21 PM11/19/22
to
Yes.

I used the assembler (NASM) in the 32-bit non-segmented mode,
where all addresses are simply 32-bit offsets.

The linker, startup code (AKA loader) and generated code then
convert these into seg16:ofs16 using 80386 32-bit instructions.

[This is SmallerC's huge memory model in a nutshell.]

While said conversion is conceptually trivial, only a few 8086
instructions (far call, far jump, lds/les) can consume 32 bits
of an address (seg16:ofs16). Everywhere else you have the far
address split into two 16-bit portions with some space (code)
between the two.

If you want to be able to use these 16-bit parts independently,
you need to produce two special kinds of relocation records,
one for the SEG keyword, the other for the OFS/OFFSET.
The latter is more or less trivial and already exists, but is
probably 32-bit in your assembler, whereas it needs to be 16-bit.
The former needs to be introduced.

The simplest is perhaps to restrict every object file to
two segments/sections (code and data), each at most 64KB
in size and 16-byte aligned and padded to a multiple of 16 bytes.
OFS/OFFSET would then be the subroutine/variable offset
from the beginning of its segment/section in the object file.
SEG would simply account for the cumulative size of all
the linked object files. In essence, you end up relocating
only the SEG part as the OFS/OFFSET part is fixed.

Otherwise you could dump all far pointers into the default
data segment and simply do lds/les as needed (naturally,
the pointer values must've been relocated by then).

Alex

Paul Edwards

unread,
Nov 20, 2022, 7:35:48 AM11/20/22
to
On Sunday, November 20, 2022 at 12:05:21 PM UTC+8, Alexei A. Frounze wrote:

> > How do I use a 32-bit physical address?
> >
> > Is it like above?

> Yes.

Thanks. I just went ahead and tried that, but it didn't seem to work.

Any idea what I did wrong?

Here is the old (working) code:

; Released to the public domain by Matthew Parker on 4 December 1995
; Mods by Paul Edwards, also public domain.
; For different models just change the .model directive

% .model memodel, c

public instint

extrn int0:proc
extrn int1:proc
extrn int3:proc
extrn int20:proc
extrn int21:proc
extrn int25:proc
extrn int26:proc

public handler0
public handler1
public handler3
public handler20
public handler21
public handler25
public handler26

.code

instint proc uses bx es
mov bx, 0
push bx
pop es
cli
mov bx, offset handler0
mov es:[0h], bx
mov bx, seg handler0
mov es:[02h], bx
mov bx, offset handler1
mov es:[04h], bx
mov bx, seg handler1
mov es:[06h], bx
mov bx, offset handler3
mov es:[0ch], bx
mov bx, seg handler3
mov es:[0eh], bx
mov bx, offset handler20
mov es:[80h], bx
mov bx, seg handler20
mov es:[82h], bx
mov bx, offset handler21
mov es:[84h], bx
mov bx, seg handler21
mov es:[86h], bx
mov bx, offset handler25
mov es:[94h], bx
mov bx, seg handler25
mov es:[96h], bx
mov bx, offset handler26
mov es:[98h], bx
mov bx, seg handler26
mov es:[9Ah], bx
sti
ret
instint endp

; the stack will already have
; flags
; cs
; ip

handler0 proc
push bp
push ax
push ax ; dummy, actually cflag storage
push bx
push cx
push dx
push si
push di
push ds
push es

mov dx, DGROUP
mov ds, dx
mov ax, sp
push ss
push ax
call int0
add sp, 4

pop es
pop ds
pop di
pop si
pop dx
pop cx
pop bx
pop ax ; actually cflag

cmp ax, 0
je clear0
jmp notclear0
clear0:
pop ax
push bp
mov bp, sp
and word ptr [bp+6],0fffeh
pop bp
pop bp
iret
notclear0:
pop ax
push bp
mov bp, sp
or word ptr [bp+6],0001h
pop bp
pop bp
iret
handler0 endp

...

And here is the new code, which is now preventing PDOS/86
from booting:

; Released to the public domain by Matthew Parker on 4 December 1995
; Mods by Paul Edwards, also public domain.
; For different models just change the .model directive

% .model memodel, c

public instint

extrn int0:proc
extrn int1:proc
extrn int3:proc
extrn int20:proc
extrn int21:proc
extrn int25:proc
extrn int26:proc

public handler0
public handler1
public handler3
public handler20
public handler21
public handler25
public handler26

.data
addr0 dd handler0
addr1 dd handler1
addr3 dd handler3
addr20 dd handler20
addr21 dd handler21
addr25 dd handler25
addr26 dd handler26

.code

instint proc uses bx es ds
mov bx, 0
push bx
pop es
cli

lds bx, addr0
mov es:[0h], bx
mov es:[02h], ds

lds bx, addr1
mov es:[04h], bx
mov es:[06h], ds

lds bx, addr3
mov es:[0ch], bx
mov es:[0eh], ds

lds bx, addr20
mov es:[80h], bx
mov es:[82h], ds

lds bx, addr21
mov es:[84h], bx
mov es:[86h], ds

lds bx, addr25
mov es:[94h], bx
mov es:[96h], ds

lds bx, addr26
mov es:[98h], bx
mov es:[9Ah], ds

sti
ret
instint endp

; the stack will already have
; flags
; cs
; ip

handler0 proc
push bp
push ax
push ax ; dummy, actually cflag storage

...



Thanks. Paul.

Paul Edwards

unread,
Nov 22, 2022, 9:27:54 PM11/22/22
to
On Sunday, November 20, 2022 at 8:35:48 PM UTC+8, Paul Edwards wrote:

> And here is the new code, which is now preventing PDOS/86
> from booting:

I decided to have another crack at this, to see if the
recent changes to pdos/86 to build it using the huge
memory model instead of the large memory model,
with a 32-bit size_t, but still pure 8086 code, had made
this problem go away. But the problem was still there.

> .data
> addr0 dd handler0
> addr1 dd handler1
> addr3 dd handler3
> addr20 dd handler20
> addr21 dd handler21
> addr25 dd handler25
> addr26 dd handler26
>
> .code
>
> instint proc uses bx es ds
> mov bx, 0
> push bx
> pop es
> cli
> lds bx, addr0

This causes ds to be destroyed.

> mov es:[0h], bx
> mov es:[02h], ds
>
> lds bx, addr1

This uses the destroyed ds to attempt to access addr1 :-)

I solved the problem by doing this:

push ds
lds bx, addr1
mov es:[04h], bx
mov es:[06h], ds
pop ds

And now all of wasm, masm and as86 assemble the code,
but I can only test that wasm and masm actually work.

BFN. Paul.

Kerr-Mudd, John

unread,
Nov 23, 2022, 7:58:32 AM11/23/22
to
^w overwritten
>
> > mov es:[0h], bx
> > mov es:[02h], ds
> >
> > lds bx, addr1
>
> This uses the destroyed ds to attempt to access addr1 :-)
>
> I solved the problem by doing this:
>
> push ds
> lds bx, addr1
> mov es:[04h], bx
> mov es:[06h], ds
> pop ds

You've changed the target address?!

If all your doing is moving some dwords, 'movsd' might be what you need.

>
> And now all of wasm, masm and as86 assemble the code,
> but I can only test that wasm and masm actually work.
>
> BFN. Paul.
>


--
Bah, and indeed Humbug.

Paul Edwards

unread,
Nov 23, 2022, 3:05:22 PM11/23/22
to
On Wednesday, November 23, 2022 at 8:58:32 PM UTC+8, Kerr-Mudd, John wrote:
> > push ds
> > lds bx, addr1
> > mov es:[04h], bx
> > mov es:[06h], ds
> > pop ds

> You've changed the target address?!

Sorry, I don't understand.

> If all your doing is moving some dwords, 'movsd' might be what you need.

Thanks, let me look into that.

By the way, I realized something.

Isn't "mov ax, DGROUP"

effectively a move of a segment?

If a.out can handle passing on the DGROUP reference, why
not the segment of other references?

Or will that be specially known by the linker?

Thanks. Paul.

Paul Edwards

unread,
Nov 23, 2022, 8:20:39 PM11/23/22
to
On Wednesday, November 23, 2022 at 8:58:32 PM UTC+8, Kerr-Mudd, John wrote:

> If all your doing is moving some dwords, 'movsd' might be what you need.

I think that is an 80386 instruction based on the error
I got from Watcom. I am after 8086.

movsw is available, but it didn't seem to buy anything
more than I already had.

BFN. Paul.

Kerr-Mudd, John

unread,
Nov 24, 2022, 12:06:23 PM11/24/22
to
Fine. but it would avoid loading seg registers unneccessarrilly (delete
duplicate letters to suit).

Paul Edwards

unread,
Nov 24, 2022, 3:42:30 PM11/24/22
to
On Friday, November 25, 2022 at 1:06:23 AM UTC+8, Kerr-Mudd, John wrote:

> > movsw is available, but it didn't seem to buy anything
> > more than I already had.
> >
> Fine. but it would avoid loading seg registers unneccessarrilly (delete
> duplicate letters to suit).

Is that for performance reasons?

Thanks. Paul.

Kerr-Mudd, John

unread,
Nov 25, 2022, 7:28:22 AM11/25/22
to
No, it just avoids Pushing & Popping ds; your choice.
Reply all
Reply to author
Forward
0 new messages