On Wed, Apr 08, 2015 at 10:32:23PM -0400, Kevin O'Connor wrote:
The problem is not with leal in hand written assembler - the problem is with leal instructions generated by gcc. To see the assembler gcc produces for the vgabios one can look at out/vgaccode16.raw.s . Or, alternatively, one can run: objdump -m i386 -M i8086 -M suffix -ldr out/vgarom.o
We've fixed up gcc assembler in the past (see scripts/vgafixup.py) to work around x86emu. However, the leal instruction seems painful to patch out - particularly so when %esp is one of the registers read or written in the leal instruction. If anyone wants to take a stab at a workaround, feel free to submit a patch.
It occurred to me that it might be possible to replace the leal instruction with a function call. The generic form of leal is:
leal $offset(%base, %index, $scale), %destination
which does:
%destination = $offset + %base + (%index * $scale)
if the above is found in the gcc assembler it could be replaced with something like:
pushl %base pushl %index pushl $offset pushl $scale callw fake_leal popl %destination
(The fake_leal assembler function that performs the actual calculation would also need to be written.) The above wouldn't work if %index is %esp, but I don't think that would happen in practice.
I'm not going to tackle the above right now, but maybe someone else is interested in attempting it. A word of caution though - I know leal doesn't work in very old x86emu versions, but it's unclear if any other gcc produced instructions are also broken. The leal instruction might just be one of many instructions that don't work.
-Kevin