Как знак инструкции MOVSX расширяет ввод в этом случае?

#assembly #x86 #disassembly #sign-extension #zero-extension

#сборка #x86 #разборка #знак-расширение #нулевое расширение

Вопрос:

У меня есть следующая разборка:

[dest] = d5 cd e8 ca 68

 movzx   eax, [ebp dest]
# value of edx at this point is: F7FBB898
movsx   edx, al
# value of edx after this is: FFFFFFD5

# [ebp var_E] stores 0
movzx   eax, [ebp var_E]
movsx   eax, al
# eax = 0 here
add     eax, edx
# eax becomes FFFFFFD5
cmp     eax, 0D5h
jnz     short loc_565564E6
  

Я дал объяснение и последовательность действий для каждой инструкции ниже:

  1. Он считывает байт из [dest] и сохраняет его в eax.
  2. Изначально значение edx равно: F7FBB898. После инструкции movsx edx, al она становится FFFFFFD5. Как я могу убедиться, что значение edx будет равно 0x000000d5 на данный момент?

Каким должно быть мое начальное значение в [dest], чтобы после этих операций конечное значение в eax было 0xd5, а не 0xFFFFFFD5

Комментарии:

1. Другими словами, вам не нужно расширение знака, вы хотите нулевое расширение.

2. Обратите внимание, что ваша первая инструкция movzx eax, [ebp dest] неоднозначна: в ней не указан размер источника памяти, поэтому она может быть нулевым расширением байта или слова в EAX. И поскольку EAX заблокирован в следующей инструкции, совершенно бессмысленно сначала увеличивать значение нуля в EAX, прежде чем расширять младший байт по знаку в EDX. movsx edx, byte [ebp dest] / movsx eax, byte [ebp var_E] было бы в точности эквивалентно первым 4 инструкциям. Вероятно, это сгенерированный компилятором код без оптимизации или с минимальной оптимизацией, в результате чего получается подобный код braindead.

Ответ №1:

Вам следует использовать movzx (Переместить с нулевым расширением) вместо movsx (Переместить со знаком расширения), если вы хотите расширить значение нулями, не глядя на его знак.

Когда вы используете movsx для перемещения 0xd5 в edx , он скопирует младшие байты to в edx и заполнит оставшиеся MSB скопированного значения ( 0xd5 = 0b11010101 , MSB равен 1), что заполнит 6 оставшихся байтов 0xFFFFFF . При movzx остальные байты заполняются 0x000000 независимо от MSB.