NASM: parser: инструкция ожидаемая rep movs
Я превращаю исполняемый файл в некоторый шелл-код NASM (для окон, если он уместен), но я везде сталкиваюсь с ошибками "ошибка: парсер: инструкция ожидается" из команд повторов.
label_0000641:
lea edi,[esp+0x164]
label_0000648:
rep movs DWORD es:[edi],DWORD ds:[esi]
label_000064a:
and DWORD [esp+0x168],0x0
Есть ли специальный синтаксис для этого? Я делаю глупую ошибку? Я понятия не имею, как идти об исправлении этих ошибок и действительно хотел бы некоторого руководства.
(Я компилирую с помощью nasm -f bin -o out.bin test.asm)
Благодарю.
3 ответа
NASM не примет rep movs DWORD es:[edi],DWORD ds:[esi]
Из руководства NASM; 2.2.3 NASM не хранит типы переменных
NASM по своей природе предпочитает не помнить типы переменных, которые вы объявляете. Тогда как МАСМ запомнит, увидев
var dw 0
, что вы объявили var как переменную размера слова, и тогда сможете заполнить неоднозначность размера инструкцииmov var,2
NASM намеренно не помнит ничего о символе var, кроме того, где он начинается, и поэтому вы должны явно кодироватьmov word [var],2
,По этой причине NASM не поддерживает
LODS
,MOVS
,STOS
,SCAS
,CMPS
,INS
, или жеOUTS
инструкции, но поддерживает только такие формы, какLODSB
,MOVSW
, а такжеSCASD
, которые явно указывают размер компонентов строк, которыми манипулируют.
Таким образом, код для использования rep movsd
Это просто выглядит как какой-то слишком многословный вывод из дизассемблера.
Цитирование из руководства Intel (раздел под названием " Строковые инструкции"):
По умолчанию
ESI
регистр адресов сегмента, обозначенногоDS
сегментный регистр....EDI
регистр адресов сегмента, обозначенногоES
сегментный регистр.
...
MOVS
инструкция перемещает строковый элемент, адресованныйESI
зарегистрироваться по адресу, указанномуEDI
регистр. Ассемблер распознает три "короткие формы" этой инструкции, которые определяют размер строки, которую нужно переместить:MOVSB
(переместить строку байтов),MOVSW
(переместить строку слова) иMOVSD
(переместить строку двойного слова).
Поэтому, если мы применим эту информацию, мы получим:
; DWORD operands means movsd, ds:[esi] is the default source, and
; es:[edi] is the default destination
rep movsd
Примечание: в описании для MOVS
в руководстве Intel, MOVS m32, m32
указан как поддерживаемый. Они называют это "явным операндом" формой инструкции. Он служит только для документации, так как единственный разрешенный источник [(R|E)SI]
и единственный разрешенный пункт назначения [(R|E)DI]
, Я не знаю, поддерживает ли NASM форму явных операндов или каков в этом случае синтаксис.
Я бы обязательно инициализировать ECX
длина строки для rep
инструкция, инициализировать EDI
а также ESI
к строке назначения и исходной строке соответственно, убедитесь, что флаг направления установлен соответственно:
label_0000641:
lea edi,[esp+0x164] ;initializing destination?
label_0000648:
rep movsd
label_000064a:
and DWORD [esp+0x168],0x0