Назначение регистров ESI & EDI?


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

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

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

5 97

5 ответов:

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

REP STOSB
REP MOVSB
REP SCASB

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

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

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

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 mulitplied на 4 и добавляет ebp смещение на 0x54 (расположение srcp); скобки вокруг адреса указывают на косвенность.


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

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

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

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

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!

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

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

в дополнение к регистрам, используемым для массовых операций, они полезны для их свойства сохранения через вызов функции (call-preserved) в 32-разрядном соглашении о вызове. Институт, ЕОИ, регистры ebx, ЭБП ВСД называют сохранившиеся в то время как в eax, ecx и edX имеют не называют сохранившиеся. Регистры, сохраненные при вызове, соблюдаются функцией библиотеки C,и их значения сохраняются через вызовы функции библиотеки C.

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

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

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

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