2

I've been working for my final project which is a disassembler for AMD64 instruction set, and i was trying to disassemble machine code by hand to understand it correctly. But i got stuck at a x87 instruction.

Machine code of instruction is: dd 04 c5 60 40 08 08...

I've checked AMD64 manual vol3, and it says DD is an x87 instruction and with the help of ModRM byte ,which is 0b00000100, my ModRM.reg field is 000 and with this information manual says this instructions meaning is "FLD mem64real". But since I've compiled this code for i386 target architecture i think that i shouldn't have 64 bit memory adress.

But the most interesting part is when i checked the binary with objdump, it says that this bytes are corresponds to fldl 0x8084060(,%eax,8) but i can't find any information about FLDL instruction nor how does objdump find this.

So my question is am i doing something wrong ?

How objdump think that instruction is FLDL but manual says its FLD ?

Target machine of binary is i386.

I use AMD64 manual volume 3 to check instructions

Version of objdump is GNU objdump (GNU Binutils for Debian) 2.26.1

Here is readelf output of binary

ELF Header
Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00 
Class:                             ELF32
Data:                              2's complement, little endian
Version:                           1 (current)
OS/ABI:                            UNIX - System V
ABI Version:                       0
Type:                              EXEC (Executable file)
Machine:                           Intel 80386
Version:                           0x1
Entry point address:               0x80482c0
Start of program headers:          52 (bytes into file)
Start of section headers:          3744 (bytes into file)
Flags:                             0x0
Size of this header:               52 (bytes)
Size of program headers:           32 (bytes)
Number of program headers:         8
Size of section headers:           40 (bytes)
Number of section headers:         31
Section header string table index: 28
1

fldl is just the AT&T syntax for the "FLD" instruction involving a long (4 bytes) register. This is equivalent to

fld     qword ptr [eax*8 + 8084060h]

in Intel syntax.

You could instruct objdump to emit Intel syntax with the -M intel flag.


While i386 does not support 64-bit addresses, it certain can read 64 bits out given an address. The "FLD m64fp" instruction reads 8 bytes from the input address (0x8084060 + eax*8 in this case), interprets it as a floating point number (a double), and then pushes it to the FPU register stack.

In this case 0x8084060 is likely an address to a global array of double and eax is an index to fetch a value out of the array.

  • But where did +eax*8 come from ? I know that DD means it's an x87 instruction and i use ModRM byte(04) to find it's fld and i think somehow c5 means eax*8. But i cannot find what is that C5 byte or which table i should look to find its values. – Efe Can Oct 10 '16 at 6:43
2

So this answer only focuses on the second question of @Efe: How is +eax*8 constructed.

You can determine the SIB-offsets with the following steps. We analyze the first two bytes 04 c5 of the whole instruction:

dd 04 c5 60 40 08 08

First, we only focus on the MOD-REG-R/M Byte (look here for details)

MOD-REG-R/M Byte = 04
--------------------------------------------------
04   0000 0100
MOD  00          Meaning: SIB with no displacement
REG  000         Meaning: eax (32-Bit)
R/M  100         Meaning: SIB with no displacement

Second, we analyze the SIB Byte of the instruction (look here for details). Scaled indexed addressing mode uses the second byte (namely, SIB byte) that follows the MOD-REG-R/M.

SIB Byte = C5
--------------------------------------------------
c5    1100 0101
Scale 11    Meaning: Index*8
Index 000   Meaning: eax register
Base  101   Meaning: Displacement only

The combination of MOD and Base lead to (look here for details)

MOD = 00 and BASE field = 101:
--------------------------------------------------
disp + eax*n
  • I've totally got distracted with mem64real keyword in manual and forgot about that we determine memory address starting with ModRM.r/m field. Thanks for reminding me that – Efe Can Oct 10 '16 at 17:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.