3.29 Windows 16-bit
#include <stdio.h>
int array1[128];
int important_var1;
int important_var2;
int important_var3;
int important_var4;
int important_var5;
int main()
{
important_var1=1;
important_var2=2;
important_var3=3;
important_var4=4;
important_var5=5;
array1[0]=123;
array1[128]=456; // BUG
printf ("important_var1=%d\n", important_var1);
printf ("important_var2=%d\n", important_var2);
printf ("important_var3=%d\n", important_var3);
printf ("important_var4=%d\n", important_var4);
printf ("important_var5=%d\n", important_var5);
};
This is what this program printed in my case (non-optimized GCC 5.4 x86 on Linux):
important_var1=1
important_var2=456
important_var3=3
important_var4=4
important_var5=5
As it happens,important_var2has been placed by compiler right afterarray1[]:
Listing 3.128: objdump -x
0804a040 g O .bss 00000200 array1
...
0804a240 g O .bss 00000004 important_var2
0804a244 g O .bss 00000004 important_var4
...
0804a248 g O .bss 00000004 important_var1
0804a24c g O .bss 00000004 important_var3
0804a250 g O .bss 00000004 important_var5
Other compiler can arrange variables in another order, and another variable would be zapped. This is also
heisenbug(3.26.2 on page 643)—bug may appear or may left unnoticed depending on compiler version
and optimization switches.
It all variables and arrays are allocated in local stack, stack protection may be triggered, or may not.
However, Valgrind can find bugs like these.
3.29 Windows 16-bit
16-bit Windows programs are rare nowadays, but can be used in the cases of retrocomputing or dongle
hacking (8.5 on page 815).
16-bitWindowsversionswereupto3.11. 95/98/ME alsosupport16-bitcode, aswellasthe32-bitversions
of theWindows NTline. The 64-bit versions ofWindows NT line do not support 16-bit executable code at
all.
The code resembles MS-DOS’s one.
Executable files are of type NE-type (so-called “new executable”).