Понимание синтаксиса x86 MOV

Я думаю, что на этот вопрос легко (возможно, до глупости легко) ответить, но после почти двух часов гугления я вычеркнул его. Я почти уверен, что моя проблема в том, что я просто не понимаю, что делает синтаксис.

Я смотрю на какой-то дизассемблированный код в IDA и понятия не имею, что делает следующее:

mov dl, byte_404580[eax]

Если я перейду к byte_404580, я обнаружу, что .data:00404580 byte_404580 db 69h говорит мне, что значение равно 0x69. Но я не вижу, как это используется.

Позвольте мне предоставить контекст, в котором появляется этот код:

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

С приведенным выше предположением, что EAX изначально равно 0x73, я получаю DL=0x76. Я пробовал варьировать значения EAX, чтобы найти закономерность, но не смог понять, что происходит.


person CatShoes    schedule 27.08.2012    source источник
comment
Какое значение в byte_404583?   -  person slavemaster    schedule 27.08.2012
comment
Это эквивалентно вычислению выражения 0x404580 + (eax & 0x0F), обработке его как адреса и взятию одного байта из этого адреса. Это говорит о том, что данные в 0x404580 представляют собой массив байтов (скорее всего, 0x10 элементов, исходя из маски), а не один байт. Сравните с 2["hello"] == "hello"[2] C.   -  person DCoder    schedule 27.08.2012
comment
@slavemaster byte_404583=0x76   -  person CatShoes    schedule 27.08.2012
comment
Я думаю, что сделал опечатку в ОП, когда сказал, что DL=ox65. Я почти уверен, что искал неправильное значение EAX.   -  person CatShoes    schedule 27.08.2012
comment
@DCoder Спасибо за это объяснение. Глядя на данные в 0x404580, это массив байтов (16 байтов, если быть точным). Затем наименее значимая часть того, что я инициализирую EAX, дает мне смещение в этом массиве байтов, чтобы получить значение для DL. Я ценю это. Если вы напишите это как ответ, я отмечу это для вас.   -  person CatShoes    schedule 27.08.2012


Ответы (1)


Этот синтаксис используется для обозначения адресации памяти, аналогично синтаксису массива C (array[index]). Ваш пример эквивалентен вычислению выражения 0x404580 + (eax & 0x0F), обработке его как адреса и взятию одного байта из этого адреса. Это говорит о том, что данные в 0x404580 представляют собой массив байтов (скорее всего 0x10 элементов, исходя из маски).

Вы можете перестать читать здесь, если это ответит на ваш вопрос.


Если вы перейдете в «Параметры»> «Общие» и установите «Показать байты кода операции» на ненулевое значение, вы увидите фактические значения байтов инструкций и сможете сопоставить их с документацией процессора, чтобы понять, что происходит. Обычно это не требуется, но может быть образовательным. Например:

mov dl, byte_404580[eax]

можно представить в виде последовательности байтов:

8A 14 05 80 45 40 00

Используя Руководство по архитектуре Intel, том 2A, это можно расшифровать следующим образом:

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

Сложив их вместе, вы получите:

эта инструкция берет один байт из EAX + 0x404580 и перемещает его в регистр DL.


IDA использует эту информацию, чтобы сделать вывод о том, что в 0x404580 есть массив значений размером в байт, пытается назвать местоположение, если оно еще не имеет имени, пытается изменить размер именованного элемента в местоположении, чтобы охватить нужное количество байтов ( он не обязательно знает, сколько элементов в этом массиве, поэтому фактически не создает там массив) и преобразует отображаемое выражение в byte_404580[eax].

person DCoder    schedule 27.08.2012