Real mode MS-DOS programs
Anders Blomdell (anders.blomdell@control.lth.se)
Wed, 1 Oct 1997 09:25:12 +0200
Is it possible to convince gcc (or djgpp) to produce real mode (as opposed
to protected mode) programs for MS-DOS? Alternatively I would be very
grateful if I could get some guidance on how to correct my problem stated
below.
Regards
Anders Blomdell
------------------------------------------------------------------------------
Anders Blomdell
Department of Automatic Control Email: anders.blomdell@control.lth.se
Lund Institute of Technology Phone: +46 46 222 4625
Box 118, S-221 00 Lund, Sweden Fax: +46 46 138118
If you are not interested in MS-DOS segmentation issues, please stop
reading here.
Scenario:
In order to automagically configure all our Intel machines with Windows NT,
I need a program that finds out which ethernet adapter a certain machine is
equipped with. In order to do that, I borrowed some of the PCI-BIOS code
from the Linux system, which worked fine on our older Pentium systems, but
fails miserably on the latest batch of computers (Phoenix BIOS 4.0 Release
6.0).
The problem is that the following call (to 0xfd9df)
__asm__("lcall (%%edi)\n\t"
"jc 1f\n\t"
"xor %%ah, %%ah\n"
"1:\tshl $8, %%eax\n\t"
"movw %%bx, %%ax"
: "=d" (signature),
"=a" (pack)
: "1" (PCIBIOS_PCI_BIOS_PRESENT),
"D" (&pci_indirect)
: "bx", "cx");
leads to the following segmentation fault
Exiting due to signal SIGSEGV
General Protection Fault at eip=000fda02
eax=00000004 ebx=0004f080 ecx=00000000 edx=000000d7 esi=000fd9a3 edi=00009ca0
ebp=0004d424 esp=0004d420 program=E:\MSDOS\DETECT.EXE
cs: sel=00cf base=00000000 limit=000fffff
ds: sel=00af base=10000000 limit=0005ffff
es: sel=00af base=10000000 limit=0005ffff
fs: sel=0087 base=0002e150 limit=0000ffff
gs: sel=00bf base=00000000 limit=ffffffff
ss: sel=00af base=10000000 limit=0005ffff
after executing approximately 20 instructions of the BIOS code below:
fd9df: 60 pusha
fd9e0: 8b ec movl %esp,%ebp
fd9e2: f9 stc
fd9e3: 9c pushf
fd9e4: c6 45 1d 81 movb $0x81,0x1d(%ebp)
fd9e8: 3c 0f cmpb $0xf,%al
fd9ea: 77 29 ja fda15 <_x+fd9c9>
fd9ec: 8d 35 bf 01 00 leal 0x1bf,%esi
fd9f1: 00
fd9f2: e8 9e 03 00 00 call fdd95 <_x+fdd49>
fd9f7: 25 ff 00 00 00 andl $0xff,%eax
fd9fc: 66 c1 e0 02 shlw $0x2,%ax
fda00: 03 f0 addl %eax,%esi # Error occurs here
fda02: 8b 36 movl (%esi),%esi
fda04: e8 8c 03 00 00 call fdd95 <_x+fdd49>
fda09: ff d6 call *%esi
fda0b: 72 08 jb fda15 <_x+fd9c9>
fda0d: c6 45 1d 00 movb $0x0,0x1d(%ebp)
...
fdd95: e8 01 00 00 00 call fdd9b <_x+fdd4f>
fdd9a: c3 ret
fdd9b: 03 34 24 addl (%esp,1),%esi
fdd9e: 81 ee ba 05 00 subl $0x5ba,%esi
fdda3: 00
fdda4: c3 ret
My guess (I'm not very good at the Intel segmented architecture) is that
some of the segment descriptors should be modified prior to the call, but
the only results I have achieved so far, is to move the segmentation fault
to the call itself...