[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Some words of encouragement

On 25/02/12 06:27, Brad Normand wrote:
> Anything that targets "normal" x86-16 with bigger than 64KB data
> chunks needs to understand arithmetic on far addresses, and I wonder
> how hard it would be to do some sort of virtual linearization here,
> basically instead of a far pointer being effectively 20 bits of
> address inside 32 bits of storage, just make them flat 32 bits.

Well, Watcom does support this --- it's called HUGE model.

Here's a simple memcpy implementation:

void copy(char* dest, const char* src, int length)
	while (length--)
		*dest++ = *src++;

Here's the small mode version:

0000                          @copy:
0000    56                        push        si
0001    57                        push        di
0002    89 C7                     mov         di,ax
0004    89 D6                     mov         si,dx
0006                          L$1:
0006    4B                        dec         bx
0007    83 FB FF                  cmp         bx,0xffff
000A    74 08                     je          L$2
000C    8A 04                     mov         al,byte ptr [si]
000E    88 05                     mov         byte ptr [di],al
0010    46                        inc         si
0011    47                        inc         di
0012    EB F2                     jmp         L$1
0014                          L$2:
0014    5F                        pop         di
0015    5E                        pop         si
0016    C3                        ret

And here's the huge mode version:

0000                          @copy:
0000    56                        push        si
0001    57                        push        di
0002    55                        push        bp
0003    89 E5                     mov         bp,sp
0005    83 EC 02                  sub         sp,0x0002
0008    C4 7E 0A                  les         di,dword ptr 0xa[bp]
000B    C5 76 0E                  lds         si,dword ptr 0xe[bp]
000E    89 46 FE                  mov         word ptr -0x2[bp],ax
0011                          L$1:
0011    FF 4E FE                  dec         word ptr -0x2[bp]
0014    83 7E FE FF               cmp         word ptr -0x2[bp],0xffff
0018    74 2B                     je          L$2
001A    8A 04                     mov         al,byte ptr [si]
001C    26 88 05                  mov         byte ptr es:[di],al
001F    89 F0                     mov         ax,si
0021    8C DA                     mov         dx,ds
0023    BB 01 00                  mov         bx,0x0001
0026    31 C9                     xor         cx,cx
0028    9A 00 00 00 00            call        __PIA
002D    89 C6                     mov         si,ax
002F    8E DA                     mov         ds,dx
0031    89 F8                     mov         ax,di
0033    8C C2                     mov         dx,es
0035    BB 01 00                  mov         bx,0x0001
0038    31 C9                     xor         cx,cx
003A    9A 00 00 00 00            call        __PIA
003F    89 C7                     mov         di,ax
0041    8E C2                     mov         es,dx
0043    EB CC                     jmp         L$1
0045                          L$2:
0045    89 EC                     mov         sp,bp
0047    5D                        pop         bp
0048    5F                        pop         di
0049    5E                        pop         si
004A    CA 08 00                  retf        0x0008

So two and a half times the size *and* it's having to call off to an
external routine to do pointer arithmetic. But you do get standard
32-bit pointer semantics with arbitrary sized data structures.

There's a compromise, large mode, where the programmer promises that no
single data structure is bigger than 64kB. This means that it can
represent any pointer as a segment+offset pair, and do sane pointer
arithmetic with just the offset, which is much cheaper; the large mode
version of the above is only 30 bytes.

> This sounds like it'd be a good way to help ferret out bcc compiler
> bugs or bypass them entirely, plus from what I've read, Watcom is one
> of the better compilers to target 16 bit x86 in general.  There may be
> some hints in FreeDOS, as openwatcom is one of the supported compilers
> for the kernel there.

Unfortunately it seems that OMF object files can't represent pointer
differences. Which means I can't do this to emit the ELKS executable header:

	dw __tend, 0           ; size of text segment in bytes
	dw _edata, 0           ; size of data segment in bytes
	dw _end - _edata, 0    ; size of bss segment in bytes
	dw _cstart_, 0         ; entry point
	dw 65535, 0            ; chmem
	dw 0, 0                ; size of symbol table

The '_end - _edata' is silently accepted by wasm but evaluates to 0.
Which is nice. nasm was more informative (and has a saner syntax; I'd
forgotten how loathesome masm syntax is).

I'm now thinking that the sanest way to go here is (a) hack Watcom to
support ELKS executables directly; (b) write a tool to disassemble the
OMF output and convert it to as86-compatible format; (c) give up and go
to the pub...

┌─── dg@cowlark.com ───── http://www.cowlark.com ─────
│ "Never attribute to malice what can be adequately explained by
│ stupidity." --- Nick Diamos (Hanlon's Razor)

Attachment: signature.asc
Description: OpenPGP digital signature

[Kernel]     [Linux ia64]     [DCCP]     [Linux for ARM]     [Linux]     [Photo]     [Yosemite News]     Dell XPS 2720 wall mount     [Linux SCSI]     [Linux Hams]

Add to Google Powered by Linux