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.

1
  • Comments are not for extended discussion; this conversation has been moved to chat. Commented Jul 29, 2019 at 0:23

1 Answer 1

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.

Sign up to request clarification or add additional context in comments.

1 Comment

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 :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.