Цель регистров ESI и EDI?

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

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

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

Ответ 1

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

REP STOSB
REP MOVSB
REP SCASB

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

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

Это большая часть того, что для этих regs.

Ответ 2

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


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

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

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

Ответ 3

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

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

Ответ 4

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

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

Ответ 5

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

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

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

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

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