I'm trying to copy a section of assembly language into a C program, but I'm having issues making the code translate because the source is in Intel format and the C compiler I'm using (MinGW through Bloodshed Dev C++ on Windows) accepts only AT&T syntax.  I've gotten everything but a single instruction to work flawlessly (disassembling the two programs shows my code is identical, line for line until the problematic section).  The instruction that is giving me trouble is "fild":

push    edx
push    eax
fild qword ptr

The code that I put in my C program is:

__asm("push %edx");
__asm("push %eax");
__asm("fild (%esp)");

The issue is that the two instructions load different values into the ST0 register (verified in a debugger).  In both cases, eax and edx have the same values before pushing (eax = 0xFE8BC1A0, edx = 0x00000000, verified in a debugger). In the assembly program, the value 4.270571936e9 is loaded into ST0, but in my C program it's very different: -1.5968e4. I looked at the instructions (in Intel format) generated by my program by doing a disassembly:

push    edx
push    eax
fild    word ptr

So it seems that it's trying to act on a word instead of a qword. But, nothing I try fixes the problem.  I read that you can append certain letters to an instruction in AT&T format to force the instruction to act on certain sizes.  So, I appended some letters to "fild" to hopefully make it act on a qword.  Appending "L" loaded -2.439536e7 into ST0, while appending "Q" loaded 4.270571936e9 into ST0, and appending "S" loaded -1.5968e4.  I tried every letter of the alphabet as a suffix, but those were the only that worked ("B" and "W" generated messages indicating they are valid, but not for this instruction for some reason).

I've been tearing my hair out over this because nothing I do seems to fix the problem.  If anyone has any ideas or suggestions about the issue I would love to hear about it!
Posted on 2010-10-23 20:38:19 by skunkiller3
Start by checking your disassembly in another disassembler (you did not mention which you used, and not all disassemblers are equal).

There's a good chance that your code DID assemble correctly, but that the disassembler is unaware of "size prefixed" instructions.

Posted on 2010-10-23 21:48:12 by Homer
In the assembly program, the value 4.270571936e9 is loaded into ST0
while appending "Q" loaded 4.270571936e9 into ST0

Isn't that what you were trying to do??
Posted on 2010-10-23 22:12:50 by Raymond
Shoot, you're right Raymond. Well, that solves this issue. "fildq" loads the correct value.  I must have additional errors later in my program when I print the value out later, because the values are different there. But, that's an issue for another day and another forum  8)

By the way, Homer.  I neglected to mention that the first section of code above (the source of my code translation effort) is in fact a disassembly.  I'm reversing a CrackMe program for the fun of it.  I'm using IDApro, by the way, for both disassembly and debug. The disassembler does show that in the original program it's a QWORD and in my C program it's a regular word.

Thanks for your help, both of you!
Posted on 2010-10-23 22:32:38 by skunkiller3