As said by commenters Michael and Ped7g already, you have use offsets. Let me explain:
x86 stores numbers in little-endian format, meaning that the lowest-order bytes are stored first in memory. A little example: Assuming you have the value 0x12345678
in eax
, and you execute this instruction:
mov [addr], eax
...then the memory at address addr
will look like this:
78 56 34 12
In your example, you have a value in dx:ax
which is a shorthand for "have a value's upper 16 bits in dx
and its lower 16 bits in ax
". Assuming the value is, again, 0x12345678
, so you have 0x1234
in dx
and 0x5678
in ax
, then you need two move instructions:
mov [addr], ax // Memory now looks like this: 78 56
mov [addr+2], dx // Memory now looks like this: 78 56 34 12
The +2
comes from the fact that ax
is a 16-bit register, i.e. it uses up two bytes when stored in memory, so since you want to put dx
right after it, you need to increase the address by 2
.
Same thing for 64-bit values in edx
and eax
, with an offset 4
. Let's assume you have the value 0x1234567890ABCDEF
split to 0x12345678
in edx
and 0x90ABCDEF
in eax
, then it would look like this:
mov [addr], eax // Memory now looks like this: EF CD AB 90
mov [addr+4], edx // Memory now looks like this: EF CD AB 90 78 56 34 12
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…