Поддерживает ли процессор mmx-технологию?
Так как MMX-технология реализована не на всех процессорах, то рекомендуется писать программы, которые предварительно проверяют тип используемого процессора и в зависимости от него переходит на участок программы, использующий или не использующий MMX-технологию. Для идентификации процессора используется команда cpuid. Полное описание команды cpuid довольно сложное, поэтому здесь мы его опустим [Юров, справочник]. Нам достаточно знать следующее: если перед выполнением команды cpuid регистр EAX сщдержит 1, то после выполнения cpuid 23-й бит регистра EDX показывает, поддерживает процессор MMX-технологию или нет. Фрагмент программы может выглядеть так:
mov eax,1
cpuid
bt edx,23
jnc no_mmx
Задача. Используя результат предыдущей задачи написать программу, которая определяет с помощью команды cpuid поддерживает ли процессор MMX-технологию, и в зависимости от результата переходит к выполнению соответствующего участка программы.
Система команд mmx
Остается вкратце остановиться на системе команд. Она включает уже знакомые нам операции: арифметические, логические, сравнения, сдвиги, пересылки, но применяемые к упакованным байтам, упакованным словам и т.д.
Типичная мнемоника команды имеет вид:
префикс P — Packed, работа с упакованными данными;
операция (ADD, SUB, OR, XOR …);
суффикс – US — Unsigned Saturation — беззнаковое насыщение;
S — Signed Saturation — знаковое насыщение;
B, W, D, Q — Byte, Word, Doubleword, Quadword — используемый тип
данных.
Команды, имеющие различный тип входных и выходных данных, снабжены двумя суффиксами.
Пример. PSRLW — Packed Shift Right Logical Words — логический сдвиг влево каждого из четырех упакованных слов.
PACKUSWB — Pack with Unsigned Saturation Words to Bytes — упаковка с беззнаковым насыщением слов в байты (эта команда упаковывает 8 знаковых слов — по четыре из первого и второго операнда команды — в 8 беззнаковых байтов, при этом отрицательные числа кодируются 00h, а слишком большие положительные — 0ffh).
Включаемый файл для TASM 5.0
Чтобы не кодировать команды MMX вручную, можно воспользоваться включаемым файлом, содержащим соответствующие макроопределения. Такой файл приведен в справочнике [Бердышев]. Но там использованы операции какого-то другого Ассемблера, не TASM. Файл mmx16.inc (переделанный под TASM для 16-разрядной платформы) можно взять, например, с дискеты, приложенной к книге [Юров]. Макроопределения этого файла представляют самостоятельный интерес. Рассмотрим фрагмент файла
…
_opc_paddsb EQU 0ech
…
mm0 EQU <ax>
mm1 EQU <cx>
mm2 EQU <dx>
mm3 EQU <bx>
mm4 EQU <sp>
mm5 EQU <bp>
mm6 EQU <si>
mm7 EQU <di>
paddsb MACRO dest:req,src:req
LOCAL pre,post
pre:
xadd word ptr src,dest
post:
ORG pre+1
DB _opc_paddsb
ORG post
ENDM
Атрибут req в параметре макроса означает, что при вызове макроса аргумент нельзя опустить (req — requisted — требуемый). Команда xadd появилась в 486-м процессоре. Неважно, что она делает (она выполняет обмен и сложение двух операндов). Важно, что код операции этой команды занимает два байта и первый байт — 0Fh. Вмсто второго байта команды нужно подставить второй байт кода оперции paddsb. Делается это так: директива ORG pre+1 устанавливает счетчик адреса так, чтобы он показывал на второй байт кода операции. Посредством DB _opc_paddsb формируется код операции. Директива ORG post возвращает счетчику адреса нужное значение. В постбайте нужные коды регистров mmx формируются за счет определений вида mm0 EQU <ax> (регистр ax кодируется как 000).
Программа теперь принимает вид
INCLUDE mmx16.inc
.MODEL small
.486
.STACK 100h
.DATA
vec1 DB 120,120,-120,-120,0,0,0,0
vec2 DB 10,2,-10,-2,0,0,0,0
vec3 DB 8 DUP(0)
.CODE
start:mov ax,@data
mov ds,ax
movq mm0,vec1 ; переслать учетверенное слово в mm0
;DB 0Fh,6Fh,06h,00h,00h
paddsb mm0,vec2 ; Сложить с насыщением упакованные байты
; Мнемоника: p - packed, add, s - saturation, b - bytes
;DB 0Fh,0ECh,06h,08h,00h
movq vec3,mm0 ; переслать учетверенное слово в vec3
;DB 0Fh,7Fh,06h,10h,00h
emms
;DB 0fh,77h
mov ax,4C00h
int 21h
END start
Упражнение. Изучить листинг этой программы. Проследить как формируются коды команд.
Программирование MMX-команд в VC++
В программу можно вставлять команды для работы с MMX. Используйте для этого встроенный ассемблер (директива __asm). В процессе отладки в окне Variables можно наблюдать содержимое MMX-регистров.
Упражнение. Переделайте приведенную выше программу в программу на языке Си с ассемблерной вставкой. Проследите работу программы в отладчике.
XMM-расширение
В MMX-технологии предполагалось, что упакованные данные — это целые числа (знаковые и беззнаковые).
В Pentium III дополнительно к возможностям Pentium II реализовано так называемое XMM-расширение. Добавлен аппаратный модуль SSE (Streaming SIMD Extensions — потоковое SIMD-расширение). В процессор добавлено 8 регистров xmm0, xmm1, …, xmm7. Каждый регистр имеет размер 128 бит. В регистре размещаются четыре числа в формате float (напомним, что размер каждого такого формата составляет 32 бита).
|
127 |
|
|
0 |
|
|
|
|
|
Для работы с этими числами введено 70 новых инструкций. Они обеспечивают параллельное выполнение операций над упакованными плавающими числами, а также их преобразование к другим форматам. Перечень этих команд имеется, например, в [Юров, справочник].
