Monday, 6 May 2019

gcc cross-compiler for 16-bit x86 processors

This may be of interest to embedded developers for the ancient 16-bit Intel x86 processors.

A port of a gcc cross-compiler for the ia16 architecture has existed for some years but there is now a developer (TK Chia) maintaining this port and trying to add support for more features, like far pointers. The source is in github but there is also an Ubuntu PPA for bionic and xenial for both i386 and amd64 architecture hosts.

I don't have Ubuntu but I do have a VM instance of AntiX 17 (32-bit) so being a lazy person I decided to see if I could just install the deb packages directly on Debian. I found that the bionic packages were too new for AntiX but the xenial packages worked. I found that these were the minimum packages I needed to not have any unsatisfied dependencies:

binutils-ia16-elf
gcc-ia16-elf
libi86-ia16-elf
libnewlib-ia16-elf


I compiled the standard hello.c program.

$ cat hello.c
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char **argv)
{
       printf("Hello world\n");
       exit(0);
}

$ ia16-elf-gcc -S hello.c

and got:

$ cat hello.s
        .arch i8086,jumps
       .code16
       .att_syntax prefix
#NO_APP
       .section        .rodata
.LC0:
       .string "Hello world"
       .text
       .global main
       .type   main, @function
main:
       pushw   %bp
       movw    %sp,    %bp
       movw    $.LC0,  %ax
       pushw   %ax
       pushw   %ss
       popw    %ds
       call    puts
       addw    $2,     %sp
       movw    $0,     %ax
       pushw   %ax
       pushw   %ss
       popw    %ds
       call    exit
       .size   main, .-main
       .ident  "GCC: (GNU) 6.3.0"


Compiling to a binary with:

$ ia86-elf-gcc -o hello hello.c

worked, but the binary isn't executable on Linux. It is:

$ file hello
hello: COM executable for DOS

I didn't explore any further as I don't have a current need for this compiler so I don't know what the library routine did for putchar.

You'd have to tweak the linker and libraries to generate code for an embedded target. But this looks promising.

3 comments:

  1. You are trying to execute this newly generated 16 bit executable on 32 or 64 bit OS? It should work on 16 bit OS such as ELKS Linux.

    ReplyDelete
  2. I know about ELKS, I followed it decades ago. But I'm more interested in building embedded binaries than running it on an OS.

    ReplyDelete
  3. I want to be able to turn on an IBM 5150 with no disk drives, load a binary from a tape, and have it run (with no DOS, just LOAD using the ROM BASIC and go, just like the PET, TRS80, Apple2). Is there a Windows build of this ia16 compiler?

    ReplyDelete