Как работает инструкция по сборке MOVSX?

Как работает инструкция по сборке MOVSX в следующем примере:

MOVSX ECX,BYTE PTR DS:[EDX]

В этом случае вот состояние регистров:

ECX = 0000000F   
EDX = 0012FD9F 

Из того, что я думал, он берет последние байты [EDX] = 9F, перемещает их в ECX, а затем знак расширяет их, чтобы они соответствовали 16 битам = 0000009F. Однако фактический результат - 00000016. Может кто-нибудь объяснить, в чем я ошибаюсь?


person Abundance    schedule 21.10.2015    source источник
comment
Старый вопрос и ответ помогут ниже, но для людей, читающих это сейчас, вы были не совсем правы здесь со своим расширением знака (если это был правильный байт для использования). 0x9F = 1001 1111 и, следовательно, ваш бит расширения знака должен быть с битом «1», а не с битом «0».   -  person Code Doggo    schedule 02.04.2018


Ответы (2)


Это частично верно. Тем не мение:

BYTE PTR DS:[EDX] получает байт, расположенный по адресу, хранящемуся в EDX. Этот байт копируется в ECX в младший байт, а оставшаяся часть заполняется знаком байта.

Для вашего неожиданного результата это означает, что по адресу памяти 1 0x12FD9F находится байт 0x16.


Примечания:

  • префикс переопределения сегмента DS: здесь не требуется. [EDX] автоматически ссылается на DS.

1 "адрес памяти" здесь означает виртуальную или физическую память.

person cadaniluk    schedule 21.10.2015

Многие инструкции Intel / AMD x86 доступны в формате "modrm" - они имеют два операнда, один из которых должен быть регистром, другой может быть регистром или ссылкой на память, адрес которой определяется байтом modrm параметра кодирование инструкции и, возможно, последующие байты инструкции, такие как sib (масштабированный байт индекса) и непосредственное смещение константы / памяти. А также по возможному байту префикса сегмента.

Обычно это инструкции reg, reg / mem в форме

   rsrcdst += rsrc
or
   rsrcdst += Memory[ ... addressessing mode ...]

Но ассемблерный код x86 не имеет отдельных кодов операций / мнемоники инструкций для форм reg, reg и reg, mem этих инструкций. Является ли операнд регистром или ячейкой памяти, указывается в ассемблере синтаксисом ассемблера.

В этом случае ваш ассемблерный код

MOVSX ECX, BYTE PTR DS: [EDX]

Код операции инструкции - MOVSX.

Операнд назначения - регистр ECX.

Исходный операнд - «BYTE PTR DS: [EDX]». На то, что это ссылка на память, указывают несколько вещей: (1) квадратные скобки вокруг «[EDX]» - квадратные скобки являются сокращением для памяти [... адрес ...]. (2) префикс «DS:», указывающий, что он находится в сегменте данных. Операнды регистров не имеют такого префикса сегмента. (3) «BYTE PTR» - который говорит: «взять адрес памяти, указанный в 'DS: [EDX]', и интерпретировать его как ссылку на 8-битный байт в памяти».

Я подозреваю, что ты действительно хочешь

MOVSX ECX,DL

«DL» - это имя для младших 8 бит 32-битного регистра EDX. Т.е. DL = EDX.bits [7: 0]. К сожалению, ассемблеры x86 обычно не принимают синтаксис типа «EDX.bits [7: 0]» (если я их не написал), поэтому вам нужно знать исторические имена подрегистров:

AL = EAX.bits[7:0]
AH = EAX.bits[15:8]
AX = EAX.bits[15:0]
EAX = 32 bit register that "covers" all of the above

и так далее: BL, CL, DL, DI, ...

person Krazy Glew    schedule 21.10.2015