Все данные в RAM должны быть выравненены так, чтобы их адреса были кратны 2,
4, 8 или 16 согласно данной схеме:
выравнивание
размер операнда PPlain и PMMX PPro, PII и PIII
1 (byte) 1 1
2 (word) 2 2
4 (dword) 4 4
6 (fword) 4 8
8 (qword) 8 8
10 (tbyte) 8 16
16 (oword) n.a. 16
На PPlain и PMMX при обращении к невыравненным данным будет теряться по меньшей мере 3 такта, если пересечена граница в 4 байта. Потери будут выше при пересечении границы кэша.
На PPro, PII и PIII невыравненные данные удут стоить вам 6-12 дополнительных тактов, если пересечена граница кэша. Невыравненные операнды, меньшие чем 16 байтов и не перешедшие границу в 32 байта, не приводят к потерям.
Выравнивание данных на 8 или 16 в стеке двойных слов может стать проблемой.
Общий метод решения - установить выравненный указатель на кадр стека. Функция
с выравненными локальными данными может выглядеть примерно так:
_FuncWithAlign PROC NEAR
PUSH EBP ; пролог
MOV EBP, ESP
AND EBP, -8 ; выравнивание указателя на кадр
стека на 8
FLD DWORD PTR [ESP+8] ; параметр функции
SUB ESP, LocalSpace + 4 ; резервируем локальные данные
FSTP QWORD PTR [EBP-LocalSpace] ; теперь сохраняем что-нибудь в
; локальной переменной
...
ADD ESP, LocalSpace + 4 ; эпилог, восстанавливаем ESP
POP EBP ; (потеря скорости AGI на PPlain/PMMX)
RET
_FuncWithAlign ENDP
В то время как выравнивание данных важно всегда, выравнивание кода не является необходимым на PPlain и PMMX. Принципы выравнивания кода на PPro, PII и PIII изложены в главе 15.
[C] Агнер Фог, пер. Aquila