3

I am doing some work on 8086 real mode. I am used to doing it in assembly, but wanted to give C compilers a try. It seems to me that compilers assume that all the segment registers have the same value. It is not so in my case; SS is 0x4C0, while the DS = ES = CS = 0x800.

So the following when compiled, produces code without taking into the fact that SS <> DS.

[Source: here]

uint8 ch;
void main()
{
    uint8 hexchars[] = {'0','1','2','3','4','5','6','7','8','9','A','B',
                        'C','D','E','F'};
    uint8 i = 0;
    ch = hexchars[i];
}

When compiled, the assignment produces: [Full source: here]

// ch = hexchars[i];
00000156  8A46FF            mov al,[bp-0x1]        ; 'i' is at [BP - 0x1]
00000159  30E4              xor ah,ah
0000015B  89C7              mov di,ax
0000015D  89EE              mov si,bp
0000015F  89FB              mov bx,di
00000161  8A40EF            mov al,[bx+si-0x11      ; 'hexchars[0] is at [BP - 0x11]
00000164  A28401            mov [0x184],al          ; 'ch' is at location 0x184

Because SS is not explicitly mentioned, DS will be assumed by the assembler.

As stated above in my case SS <> DS, thus AL now has a value from a wrong address.

MOV AL, DS:[BX + SI - 0x11] <> MOV AL, SS:[BX + SI - 0x11]

Compilers I have tried:

1. GCC Version 6.2.0 (Sourcery CodeBench Lite 2016.11-64)

ia16-elf-gcc -Wall main.c -o main.com -T main.ld

Linker file is as follows:

OUTPUT_FORMAT(binary)
SECTIONS
{
    . = 0x0;
    .text :
    {
        *(.text);
    }
    .data :
    {
        *(.data);
        *(.bss);
        *(.rodata);
    }
    _heap = ALIGN(4);
    /DISCARD/ : 
    {
         *(.eh_frame)
    }
}

2. Bruce's C compiler [Full source used with BCC here]

bcc -ansi -0 -W -c main.c -o main.o
ld86 -d main.o -o main.com -T000

UPDATE: Tried SmallerC. Here again compiler is assuming SS = DS.

3. Smaller C [Source here]

    smlrc -seg16 -Wall main.c main.s
    nasm -f bin main.s -o main.com

The result is more or less the same in both the compilers. No compiler is explicitly specifying SS when reading from stack. The question is there a way to inform the compiler about the constraint, am I doing something wrong.

Arjob Mukherjee
  • 387
  • 1
  • 10
  • Comments are not for extended discussion; this conversation has been [moved to chat](https://chat.stackoverflow.com/rooms/197130/discussion-on-question-by-arjob-mukherjee-segmented-memory-model-in-c-cross-comp). – Bhargav Rao Jul 29 '19 at 00:23

1 Answers1

1

Have you tried the watcom or borland compilers? Watcom threw it over the fence /open sourced their suite ages ago. They had 16bit multi-model compilers. I don't know the state of borlands; but if you could find an image you can probably run it faster under qemu than it ever ran on a real machine.

They supported multiple memory models; the one you likely want is compact: 16 bit code pointers, 32 bit data pointers. There is a reference here: What the....

Even when you are done with that, depending what you try to do, you could end up with these weird things called segment fixups, which permit a limited relocation of programs within a 1mb address space. These get old fast.

To make life easier, you could use a tiny model (which generates true images); and make all external data referenced by explicit far pointers. This is a grotesque hack where you can end up with:

const char far const * const far *p;

not being a joke. The 80s and 90s saw a horse race between C and C++ for creating the most programmer hostile syntax. Clearly C++ won, but the ISO-C committee refuses to throw in the towel, making the world a bit more insane every few years.

A bit of advice: flip the machine to 32bit mode, and use some sane tools.

mevets
  • 10,070
  • 1
  • 21
  • 33
  • Thanks for your reply. I have tried Open Watcom and it works (with the -zu option). However I have decided to write the kernel and drivers all in assembly (like the original 86-DOS). I can write application programs in any 8086 C cross compiler, as the kernel will make sure SS = DS, when calling an application (Tiny model). This is what I have decided for now. I kind of understand now, that it will be a lot easier to write a protected mode OS, but you see, this is my first OS development work, and so I want it to be close to the original ones, plus I hope when I am old, I can brag about it :) – Arjob Mukherjee Aug 10 '19 at 15:42