Назначение регистров ESI & EDI? - PullRequest
109 голосов
/ 06 декабря 2009

Каково реальное назначение и использование регистров EDI & ESI в ассемблере?

Я знаю, что они используются для строковых операций с одной стороны.

Может кто-нибудь также привести пример?

Ответы [ 5 ]

76 голосов
/ 07 декабря 2009

SI = Исходный индекс
DI = Индекс назначения

Как указали другие, они имеют специальное использование с инструкциями строки. Для программирования в реальном режиме сегментный регистр ES должен использоваться с DI и DS с SI, как в

movsb  es:di, ds:si

SI и DI также могут использоваться в качестве регистров индекса общего назначения. Например, исходный код C

srcp [srcidx++] = argv [j];

компилируется в

8B550C         mov    edx,[ebp+0C]
8B0C9A         mov    ecx,[edx+4*ebx]
894CBDAC       mov    [ebp+4*edi-54],ecx
47             inc    edi

, где ebp+12 содержит argv, ebx равно j, а edi имеет srcidx. Обратите внимание, что третья инструкция использует edi, умноженное на 4, и добавляет ebp смещение на 0x54 (расположение srcp); квадратные скобки вокруг адреса обозначают косвенность.


Хотя я не могу вспомнить, где я это видел, но это подтверждает большую часть этого, а это (слайд 17) другие:

AX = аккумулятор
DX = аккумулятор двойных слов
CX = счетчик
BX = базовый регистр

Они выглядят как регистры общего назначения, но есть ряд инструкций, которые (неожиданно?) Используют один из них - но какой? - неявно.

70 голосов
/ 06 декабря 2009

Есть несколько операций, которые вы можете выполнять только с с помощью DI / SI (или их расширенными аналогами, если вы не изучали ASM в 1985 году). Среди них

REP STOSB
REP MOVSB
REP SCASB

Это, соответственно, операции для повторного (= массового) хранения, загрузки и сканирования. Что вы делаете, вы устанавливаете SI и / или DI так, чтобы они указывали на один или оба операнда, возможно, устанавливали счет в CX и затем позволяли копировать. Это операции, которые работают с кучей байтов за раз, и они как бы переводят процессор в автоматический режим. Поскольку вы явно не кодируете циклы, они выполняют свою работу более эффективно (обычно), чем цикл с ручным кодированием.

На всякий случай, если вам интересно: в зависимости от того, как вы настроили операцию, повторное сохранение может быть чем-то простым, например, вставка значения 0 в большой непрерывный блок памяти; Я думаю, что MOVSB ​​используется для копирования данных из одного буфера (ну, любой набор байтов) в другой; и SCASB используется для поиска байта, который соответствует некоторому критерию поиска (я не уверен, что это только поиск на равенство, или что - вы можете посмотреть его :))

Это большая часть того, для чего предназначены эти регистры.

32 голосов
/ 06 декабря 2009

Операционные коды, такие как MOVSB ​​и MOVSW, которые эффективно копируют данные из памяти, на которую указывает ESI, в память, на которую указывает EDI. Таким образом,

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!
11 голосов
/ 07 декабря 2009

В дополнение к строковым операциям (MOVS / INS / STOS / CMPS / SCASB / W / D / Q и т. Д.), Упомянутым в других ответах, я хотел добавить, что есть и более «современные» инструкции по сборке x86, которые неявно используйте как минимум EDI / RDI:

Инструкция SSE2 MASKMOVDQU (и предстоящая инструкция AVX VMASKMOVDQU) выборочно записывают байты из регистра XMM в память, указанную EDI / RDI.

4 голосов
/ 22 октября 2016

Помимо регистров, используемых для массовых операций, они полезны тем, что их свойство сохраняется через вызов функции (сохраняемый при вызове) в 32-битном соглашении о вызовах. ESI, EDI, EBX, EBP, ESP сохраняются при вызове, тогда как EAX, ECX и EDX не сохраняются при вызове. Сохраняемые вызовы регистры соблюдаются функцией библиотеки C, а их значения сохраняются при вызове функций библиотеки C.

Джефф Дюнтманн в своей книге на ассемблере имеет пример кода на ассемблере для печати аргументов командной строки. Код использует esi и edi для хранения счетчиков, поскольку они не будут изменены функцией printf библиотеки C. Для других регистров, таких как eax, ecx, edx, нет гарантии, что они не будут использоваться функциями библиотеки C.

https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025

См. Раздел 12.8 Как C видит аргументы командной строки.

Обратите внимание, что 64-разрядные соглашения о вызовах отличаются от 32-разрядных соглашений о вызовах, и я не уверен, сохраняются ли эти регистры вызовов или нет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...