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

Я довольно догматичен об объявлении каждой возможной переменной final. Это включает параметры метода, локальные переменные, и редко, поля объекта значения. У меня есть три главных причины для объявления последних переменных везде:

  1. Объявление Намерения: Путем объявления последней переменной я заявляю, что эта переменная предназначена, чтобы быть записанной в только однажды. Это - тонкая подсказка другим разработчикам и большая подсказка к компилятору.
  2. Переменные Единственного использования Осуществления: Я верю в идею, что каждая переменная должна иметь только одну цель в жизни. Путем предоставления каждой переменной только одной цели Вы уменьшаете время, которое это берет к grok цель той конкретной переменной при отладке.
  3. Допускает Оптимизацию: Я знаю, что компилятор раньше имел приемы улучшения производительности, которые положились конкретно на неизменность ссылки на переменную. Мне нравится думать, что некоторые из этих старых приемов производительности (или новые) будут использоваться компилятором.

Однако я действительно думаю, что заключительные классы и методы совсем не так же полезны как ссылки последней переменной. final ключевое слово, когда используется с этими объявлениями просто предоставляют контрольно-пропускные пункты автоматизированному тестированию и использованию Вашего кода способами, которыми Вы никогда, возможно, не ожидали.

115
задан starblue 6 December 2009 в 19:33
поделиться

4 ответа

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

REP STOSB
REP MOVSB
REP SCASB

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

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

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

74
ответ дан 24 November 2019 в 02:26
поделиться

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

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

12
ответ дан 24 November 2019 в 02:26
поделиться

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 = базовый регистр

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

78
ответ дан 24 November 2019 в 02:26
поделиться

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

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!
33
ответ дан 24 November 2019 в 02:26
поделиться
Другие вопросы по тегам:

Похожие вопросы: