Использование turbo pascal с языком ассемблера. Встроенный ассемблер, страница 2

loop    @1

end;

asm

@1:

...

jc      @2

...

jmp    @1

@2:

end;

goto Start;

Stop:

end;

Заметим, что нормальная метка  может  быть  определена  внутри оператора asm и использована вне оператора asm, и наоборот. Заметим также, что одно и то же имя локальной метки может  использоваться в различных операторах asm.

Префикс.

Встроенный ассемблер поддерживает встроенные префиксы:

------------------------------------------------------------------LOCK              Захват шины

REP               Повтор строковой операции

REPE/REPZ         Повтор строковой операции пока =/0

REPNE/REPNZ       Повтор строковой операции пока (не =)/(не 0)

SEGCS             Перекрытие CS (сегмент кода)

SEGDS             Перекрытие DS (сегмент данных)

SEGES             Перекрытие ES (экстра сегмент)

SEGSS             Перекрытие SS (сегмент стека)

------------------------------------------------------------------С ассемблерной инструкцией могут  быть  указаны  0  или  более префиксов. Например:

asm

rep    movsb

SEGES  lodsw

SEGCS  mov ax,[bx]

SEGES

mov    WORD PTR [DI],0

end;

Заметим, что  префикс  может быть указан без кода инструкции в том же операторе -  в  этом  случае  префикс  воздействует  на  код инструкции в следующем ассемблерном операторе.

Код инструкции  очень  редко  имеет более одного префикса и не может быть указано более  3  префиксов  (LOC,  затем  SEGxx,  затем

REPxx). Будьте внимательны при использовании нескольких префиксов их порядок важен и некоторые процессоры 80х86 не могут обрабатывать все комбинации  правильно.  Например,  8086  или 8088 помнят только префикс REPxx,  если  в  середине  строковой  инструкции  возникает прерывание. Поэтому  префиксы  LOC  и  SEGxx  не могут быть надежно закодированы до REPxx в строковой инструкции.

Коды инструкций.

Встроенный Ассемблер    поддерживает   все   коды   инструкций

8086/8087 и 80286/80287. Коды 8087 допустимы только в состоянии {$N

+} (числовой  процессор  разрешен),  коды  80286 допустимы только в состоянии {$G+} ( генерация кода 80286  разрешена),  и  коды  80287

разрешены только в состоянии {$G+,N+}.

Полное описание этих инструкций см.  в руководствах по 80х86 и

80х87.

Размер инструкции RET.

Инструкция RET   генерирует   ближний   или   дальний  возврат в зависимости от модели вызова текущей процедуры или функции.

procedure NearProc; near;

begin

asm

ret     {генерирует ближний вызов}

end;

end;

procedure FarProc; far;

begin

asm

ret     {генерирует дальний вызов}

end;

end;

С другой стороны,  инструкции RETN и  RETF  всегда  генерируют ближний возврат и дальний возврат, вне зависимости от модели вызова текущей процедуры или функции.

Автоматический размер перехода.

Если не   было   указано   противное,   встроенный   Ассемблер оптимизирует инструкции  перехода,  автоматически   выбирая   самую короткую, и,  следовательно, самую эффективную инструкцию перехода.

Автоматический выбор инструкции перехода применяется  к  инструкции безусловного перехода JMP и ко всем инструкциям условного перехода, когда назначение - метка (а не процедура или функция).

Для инструкции безусловного перехода JMP  встроенный Ассемблер генерирует короткий   переход  (1  байт  кода  операции  и  1  байт смещения), если расстояние до  метки  назначения  внутри  диапазона от -128  до  127  байт;  иначе генерируется ближний переход (1 байт кода операции и 2 байта смещения).

Для инструкции  условного   перехода   генерируется   короткий переход (1  байт кода и 1 байт смещения),  если расстояние до метки назначения от -128 до 127 байт; иначе генерируется короткий переход с обратным  условием,  который  обходит  ближний  переход  на метку назначения (5 байт в итоге). Например оператор

JC Stop

где Stop не внутри диапазона короткого перехода, преобразуется в машинный код

jnc Skip

jmp Stop

Skip: