Использование регистров FPU и MMX в качестве регистров общего назначения

Большинство ассемблерных программ используют 4 регистра общего назначения eax ebx ecx edx, но я обнаружил, что довольно часто мне нужно использовать более 4 регистров, чтобы легко выполнить мою задачу, не требуя слишком много push и pop из стека. Поскольку моя программа не имеет намерения использовать регистры FPU или MMX для вычислений с плавающей запятой или их «предполагаемого использования», считается ли приемлемым использование этих дополнительных регистров в вашей программе?

Например. использование xmm0 для счетчика приращения цикла, освобождающего регистр ecx для других целей.


person user99545    schedule 23.02.2013    source источник
comment
Вы можете делать все, что хотите. Если вы обнаружите, что использование регистров xmm быстрее, чем перенос в стек, сделайте это.   -  person Mysticial    schedule 23.02.2013
comment
@Mysticial Редко кто-нибудь говорит мне, что я могу делать в программировании все, что хочу. Копаю :)   -  person user99545    schedule 23.02.2013
comment
x86_64 имеет 8 дополнительных регистров для общего использования.   -  person Dietrich Epp    schedule 23.02.2013
comment
Отвращение к использованию памяти станет серьезным препятствием, когда вы перейдете к алгоритмам, более сложным, чем Hello world. Лучше научитесь использовать память (подсказка: PUSH / POP не, как вы это делаете). И да, ESI, EDI, EBP. ESP, если ты сумасшедший.   -  person Seva Alekseyev    schedule 25.02.2013
comment
Подсказка громче: установите кадр стека при вводе функции и установите EBP так, чтобы он указывал на кадр. Затем вы можете иметь столько ячеек частной памяти, сколько хотите, выделяя их во фрейме стека. Мой личный опыт заключается в том, что если у меня есть несколько структур данных, к которым осуществляется доступ с помощью указателей в регистрах (как обычно), я в значительной степени могу обойтись 6 регистрами (я записываю EBP для указателя фрейма стека) только для случая push и pop . Да, я переписываю свою партию кода, когда меняю ее, чтобы воспользоваться преимуществами / жить с новыми ограничениями исправленного кода.   -  person Ira Baxter    schedule 25.02.2013
comment
Почему бы вам сначала не написать простую версию C, чтобы увидеть, как регистрируется утечка компилятора. Но если необходимо использовать много регистров, рекомендуется перейти на x86_64.   -  person phuclv    schedule 10.08.2013


Ответы (3)


Почему четыре? Вы можете использовать все: eax, ebx, ecx, edx, esi, edi и ebp. Это семь. Или этого тоже мало?

Регистры FPU и MMX несколько неудобны для работы, поскольку они могут быть загружены только из себя и памяти и сохранены только в себе и в памяти. Вы не можете свободно перемещать данные между ними и регистрами общего назначения, а также нет инструкций, способных работать с обоими типами регистров одновременно.

Если семи регистров общего назначения недостаточно, используйте локальные переменные / переменные в стеке. Например, вы можете напрямую уменьшить значение счетчика в памяти, а также напрямую сравнить его с константой или другим регистром. Скорее всего, это будет не медленнее (скорее всего, быстрее), чем странным образом использовать регистры FPU или MMX.

person Alexey Frunze    schedule 23.02.2013
comment
Нет, семь регистров не так быстро, как использовать их все. Регистры MMX могут быть весьма полезными. - person Ben Voigt; 23.02.2013
comment
@BenVoigt: Честно говоря, они бесполезны в качестве счетчика циклов вместо ecx. Ветвление в регистре MMX, становящемся нулевым, намного менее эффективно, чем dec ecx / jnz, и в любом случае требует наличия запасного целочисленного регистра в этой точке. Но обязательно, если вы хотите заполнить массив возрастающей последовательностью, используйте регистр XMM и paddd / movd store. Или лучше, векторизуйте и заполните сразу 4 элемента с помощью paddd / movdqu store. Но тогда вы просто векторизуете цикл обычным способом с помощью векторных регистров. - person Peter Cordes; 03.10.2020
comment
Но да, особенно в 32-битном коде (где давление регистров хуже) могут быть случаи, когда использование нижнего элемента векторного регистра в качестве скаляра имеет смысл, если вы безусловно делаете некоторые целочисленные вещи, которые не зависят от значений в целочисленных регистрах. Особенно просто копирование памяти. Имейте в виду, что MMX в какой-то момент понадобится emms, стоимость циклов по сравнению с SSE2 для регистров XMM. - person Peter Cordes; 03.10.2020

Как часто вам нужны полные 32 бита регистра? Для таких вещей, как маленькие счетчики, не стесняйтесь использовать байтовые четверти регистров общего назначения: AH / AL, BH / BL, CH / CL, DH / DL. С помощью некоторых побитовых уловок вы также можете использовать старшие 16 бит регистров общего назначения в качестве промежуточного хранилища для переменных размером с слово.

В реальном режиме (читай: под DOS) вы также можете использовать сегментные регистры ES, FS и GS для хранения промежуточных значений. Однако в ОС с защищенным режимом (Windows, Linux, * nix) код выйдет из строя.

person Seva Alekseyev    schedule 25.02.2013
comment
Это хорошая идея только для процессоров Intel (которые переименовывают AH отдельно от остальной части реестра). На AMD inc ah и inc al имеют ложную зависимость друг от друга. См. Почему GCC не использует частичные регистры?. Даже на Intel (начиная с Haswell или около того) запись AL на самом деле является слиянием с RAX, что означает, что mov al, 6 не разрушение зависимостей, пока mov eax, 6. (Это не приводит к принудительному слиянию отдельно переименованного AH, поэтому, по крайней мере, не связывает эти деп-цепочки) - person Peter Cordes; 03.10.2020

Конечно, есть SI и DI, а на x64 у вас есть дополнительные регистры, но вы можете использовать регистры FP для чего угодно.

person TIm Hill    schedule 23.02.2013