"Hello World" crashes on i8086/msdos when compiled with every model except Huge.
Summary
Trying to build the simplest possible "Hello World" example with i8086/msdos target using every memory model produced crashing binaries, except -WmHuge.
System Information
- Operating system: MS-DOS 5.0 (the default reported version) on DOSBox-X and DOSBox-staging
- Processor architecture: 80x86 (defaults to 80486 or Pentium)
-
Compiler version: trunk, latest
x86_64/linuxcross-compiler snapshot from https://downloads.freepascal.org/fpc/snapshot/trunk/i8086-msdos/ - Device: DOSBox emulator
Steps to reproduce
I created a test script which produces binaries replicating the reported issue:
#!/usr/bin/env bash
cat << EOF >hello.pas
program hello;
begin
System.WriteLn('Hello World!');
end.
EOF
rm -rf "out/" && mkdir -p "out/"
for model in "small" "tiny" "medium" "compact" "large" "huge" ; do
url_suffix="-$model"
if [ "$model" == "small" ]; then
url_suffix="" # consistency on CDN could be better, duh
fi
rm -rf "out-$model/" "fpc-$model/"
mkdir -p "fpc-$model/"
mkdir -p "out-$model/"
cd "fpc-$model/"
echo "Downloading FPC for model: $model"
wget -q "https://downloads.freepascal.org/fpc/snapshot/trunk/i8086-msdos/fpc-3.3.1.msdos.built.on.x86_64-linux${url_suffix}.tar.gz"
tar xf fpc-*.tar.gz
rm fpc-*.tar.gz
echo "Building for model: $model"
./bin/x86_64-linux/ppcross8086 \
-XX -Tmsdos -Mtp -Wm${model} \
-Fu'./units/i8086-msdos/*' \
-Fu'./units/msdos/*' \
-o../out-$model/hello.exe \
../hello.pas
if [ ! -e ../out-$model/hello.exe ]; then
echo "Building with memory model $model failed to produce an executable."
else
mv ../out-$model/hello.exe ../out/$model.exe
fi
rm -rf ../out-$model/
echo
cd ..
done
echo "Done. Try running 'dosbox-x --debug ./out/hello.<model>.exe' to check each executable manually."
What is the current bug behavior?
These vary between models:
-
Tiny: Compiler throws
Internal error 202102001 - Compact: Does nothing and exits to DOS
- Small: Most spectacular - long beep and puts lots of trashed random ASCII chars on screen, then exits.
-
Medium: Throws INT 6h (
Invalid Opcode) in constant loop, reported by DOSBox-Xstderr - Large: Same as Medium
-
Huge: Just works, prints
Hello World!and exits.
What is the expected (correct) behavior?
Just print Hello World! and exit the program.
Relevant logs and/or screenshots
There are not many, -va on Tiny doesn't print anything suspicious, the full error line is: hello.pas(5,1) Fatal: Internal error 202102001
Possible fixes
As I've encountered this during my Mario & Luigi TP->FPC porting project I found various issues which might be related to data/segments aligning or pointer arithmetic. Seems like every of them has the same root cause, including this. But for the sake of clarity, I wanted to minimize it down to reproducible legacy-free example.
Who would expect that example would be a "Hello World"?
On the other hand, using System.WriteLn() in the game mentioned above seems to work (before i initialize VGA, of course) as I was using it for "print debugging" on initial stage.