Frederic Cambus

Blog · Git · Contact

Playing with DJGPP and GCC 10 on DOS

DOS Toolchains

I was recently amazed to discover that DJGPP was still being maintained, and had very recent versions of GCC and binutils available. I have not been doing any C programming on DOS in a very long time now, so I think the timing is right.

There is an installation program with an interface very similar to the good old Turbo Vision, which could be helpful in case one wants to install the full environment.

DJGPP Installer

DJGPP Installer

I'm only interested in using the C frontend for now, so I will do a manual installation.

We need the following components:

djdev205.zip    B  2,509,574  2015-10-18   DJGPP development kit 2.05
bnu2351b.zip    B  6,230,009  2021-01-16   GNU Binutils 2.35.1 binaries for DJGPP
gcc1030b.zip    B 42,027,946  2021-04-18   GNU GCC C compiler 10.3.0 for DJGPP V2
csdpmi7b.zip    B     71,339  2010-01-29   CS's DPMI Provider r7 Binaries

The development environment can be bootstrapped as follows:

mkdir -p ~/dos/djgpp
cd ~/dos/djgpp
wget https://www.delorie.com/pub/djgpp/current/v2/djdev205.zip
wget https://www.delorie.com/pub/djgpp/current/v2gnu/bnu2351b.zip
wget https://www.delorie.com/pub/djgpp/current/v2gnu/gcc1030b.zip
wget https://www.delorie.com/pub/djgpp/current/v2misc/csdpmi7b.zip
unzip djdev205.zip
unzip bnu2351b.zip
unzip gcc1030b.zip
unzip csdpmi7b.zip

When using FreeDOS, we need to add the following in AUTOEXEC.BAT:

set DJGPP=c:\djgpp\djgpp.env
set PATH=c:\djgpp\bin;%PATH%

Alternatively, when using DOSBox instead, we need the following in dosbox.conf:

[autoexec]
mount c ~/dos
path=c:\djgpp\bin
set DJGPP=c:\djgpp\djgpp.env
c:

Once we are done installing, this gives us GCC 10.3.0 and ld 2.35.1:

C:\>gcc --version
gcc.exe (GCC) 10.3.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

C:\>ld --version
GNU ld (GNU Binutils) 2.35.1
Copyright (C) 2020 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or (at your option) a later version.
This program has absolutely no warranty.

To verify things are working properly, let's create a simple test program:

#include <stdio.h>

int
main()
{
	puts("Hello World!");

	return 0;
}

We then build and run it:

C:\>gcc hello.c -o hello

C:\>hello
Hello World!

Here is the output of running file on the executable:

HELLO.EXE: MS-DOS executable, COFF for MS-DOS, DJGPP go32 DOS extender

Let's build only an object file:

C:\>gcc -c hello.c

We can run nm on it to list symbols:

C:\>nm hello.o
00000000 b .bss
00000000 N .comment
00000000 d .data
00000000 t .text
0000000d T _main
         U _puts

And run objdump to display its content:

C:\>objdump -s hello.o

HELLO.o:     file format coff-go32

Contents of section .text:
 0000 48656c6c 6f20576f 726c6421 008d4c24  Hello World!..L$
 0010 0483e4f0 ff71fc55 89e55183 ec0483ec  .....q.U..Q.....
 0020 0c680000 0000e8d5 ffffff83 c410b800  .h..............
 0030 0000008b 4dfc89ec 5d8d61fc c3909090  ....M...].a.....
Contents of section .comment:
 0000 4743433a 2028474e 55292031 302e332e  GCC: (GNU) 10.3.
 0010 30000000                             0...            

We can also use objdump to disassemble the object file:

C:\>objdump -d hello.o

HELLO.o:     file format coff-go32

Disassembly of section .text:

00000000 <.text>:
   0:	48                      dec    %eax
   1:	65 6c                   gs insb (%dx),%es:(%edi)
   3:	6c                      insb   (%dx),%es:(%edi)
   4:	6f                      outsl  %ds:(%esi),(%dx)
   5:	20 57 6f                and    %dl,0x6f(%edi)
   8:	72 6c                   jb     76 <_main+0x69>
   a:	64 21 00                and    %eax,%fs:(%eax)

0000000d <_main>:
   d:	8d 4c 24 04             lea    0x4(%esp),%ecx
  11:	83 e4 f0                and    $0xfffffff0,%esp
  14:	ff 71 fc                pushl  -0x4(%ecx)
  17:	55                      push   %ebp
  18:	89 e5                   mov    %esp,%ebp
  1a:	51                      push   %ecx
  1b:	83 ec 04                sub    $0x4,%esp
  1e:	83 ec 0c                sub    $0xc,%esp
  21:	68 00 00 00 00          push   $0x0
  26:	e8 d5 ff ff ff          call   0 <.text>
  2b:	83 c4 10                add    $0x10,%esp
  2e:	b8 00 00 00 00          mov    $0x0,%eax
  33:	8b 4d fc                mov    -0x4(%ebp),%ecx
  36:	89 ec                   mov    %ebp,%esp
  38:	5d                      pop    %ebp
  39:	8d 61 fc                lea    -0x4(%ecx),%esp
  3c:	c3                      ret
  3d:	90                      nop
  3e:	90                      nop
  3f:	90                      nop

Besides the C frontend, the Ada, C++, Fortran, Objective C, and Pascal frontends are also available. While I used DOSBox to test the development environment and prepare this article, I've since moved to FreeDOS which I'm running natively on my ASUS Eee PC. I'm currently having a lot of fun redoing some small character and color cycling effects in text mode.