Looking for 16-bit x86 compiler
Asked Answered
T

10

18

I am working on an embedded systems project and have run into an issue of the compiler being programatically embedded in the Paradigm C++ IDE. I would like to be able to automate building.

The processor is the AMD186ES. I am not working with the OS - just baremetal stuff. I need to generate real-mode 16-bit 8086 machine code from C++.

My googling indicates that G++ can build such code.

My questions are:

Can g++ be configured to build this machine code?

Are there other C++ compilers that can do it as well?

Tillion answered 22/10, 2008 at 22:29 Comment(1)
see Is there a C compiler that targets the 8086?Gertrudgertruda
G
8

I am currently using gnu as (part of binutils and the assembler used for gcc) and I have successfully been assembling 16bit assembly code with the following:

as <file>
ld --oformat binary -Ttext 0x0 -e start <file>

with my assembly files starting out with:

.code16
.globl start
.text
start:

since its plain binary omitting the lines,

.globl start
start:

will simply yield an warning, even though flat binaries need no entry point.


something I learned the hard way;

-Ttext 0x0

is critical, otherwise the .text segment is pushed outside of 16bit addressing range (don't ask me why)

I am personally still learning assembly, so this is just my way, not necessarily the best way.


EDIT: If you are writing boot code, you should change

-Ttext 0x0

to

-Ttext 0x7c00

this will offset your memory addresses by 0x7c00 since boot code is usually loaded at 0x7c00 by the BIOS.

Glabrous answered 10/10, 2012 at 23:5 Comment(5)
Interesting. Does/can this yield elf files, a.out files, or do they get stripped down to a no-OS binary?Tillion
@paulNathan ld --oformat binary -Ttext 0x0 -e start <file> strips it down to a no-os binary; However, this bases memory addresses at 0x0000 if you are writing boot code, change -Ttext 0x0000 to -Ttext 0x7c00 as this is where boot code is loaded in memory.Glabrous
I have tapped this answer as the answer, since I think any shop which cares about this stuff can figure out the c++ -> asm path with gcc pretty easily.Tillion
@PaulNathan - did you manage to complete that path? A little research indicates that GCC's lack of understanding of segments/far pointers may be a real obstacle for anything which needs an address space larger than 64K.Truncheon
@ChrisStratton: I asked the question 5 years ago. Due to external considerations, this line of work was dropped in '09. I haven't been back since. Sorry. However, I would be surprised if gcc 2.9 didn't get segmented memory.Tillion
H
11

Your best bet is probably OpenWatcom, which includes a C++ compiler. Back in the early-to-mid 90s, I believe this was the best C/C++ compiler around. It was open-sourced a few years ago.

Hypersensitize answered 22/10, 2008 at 22:36 Comment(2)
IIRC, Watcom spits out weird .objs. If that's not true of OpenWatcom, it's probably your best choice due to all the control it gives you over code generationRede
@JimR: Yeah, I think MS's >16-bit tools are essentially alone in using COFF/**ar** for .obj and .lib files; the other DOS-family tools seem to generally either use OMF (Borland, Watcom, Digital Mars, MS for 16-bit code, ...), or name their files something else, like .o and .a (GNU toolchain, and presumably any others hailing from *nix-land). The NT project seems to have picked up this *nix technology (COFF objects and ar archives) back when they were cross-developing NT from *nix hosts, but kept the traditional DOS file extensions.Tittle
G
8

I am currently using gnu as (part of binutils and the assembler used for gcc) and I have successfully been assembling 16bit assembly code with the following:

as <file>
ld --oformat binary -Ttext 0x0 -e start <file>

with my assembly files starting out with:

.code16
.globl start
.text
start:

since its plain binary omitting the lines,

.globl start
start:

will simply yield an warning, even though flat binaries need no entry point.


something I learned the hard way;

-Ttext 0x0

is critical, otherwise the .text segment is pushed outside of 16bit addressing range (don't ask me why)

I am personally still learning assembly, so this is just my way, not necessarily the best way.


EDIT: If you are writing boot code, you should change

-Ttext 0x0

to

-Ttext 0x7c00

this will offset your memory addresses by 0x7c00 since boot code is usually loaded at 0x7c00 by the BIOS.

Glabrous answered 10/10, 2012 at 23:5 Comment(5)
Interesting. Does/can this yield elf files, a.out files, or do they get stripped down to a no-OS binary?Tillion
@paulNathan ld --oformat binary -Ttext 0x0 -e start <file> strips it down to a no-os binary; However, this bases memory addresses at 0x0000 if you are writing boot code, change -Ttext 0x0000 to -Ttext 0x7c00 as this is where boot code is loaded in memory.Glabrous
I have tapped this answer as the answer, since I think any shop which cares about this stuff can figure out the c++ -> asm path with gcc pretty easily.Tillion
@PaulNathan - did you manage to complete that path? A little research indicates that GCC's lack of understanding of segments/far pointers may be a real obstacle for anything which needs an address space larger than 64K.Truncheon
@ChrisStratton: I asked the question 5 years ago. Due to external considerations, this line of work was dropped in '09. I haven't been back since. Sorry. However, I would be surprised if gcc 2.9 didn't get segmented memory.Tillion
C
7

Doesn't your chip vendor (AMD, I guess) have any pointers to compilers for the chip?

If not, you may be able to use some 16-bit DOS compilers - but you'll have several potential big problems:

  1. getting a library for the compiler that is not dependent on the BIOS or MS-DOS
  2. debugging
  3. linkers for embedded systems usually have specific support for locating code in specific memory regions. That's not usually included in compilers for DOS, but you may be able to find some sort of linker/locator that'll do the trick for you.

A couple of compilers that are still supported and generate 16-bit code are:

Chauffer answered 22/10, 2008 at 22:42 Comment(0)
C
7

This google search shows a series of links for setting gcc up as a cross compiler. To get it to target something other than a standard ELF binary you can frig the output. This link discusses excluding the standard libraries and customising the output format. You may have to do some fiddling to get it to work.

As an alternative openwatcom.org has an open-source version of the Watcom C compiler, which might also be able to do what you want.

Cholecystotomy answered 22/10, 2008 at 22:42 Comment(1)
wonderful link (muppetlabs.com/~breadbox/software/tiny/teensy.html) seems like something I would write. inc %upvoteGlabrous
V
6

Take a look at bcc, which is a 16-bit x86 C compiler. For example, there are also Debian packages for it.

Valediction answered 22/10, 2008 at 22:48 Comment(0)
G
6

There's a patch for GCC 4.3: New back end ia16: 16-bit Intel x86

And here's an update for it. Note that it probably doesn't work very well, for example, the updated post says: "Constructors and destructors are now supported, but for some reason they only work on the elks configuration."

This Docker container has a build of it: https://registry.hub.docker.com/u/ysangkok/ia16-gcc-rask

I didn't manage to make DOS binaries yet: How do I assemble GAS assembly and link it with the Open Watcom C library?

Gertrudgertruda answered 1/5, 2013 at 21:3 Comment(1)
Did GCC's ia16 backend ever get anywhere? This is different from x86 gcc's -m16, right? That just puts a .code16gcc at the top of output assembly, but still uses 32-bit int and 32-bit addressing modes so will definitely only run on a 386+, not 8086.Himmler
G
4

The most recent as per 2014 is Dev86.

Gertrudgertruda answered 24/8, 2014 at 16:32 Comment(1)
But is 8086 too old? Support for 80186, 80286 or higher is better. They have some more useful instructionsShinshina
D
2

Not sure but I think old version of borland c++ was able to do that. you can download version 5.5 t : here good luck

Darceydarci answered 22/10, 2008 at 22:49 Comment(2)
The thing is the OP is "not working with the OS - just baremetal stuff", and I'm not sure if Borland C or Turbo C can emit code bare code that's not for MSDOS or notShinshina
Yes, Borland C and C++ emit code that is usable on baremetal 8086 and 80186. Paradigm licensed and improved the Borland compilers and packages this with assorted support including libraries and Paradigm Locate (required to map linker output into loadable hex image).Loadstar
T
1

80186 free C compiler:

http://coding.derkeiler.com/Archive/General/comp.arch.embedded/2005-09/msg01063.html

Tarriance answered 25/10, 2008 at 12:16 Comment(0)
C
0

It has been a long time since I've looked at Paradigm stuff (are they still around?) -- are you sure they don't have command-line equivalents for the compiler? My recollection is that they were built on top of Borland's compiler toolchain... So maybe an old copy of Borland compilers might do the trick?

-- Ah, looking a little futher, I find that Paradigm is still around (www.devtools.com) selling X86 tools. (Must be a cash cow!)

Their professional product includes scripting... Depending on the amount of work you plan to do, it just might be worth it to bite the bullet and buy their full offering...

Good luck.

Chellean answered 22/10, 2008 at 22:50 Comment(1)
I was given the "lite" version with my embedded board. Somehow Paradigm embedded the compiler into the IDE executable.Tillion

© 2022 - 2024 — McMap. All rights reserved.