I can't understand why I receive an Illegal Instruction with a piece of code implemented as assembly inside C program. I explain a bit.
I have a value at a specific address and I want to move that value into EAX x86 register, something like
MOV EAX, [address]
In the C code I have the pointer for that address. I have prepared the binary code of this instruction in this way:
MOV OpCode:
7 6 5 4 3 2 1 0
|_|_|_|_|_|_|D|S|
D = 1 --> I want REG as destination
S = 1 --> 32 bit operand
D S
--> |1|0|0|0|1|0|1|1| --> 0x89
Mod R/M:
7 6 5 4 3 2 1 0
|_|_|_|_|_|_|_|_|
--> MOD = |7|6| bits
--> REG = |5|4|3| bits
--> R/M = |2|1|0| bits
MOD = Indirect --> |0|0|
REG = EAX = 0 --> |0|0|0|
Address is not in a register and I want to move memory data to EAX register. I have the value of the memory location, so:
R/M = |1|1|0| --> direct
--> |0|0|0|0|0|1|1|0| --> 0x06
Address = [byte0] [byte1] [byte2] [byte3]
--> 0x8b 0x06 [byte3] [byte2] [byte1] [byte0] 0xc3
In this way I obtain an illegal instruction but I don't understand why. If I use R/M = 101 I obtain 0x8b 0x05 [byte3] [byte2] [byte1] [byte0] 0xc3 and all work fine.
So, where is the problem? Is there someone that could explain the MOD=00, R/M=110 usage from this table? direct???
MOD=00, R/M=101 works but in the table I see memory location calculated from DI but I have a direct memory location...
Note: Code compiled on Ubuntu 20.04 (64 bit) with -m32 gcc switch