Хорошо, таким образом, у меня есть эта строка в моем блоке
MOV EAX, DWORD PTR DS:[ESI]
где ESI 00402050
(ASCII, "123456789012")
После этой инструкции: EAX = 34333231
Что действительно произошло здесь? Как это значение вычисляется, и почему?
Где я мог получить некоторую хорошую ссылку на такого рода вещи?
Регистры в квадратных скобках, например [ESI]
, являются указателями с разыменованием. Указанная вами инструкция перемещает DWORD
(32-битное / 4-байтовое значение) в ячейку памяти, указанную ESI
, в регистр EAX
. В вашем случае ячейка памяти 00402050
, читаемая как DWORD
, содержит 34333231
.
Написано на псевдо-C:
DWORD EAX; /* Declaring the registers as we find them in silico */
DWORD ESI;
ESI = 0x00402050; /* Set up your initial conditions for ESI */
EAX = *((DWORD *)ESI); /* mov EAX, DWORD PTR [ESI] */
/* ^ ^ ^^^^^^^ */
/* | | | */
/* | | +----------- From "DWORD PTR" we get "DWORD *" in C. */
/* | | */
/* | +----------------- The C dereferencing operator * replaces []. */
/* | */
/* +------------------- The C assignment operator = replaces mov opcode. */
В вашем случае неверно, что 0x00402050
«равно» строке «1234567890»
- скорее, это указывает на память который содержит эту строку.
Полученное значение 0x34333231
состоит из значений ASCII для цифр «1234»
, которые являются первыми четырьмя байтами (т. Е. Первым DWORD
) строки. Они появляются в обратном порядке, потому что архитектура Intel имеет "прямой порядок байтов" в байтовом представлении DWORD
в памяти.
В вашем примере в это время инструкция mov
загружает символы ASCII, как если бы они были четырьмя байтами значения unsigned long
, тогда как на самом деле они представляют собой строку из одиночных -байтовые символы.