Для копирования байтов между регистрами или памятью в x86 используйте MOV, но если нужен перенос с расширением или сжатием – DD (Doubleword to Doubleword) окажется точнее. Эта мнемоника работает с 32-битными операндами, сохраняя разрядность без неявных преобразований.
Пример: DD EAX, EBX скопирует содержимое EBX в EAX, игнорируя флаги. В отличие от MOVZX или MOVSX, здесь нет обработки знака или нуля – только прямая передача данных. Это полезно при работе с буферами, где важно избежать лишних операций.
В реальных задачах, таких как распаковка структур или подготовка аргументов для вызовов API, DD сокращает число инструкций. Например, при копировании блока из 4 байт между стеком и регистром он исключает два отдельных MOV для младшей и старшей частей.
Объявление данных с помощью директивы dd
Для резервирования 32-битных значений в сегменте данных используйте синтаксис: имя_метки dd значение1, значение2, ...
. Например, numbers dd 10, 20, 0xFFFF
создаст три двойных слова (10, 20 и 65535).
Особенности размещения
Адрес следующего элемента будет автоматически смещен на 4 байта. Если требуется выравнивание, добавьте ALIGN 4
перед объявлением.
Примеры использования
buffer dd 256 dup(?)
– резервирует 256 неинициализированных двойных слова. Для строк в UTF-32: unicode_str dd 'A', 'B', 0
. Младший байт размещается по младшему адресу (little-endian).
Практические примеры работы с памятью через dd
Копирование участка памяти в файл
Для сохранения содержимого памяти по адресу 0x10000 в файл memory_dump.bin выполните:
dd if=/dev/mem of=memory_dump.bin bs=1 count=1024 skip=$((0x10000))
Параметр bs=1 задает размер блока в 1 байт, count=1024 копирует 1 КБ данных.
Запись данных в физическую память
Чтобы записать содержимое файла patch.bin по адресу 0xA0000:
dd if=patch.bin of=/dev/mem bs=1 seek=$((0xA0000)) conv=notrunc
Флаг conv=notrunc предотвращает обрезание файла при записи.
Для работы с MMIO-регистрами добавьте seek с шестнадцатеричным смещением:
dd if=/dev/zero of=/dev/mem bs=4 seek=$((0xFEDC0000/4)) count=1