 |
По умолчанию генерация эффективного кода разрешена. Однако
на генерацию эффективного кода влияют не только директивы SMART и
NOSMART, но и директива VERSION.
Примечание: О директиве VERSION подробнее рассказыва-
ется в Главе 3.
Генерация эффективного кода влияет на следующие ситуации ге-
нерации кода:
- Замена инструкции LEA инструкцией MOV, если операндом инс-
трукции LEA является простой адрес.
- Где это возможно, выполняется генерация булевских инструк-
ций со знаком,. Например, AND AX,+02 вместо AND AX,0002.
Турбо Ассемблер 3.0/tasm/#2-2 = 10 =
- Замена инструкции CALL FAR xxxx комбинацией инструкций
PUSH CS, CALL NEAR xxxx, где целевой адрес xxxx использует
тот же регистр CS.
Использование эффективных инструкций облегчает написание эф-
фективного кода. Некоторые стандартные инструкции Intel также
расширены таким образом, чтобы расширить их возможности и облег-
чить использование. Они обсуждаются в следующих разделах.
Расширенные инструкции перехода
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Условные переходы, такие как JC или JE в процессорах 8086,
80186 и 80286 могут быть только ближними (NAER), то есть переход
выполняется в границах сегмента и на расстояние -128 байт +127
байт относительно текущего адреса. Это ограничение действует и
для условных инструкций цикла, таких как JCXZ или LOOP (на всех
процессорах фирмы Intel).
Там, где это необходимо, Турбо Ассемблер может генерировать
дополнительные последовательности переходов и обходить это огра-
ничение. Например, Турбо Ассемблер может преобразовать инструк-
цию:
JC xxx
в инструкции:
JNC temptag
JMP xxx
Вы можете разрешить данную дополнительную последовательность
переходов в помощью директивы JUMPS, и запретить ее директивой
NOJUMPS. По умолчанию Турбо Ассемблер не генерирует это средство.
Когда вы указывает директиву JUMPS, Турбо Ассемблер резерви-
рует достаточно места для дополнительных последовательностей пе-
рехода во всех условных переходах вперед. Когда определяется фак-
тическое расстояние перехода вперед, дополнительная последова-
тельность может не понадобиться. Когда это происходит, Турбо Ас-
семблер для заполнения лишнего пространства генерирует инструкции
NOP.
Чтобы избежать дополнительных инструкций NOP, вы можете:
- использовать переопределение условных переходов, диапазон
которых вам известен, например:
JC SHORT abc
ADD ax,ax
abc:
- задать параметр командной строки /m (подробнее о нем расс-
Турбо Ассемблер 3.0/tasm/#2-2 = 11 =
казывается в Главе 2).
Дополнительные инструкции цикла процессора 80386
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
В инструкциях цикла процессора 80386 в качестве регист-
ра-счетчика может использоваться регистр CX или ECX. Стандартные
мнемоники инструкций LOOP, LOOPE, LOOPZ, LOOPNE и LOOPNZ фирмы
Intel выбирают регистр-счетчик на основе того, является ли теку-
щий сегмент кода 32-битовым сегментом (тогда используется ECX)
или 16-битовым (используется регистр CX).
Турбо Ассемблер имеет специальные инструкции, которые увели-
чивают гибкость средства LOOP. Инструкции LOOP, LOOPE, LOOPWZ,
LOOPWNE и LOOPWNZ используют в качестве счетчика регистр CX, не-
зависимо от текущего сегмента. Аналогично, инструкции LOOPD,
LOOPDE, LOOPDZ, LOOPDNE и LOOPDNZ используют в качестве счетчика
регистр ECX.
Дополнительные инструкции ENTER и LEAVE
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Инструкции ENTER и LEAVE используются для удаления из стека
кадра процедуры. В зависимости от того, является текущий сегмент
кода 16-битовым или 32-битовым, стандартные инструкции ENTER и
LEAVE будут модифицировать либо регистры BP и SP, либо EBP и ESP.
Если сегмент кода - это 32-битовый сегмент, а сегмент стека - 16-
битовый, то данные инструкции могут оказаться неподходящими.
В Турбо Ассемблере предусмотрены 4 дополнительные инструк-
ции, которые всегда выбирают конкретный размер стека, независимо
от размера сегмента кода. Инструкции ENTERW и LEAVEW всегда выби-
рают в качестве регистров кадра стека BP и SP, a ENTERD и LEAVED
- регистры EBP и ESP.
Дополнительные инструкции возврата
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Стандартная инструкция RET генерирует код, который соответс-
твующим образом завершает текущую процедуру. Это включает в себя
генерацию кода завершения процедуры, которая использует интер-
фейсные соглашения языка высокого уровня. Даже если для процедуры
используются соглашения NOLANGUAGE, инструкция RET в зависимости
от описания процедуры (описана она как NEAR или FAR) будет гене-
рировать различный код. Для процедуры NEAR Турбо Ассемблер гене-
рирует дальнюю инструкцию возврата. Для процедуры FAR Турбо Ас-
семблер генерирует ближнюю инструкцию возврата. (Вне процедуры
всегда генерируется ближний возврат.)
Турбо Ассемблер включает в себя дополнительные инструкции,
которые позволяют задавать генерацию нужных инструкций возврата
(без кода завершения). Они перечислены в следующей таблице:
Турбо Ассемблер 3.0/tasm/#2-2 = 12 =
Инструкции возврата Таблица 13.2
ЪДДДДДДДДДДДДДДДДДВДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДї
і Инструкция і Функция і
ГДДДДДДДДДДДДДДДДДЕДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДґ
і RETN і Всегда генерирует ближний возврат. і
і і і
і RETNF і Всегда генерирует дальний возврат. і
і і і
і RETCODE і Генерирует возврат, тип которого соответ- і
і і ствует текущей выбранной модели. Для модели і
і і TINY, SMALL, COMPACT и TPASCAL генерируется і
і і ближний возврат. Для модели MEDIUM, LARGE, і
і і HUGE и TCHUGE - дальний возврат. і
АДДДДДДДДДДДДДДДДДБДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДЩ
Расширенные инструкции PUSH и POP
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Турбо Ассемблер поддерживает несколько расширений инструкций
PUSH и POP. Эти расширения существенно уменьшают объем ввода, не-
обходимого для задания расширенной последовательности инструкций
PUSH и POP.
Турбо Ассемблер 3.0/tasm/#2-2 = 13 =
Инструкции PUSH и POP с несколькими операндами
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
На одной строке вы можете задать несколько инструкций PUSH и
POP. Например:
PUSH ax
PUSH bx
PUSH cx
POP cx
POP bx
POP ax
можно записать как:
PUSH ax bx cx
POP cx bx ax
Чтобы Турбо Ассемблер распознавал наличие нескольких операн-
дов в этих инструкциях, нужно чтобы любой операнд не мог рассмат-
риваться как часть соседнего операнда, например инструкция:
PUSH foo [bx]
может привести к непредвиденному результату, поскольку foo,[bx] и
foo[bx] являются допустимыми выражениями. Чтобы эта инструкция
стала определенней, можно использовать круглые или квадратные
скобки, например:
PUSH [foo] [bx]
Использование в инструкциях PUSH и POP указателей
ДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДДД
Стандартные инструкции PUSH и POP не могут сохранять в стеке
дальние указатели, которые требуют 4 байт в процессорах 8086,
80186 и 80286 и 6 байт в процессоре 80386.
Турбо Ассемблер допускает указание в инструкциях PUSH и POP
операнда-указателя размером DWORD для процессора 8086, 80186 и
80286 и QWORD для процессора 80386. Когда обнаруживаются такие
инструкции, Турбо Ассемблер генерирует инструкции PUSH и POP для
|