Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Процессор х86.docx
Скачиваний:
21
Добавлен:
23.04.2019
Размер:
725.45 Кб
Скачать
  1. Процессор х86: инструкции цикла. Ожидание готовности пу с тайм-аутом.

В процессоре х86 аппаратно реализован цикл со счетным параметром. В качестве счетчика цикла используется регистр ecx. Инструкция цикла имеет мнемокод loop. В нижеследующем примере участок кода, заключенный между меткой lpm и инструкцией loop lpm, будет выполнен 100 раз:

mov ecx, 100

lpm:

. . .

. . .

loop lpm

В ходе выполнения инструкции loop содержимое регистра ecx аппаратно уменьшается на единицу и после этого сравнивается с нулем. Поэтому, если перед началом цикла регистр ecx обнулить, то цикл выполнится 10000000h (4294967296) раз.

В программах, осуществляющих обмен данными с периферийными устройствами для организации тайма-аута используются инструкции цикла с дополнительной проверкой флага нуля loopz и loopnz или их эквиваленты loope и loopne.

При выполнении инструкции loopz/loope переход на метку осуществляется при одновременном выполнении двух условий: содержимое регистра ecx не равно 0 и флаг нуля установлен.

При выполнении инструкции loopnz/loopne переход на метку осуществляется при одновременном выполнении двух условий: содержимое регистра ecx не равно 0 и флаг нуля сброшен.

  1. Процессор х86: безусловный переход и виды меток.

Инструкция безусловного перехода имеет мнемокод jmp, сокращение от jump - прыжок, и имеет один операнд – адрес перехода, задаваемый обычно при помощи метки.

В тексте программы на ассемблере меткой можно пометить любую инструкцию. Для именования меток используются те же правила, что и для задания имен переменных: последовательность из букв и цифр, начинающаяся с буквы. Компилятор создает таблицу меток, в которую помещает идентификаторы меток и адреса инструкций, которые отмечены данными метками, а затем в тексте программы во всех инструкциях управления ходом вычислительного процесса заменяет идентификаторы меток их значениями, т.е. адресами инструкций, на которые будет осуществляться переход. Например, если в тексте программы имеется следующий код, и инструкция, помеченная меткой m1, окажется размещенной по адресу 50637844h, то инструкция jmp m1, будет эквивалентной

jmp 50637844h.

Метки могут быть трех типов: дальние, ближние и короткие. Дальняя метка состоит из двух частей: сегмента и адреса в данном сегменте, ближняя метка содержит адрес в текущем сегменте кода, а короткая – содержит не абсолютный адрес, а относительный. Относительный адрес – это расстояний в байтах до точки перехода, т.е. это число со знаком, которое прибавляется к текущему значению программного счетчика. Дальние метки применялись в основном в 16-разрядном реальном режиме и в настоящее время в прикладном программировании не используются. Поэтому термин «ближняя» вышел из употребления и, когда говорят просто метка, то имеют в виду ближнюю метку. В примере, представленном выше, метка m1 рассматривается как ближняя. Короткие метки позволяют создавать позиционно-независимый код, т.е. код, который можно без изменения адресов перехода поместить в любое место адресного пространства процесса. Современные оптимизирующие компиляторы, как правило, генерируют короткие метки, и, более того, многие операционные системы требуют, чтобы прикладные программы использовали только короткие метки. Таким образом, в нашем примере, если инструкция

mov ebx, b имеет адрес 50637944h, оптимизирующий компилятор сгенерирует инструкцию jmp –100h.

В большинстве вычислительных систем продолжительность выполнения операций in и out составляет около 1 мкс и не зависит от частоты процессора и шины. В приведенном ниже примере проверяется регистр состояния ПУ, в котором готовности устройства соответствует установка в 1 бита № 2. Выход из цикла осуществляется или по готовности устройства или по выполнении заданного количества повторений. На выходе из цикла можно проверить флаг нуля. Если флаг сброшен, то устройство готово, если установлен, то прошло 2 миллисекунды (цикл выполнился 2000 раз), а устройство так и не готово, т.е. время ожидания истекло:

char *ps, srd[]="готово", stm[]="тайм-аут";

. . .

mov ecx, 2000

mov dx, <адр.рег.упр.>

m: in al, dx

test al, 0x04

loopz m

jnz r

lea ebx, stm

jmp c

r: lea ebx, srd

c: mov ps, ebx