This syntax is used to denote memory addressing, similar to C's array syntax (array[index]
). Your example is equivalent to computing the expression 0x404580 + (eax & 0x0F)
, treating it as an address, and taking one byte from this address. This suggests that the data at 0x404580
is an array of bytes (most likely 0x10
elements, based on the mask).
You can stop reading here if that answers your question.
If you go into Options > General and set "Show Opcode Bytes" to a non-zero value, you will see the actual values of the instruction bytes and be able to cross-reference them with the processor documentation to understand what's happening. This is usually not required, but it can be educational. For example:
mov dl, byte_404580[eax]
can be expressed as a sequence of bytes:
8A 14 05 80 45 40 00
Using Intel's Architecture Manual, Volume 2A, this can be decoded 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 these together, you get:
this instruction takes one byte from EAX + 0x404580
and moves it into the DL
register.
IDA uses this information to infer that there's an array of byte-sized values at 0x404580
, tries to name the location if it doesn't yet have a name, tries to resize the named item at the location to span the right amount of bytes (it doesn't necessarily know how many elements there are in this array, so it doesn't actually create an array there) and transforms the displayed expression to byte_404580[eax]
.