Understanding MOV x86 Syntax

I think this is an easy (maybe silly-easy) question to answer, but after almost two hours of work on Google, I crossed out. I'm sure my problem is that I just don't understand what the syntax is doing.

I am looking at some sort of parsed code in the IDA, and I have no idea what the following does:

mov dl, byte_404580[eax] 

If I go to byte_404580 , I find .data:00404580 byte_404580 db 69h , telling me that the value is 0x69 . But I do not see how it is used.

Let me indicate the context in which this code appears:

 mov eax, 0x73 ; Move hex 73 to EAX and eax, 0x0F ; Keep lower half of EAX mov dl, byte_404580[eax] ; MAGIC 

Given the assumption that EAX initially 0x73, I get DL = 0x76. I tried changing the EAX values ​​to find some pattern, but I could not figure out what was going on.

+4
source share
1 answer

This syntax is used to indicate memory addressing, similar to the syntax of an array C ( array[index] ). Your example is equivalent to evaluating the expression 0x404580 + (eax & 0x0F) , treating it as an address and taking one byte from that address. This suggests that the data in 0x404580 is an array of bytes (most likely 0x10 mask-based elements).

You can stop reading here if this answers your question.


If you go to "Parameters"> "General" and set "Show operation code bytes" to a non-zero value, you will see the actual values ​​of the command bytes and you can cross-reference them with the processor documentation to understand what is happening, usually this is not required, but can be educational. For instance:

 mov dl, byte_404580[eax] 

can be expressed as a sequence of bytes:

 8A 14 05 80 45 40 00 

Using the Intel Architecture Guide Volume 2A , you can decode as follows:

 8A - instruction opcode for MOV r8, r/m8 - determines the operand sizes 14 - the Mod R/M byte: | 00010100b Mod | 00 R/M | 100 Reg | 010 Mod R/M combination 00-100 is specified as "followed by the SIB byte". Reg 010 stands for register DL/DX/EDX, the destination operand. 05 - the SIB byte: | 00000101b Scale | 00 Index | 000 Base | 101 This combination is specified as [scaled value of EAX] + a 32 bit displacement. 80 45 40 00 - the displacement itself, 0x404580 

Adding them together, you get:

this command takes one byte from EAX + 0x404580 and moves it to the DL register.


The IDA uses this information to conclude that an array of byte size values ​​is 0x404580 , trying to specify a location if it does not already have a name, trying to resize a named element in a location to span the correct number of bytes (it does not necessarily know how many there are no elements in this array, so it does not actually create an array there) and converts the displayed expression to byte_404580[eax] .

+4
source

All Articles