tkchia / gcc-ia16

Fork of Lambertsen & Jenner (& al.)'s IA-16 (Intel 16-bit x86) port of GNU compilers ― added far pointers & more • use https://github.com/tkchia/build-ia16 to build • Ubuntu binaries at https://launchpad.net/%7Etkchia/+archive/ubuntu/build-ia16/ • DJGPP/MS-DOS binaries at https://gitlab.com/tkchia/build-ia16/-/releases • mirror of https://gitlab.com/tkchia/gcc-ia16

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Incorrectly writing offset to DS in specific nested for loops with optimization enabled

asiekierka opened this issue · comments

I did not manage to write a reproduction that works as a DOS .EXE - no matter what I did, the register allocations arranged themselves differently, not triggering the bug - so I'm attaching the whole main.i file: https://asie.pl/files/gcc-ia16-20230905-193115.i

However, the assembly generation error is thankfully obvious when pointed out: When compiling the above file with ia16-elf-gcc -O2 -mcmodel=medium -c -o main.o gcc-ia16-20230905-193115.i, the following ASM sequence gets emitted:

 163:	31 ff                	xor    %di,%di
 165:	89 f8                	mov    %di,%ax
 167:	ba 00 00             	mov    $0x0,%dx
			168: R_386_16	SwanOffset
 16a:	8e da                	mov    %dx,%ds
 16c:	e9 de fe             	jmp    4d <main+0x4d>

Of particular note is the mov %dx,%ds sequence, which writes a pointer offset into %ds. %ds is not fixed later, leading to later-executed register->memory writes, such as:

  6f:	88 44 01             	mov    %al,0x1(%si)

to write to an incorrect memory location.

This issue does not occur when the bitfield access to sprites[].tile/palette is replaced with a non-bitfield access, but it's possible to trigger an adjacent issue in this scenario.