Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Финогенов-основы_языка_ассемблера.doc
Скачиваний:
26
Добавлен:
17.09.2019
Размер:
3.35 Mб
Скачать

Int Программное прерывание

Команда hit инициирует в процессоре процедуру прерывания, в ре­зультате которой управление передается на обработчик прерывания с номером п, который указан в качестве операнда команды int. В стек теку­щей программы заносится содержимое регистра флагов, сегментного ре­гистра CS и указателя команд IP, после чего в регистры IP и CS переда­ется содержимое двух слов из вектора прерывания с номером п (располо­женных по адресам 0:п*4 и 0:п*4+2). Команда сбрасывает флаги IF и TF в 0. Команда iret, которой всегда завершается обработчик прерывания, вос-станаштивает исходное состояние этих флагов.

Пример 1

int 60h

; Переход на прикладной ;обработчик прерывания 60h

Пример 2

mov AH,1

int 21h

;Функция MS-DOS — ввод с ;клавиатуры кода ASCII символа ;Вызов MS-DOS

230

Приложение

Пример 3

mov АН, О

mt 16h

;Функция BIOS (прерывание ;16h) — ввод с клавиатуры ;кода ASCII и скен-кода символа ;Вызов BIOS

Into Прерывание по переполнению

Команда into, будучи установлена вслед за какой-либо арифметичес­кой, логической или строковой командой, вызывает обработчик преры­ваний через вектор 4, если предшествующая команда установила флаг переполнения OF. Перед использованием команды INTO прикладной программист должен поместить в вектор прерывания 4 двухсловный адрес своей программы обработки прерывания по переполнению. Команда сбра­сывает флаги IF и TF в 0. Команда iret, которой всегда завершается обра­ботчик прерывания, восстанавливает исходное состояние этих флагов.

Пример

add into

АХ,ВХ произвольная команда

;Вызов прикладного ;обработчика через вектор 4, ;если OF=1 ;Продолжение программы, если OF=0

Iret Возврат из прерывания

Команда iret возвращает управление прерванному в результате аппа­ратного или программного прерывания процессу. Команда извлекает из стека три верхние слова и помещает их в регистры IP, CS и флагов (см. команду mt). Командой iret должен завершаться любой обработчик преры­ваний, как аппаратных, так и программных (от команды int). Команда не воздействует на флаги, однако она загружает в регистр флагов из стека его исходное содержимое, которое было там сохранено процессором в процессе обслуживания прерывания. Если требуется, чтобы после возвра­та из обработчика программного прерывания командой iret какие-либо флаги процессора были установлены требуемым образом (весьма распрос­траненный прием), их установку надо выполнить в копии флагов в стеке.

386+ IRETD

Возврат из прерывания в 32-разрядном режиме

Команда ire-td используется в защищенном режиме для возврата из обработчика прерывания или исключения, а также для переключения на исходную задачу. В отличие от 16-разрядной команды iret, данная коман­да, завершая обработку прерывания или исключения, снимает со стека 3 двойных слова, содержащие расширенный регистр флагов EFALGS, CS и расширенный указатель команд EIP. В случае переключения задач команда iretd выполняет переключение контекстов задач — сохранение состояния завершающейся задачи в ее сегменте состояния задачи и загрузку регист­ров процессора из сегмента состояния исходной задачи.

Система команд процессоров Intel

231

Jcc Команды условных переходов

Команды, обозначаемые (в книгах, не в программах!) Jcc, осуществ­ляют переход по указанному адресу при выполнении условия, заданного мнемоникой команды. Если заданное условие не выполняется, переход не осуществляется, а выполняется команда, следующая за командой Jcc. Переход может осуществляться как вперед, так и назад в диапазоне + 127...-128 байтов.

В составе команд процессора предусмотрены следующие команды ус­ловных переходов:

Команда Перейти, если

ja выше

jae выше или равно

jb ниже

jbe ниже или равно

jc перенос

jcxz СХ=0

je равно

jg . больше

jge больше или равно

jl меньше

jle меньше или равно

jna не выше

jnae не выше и не равно

jnb не ниже

jnbe не ниже и не равно

jnc нет переноса

jne не равно

jng не больше

jnge не больше и не равно

jnl не меньше

jnle не меньше и не равно

jno нет переполнения

jnp нет четности

jits знаковый бит равен О

jnz не нуль

jo переполнение

jp есть четность

jpe сумма битов четная

jpo сумма битов нечетная

js знаковый бит равен

jz нуль

Условие перехода

CF=0 и ZF=0

CF=0

CF-1

CF=1 или ZF=1

CF=1

CX=0

ZF=1

ZF=0 или SF=OF

SF=OF

SF не равно OF

ZF=1 или SF не равно OF

CF=1 или ZF=1

CF=1

CF=0

CF=0 и ZF=0

CF=0

ZF=0

ZF=1 или SF не равно OF

SF не равно OF

SF=OF

ZF=0 и SF=OF

OF=0

PF=0

SF=0

ZF=0

OF=1

PF=1

PF=1

PF=0

SF=1

ZF=1

Команды условных переходов, осуществляющие переход по условию «выше — ниже», предназначены дчя анализа чисел без знака; команды, осуществляющие переход по условию «больше — меньше», предназначе­ны для анализа чисел со знаком.

232

Приложение

Пример 1

cmp СХ,0 je equal

Пример 2

cmp AX, 10000

ja above

Пример 3

crap AX,1000h

Jg

greater

;CX=0'

;Если да, перейти на метку equal

;Пусть AX=8000h=32768

;<=-32768)

;32768 > 10000. Переход будет

;Пусть AX=8000h=-32768

;(=32768)

j-32768 < lOOOh. Перехода не будет

Пример 4

int 21h ic error

;Вызов системной функции ;Если CF=1 (ошибка), перейти ;на метку error

386+ Команды условных переходов имеют варианты 16- и 32-разряд­ной адресации (при тех же мнемонических обозначениях) и могут пере­давать управление в диапазоне -32768...+32767 байт для сегментов с атри­бутом размера 16 и вдиапазоне -231...+231-1 байт для сегментов с атрибу­том размера 32.

JMP Безусловный переход

Команда jmp передает управление в указанную точку того же или другого программного сегмента. Адрес возврата не сохраняется. Команда не воздействует на флаги процессора.

Команда jmp имеет пять разновидностей:

  • переход прямой короткий (в пределах -128...+ 127 байтов);

  • переход прямой ближний (в пределах текущего программного сег­ мента);

  • переход прямой дальний (в другой программный сегмент);

  • переход косвенный ближний;

  • переход косвенный дальний.

Все разновидности переходов имеют одну и ту же мнемонику jmp, хотя и различающиеся коды операций. Во многих случаях транслятор мо- \ жет определить вид перехода по контексту, в тех же случаях, когда этой невозможно, следует использовать атрибутные операторы: ;.

short — прямой короткий переход; J

near ptr — прямой ближний переход; £-'

far ptr — прямой дальний переход; Ь

word ptr — косвенный ближний переход; ;

dword ptr — косвенный дальний переход.

устема команд процессоров Intel

2Э&

Примеры прямого короткого перехода

jmp short shpt ;Переход на метку shpt

;в пределах +127...-128 байтов

jmp shpt ;To же самое, если shpt

; находится выше по тексту программы

Примеры прямого ближнего перехода

jmp pt ;Переход на метку pt

;в пределах текущего сегмента jmp near ptr pt ;To же самое

Примеры косвенных ближних переходов

Пример 1

raov

BX,offset pt ВХ

;ВХ=адрес точки перехода ;Переход в точку-pt

Пример 2

;В полях данных:

addr dw pt

;В программном сегменте: jmp DS:addr jmp word ptr addr

Пример 3

;B полях данных:

addr dw pt

;B программном сегменте:

mov DI,offse-t addr

jmp [Dl]

Пример 4

;B полях данных: tbl dw ptl

dw pt2

dw pt3 ;B программном сегменте:

mov BX,offset tbl

mov- SI,4

call [BX][SI]

;Ячейка с адресом точки перехода

; Переход в точку pt ;То же самое

;Ячейка с адресом точки перехода

;51=адрес ячейки с адресом точки перехода ; Переход в точку pt

;Ячейка с адресом 1 ;Ячейка с адресом 2 ;Ячейка с адресом 3

;ВХ=адрес таблицы адресов переходов ;51=смещение к адресу pt3 ; Переход в точку pt3

Примеры прямых дальних переходов

jmp far ptr farpt ;Переход на метку farpt в

;другом профаммном сегменте

jmp farpt ".Переход на метку farpt в другом

программном сегменте, если farpt ;объявлена дальней меткой ;директивой farpt label far

234

Приложение

Примеры косвенных дальних переходов

Пример 1

; В полях данных:

addr dd pt ;Поле с двухсловным

;адресом точки перехода ;В профаммном сегменте:

jmp DS:addr ;Переход в точку pt

jrap dword ptr addr ;To же самое

Пример 2

;B полях данных:

addr dd pt ;Поле с двухсловным

;адресом точки перехода ;В профаммном сегменте:

mov DI,offset addr ;П1=адрес поля с адресом

;точки перехода jmp [DI] ;Переход в точку pt

386+ Допустимо использование дополнительных режимов адресации 32-разрядных процессоров. Для 32-разрядных приложений допустимо ис­пользование 32-битовых операндов. В защищенном режиме вместо сегмен­тного адреса сегмента (при дальних переходах) выступает его селектор.

LAHF Загрузка флагов в регистр АН

Команда lahf копирует флаги SF, ZF, AF, PF и CF соответственно в разряды 7, 6, 4, 2 и 0 регистра АН. Значение битов 5, 3 и 1 регистра АН не определено. Команда не имеет параметров и не изменяет флаги про­цессора.

Команда lahf (совместно с командой sahf) дает возможность читать и изменять значения флагов процессора, в том числе флагов SF, ZF, AF и PF, которые нельзя изменить непосредственно. Однако следует иметь в виду, что команда lahf переносит в АН только младший байт регистра флагов. Поэтому нельзя изменить с ее помощью, например, состояние флага OF.

Пример 1

lahf

or sahf

; Регистр АН отображает ;состояние регистра флагов AH,80h ;Установка бита 1 - SF

;3афузка АН в регистр ;флагов, где теперь SF = 1

Пример 2

lahf

and sahf

; Регистр АН отображает ;состояние регистра флагов AH,OBFh ;Сброс бита 6 - ZF

;3афузка АН в регистр ;флагов, где теперь ZF = О

тем а команд процессоров Intel

235

386Р+ LAR Загрузка прав доступа

Команда lar загружает в первый операнд (16- или 32-разрядный ре­гистр) поле атрибутов сегмента из дескриптора сегмента, заданного се­лектором во втором операнде. В качестве операнда с селектором может использоваться 16- или 32-разрядный регистр или ячейка памяти. В опе­ранд-приемник поступают два байта атрибутов селектора с замаскиро­ванным полем старших битов границы сегмента,

LDS Загрузка указателя с использованием регистра DS

Команда Ids считывает из памяти по указанному адресу двойное слово (32 бит), содержащее указатель (полный адрес некоторой ячейки), и заг­ружает младшую половину указателя (т.е. относительный адрес) в указан­ный в команде регистр, а старшую половину указателя (т.е. сегментный адрес) в регистр DS. Таким образом, команда

Ids

reg,mem

эквивалентна следующей группе команд:

niov reg,word ptr mem mov DS,word ptr mem+2

В качестве первого операнда команды Ids указывается регистр обще­го назначения; в качестве второго — ячейка памяти с двухсловным со­держимым. Указатель, содержащийся в этой ячейке, может быть адре­сом как процедуры, так и поля данных. Команда не воздействует на фла­ги процессора.

Пример 1

;В полях данных: addr dd myproc

;В программном сегменте: Ids SI,addr

Пример 2

;В полях данных: mem dw 25

addr dd myproc

;B программном сегменте: mov BX.offset addr

Ids DX,[BX]

;Двухсловный адрес процедуры ;myproc

;DS:SI ' myproc

;Ячейка памяти с произвольным содержимым Двухсловный адрес этой ;ячейки

;ВХ=адрес ячейки addr

;ВХ=смещение ячейки mem, ;В5=сегментный адрес ячейки ;mem

236

Приложение

Пример 3

;В полях данных: dptr dd proc 1

;Полный адрес процедуры

proc 2 ргосЗ

;procl

dd

;Полный адрес процедуры

;ргос!

dd

;Полный адрес процедуры

;ргос!

;В программном сегменте:

mov SI,8 ;Смещение к адресу ргосЗ

Ids DI,dptr[SI] ;DS:DI -> ргосЗ

386+ Допустимо использование 32-разрядного регистра-приемника и 32-битового смещения в памяти, а также дополнительных режимов адре­сации 32-разрядных процессоров. В защищенном режиме вместо сегмент­ного адреса сегмента выступает его селектор.

LEA Загрузка исполнительного адреса

Команда lea загружает в регистр, указанный в команде в качестве пер­вого операнда, относительный адрес второго операнда (не значение опе­ранда!). В качестве первого операнда следует указывать регистр общего на­значения (не сегментный), в качестве второго — ячейку памяти. Команда

lea reg,mem эквивалентна команде

mov reg,offset mem

но у первой команды больше возможностей описания адреса интересую­щей нас ячейки. Команда не воздействует на флаги процессора.

Пример 1

;В полях данных: message db ;В программном сегменте: lea SI, message

Пример 2

; В полях данных:

nmb db '0123456789'

;В программном сегменте:

mov SI, 7

lea DX,nmb[SI]

Пример 3

;B полях данных:

nmb db '0123456789'

;В программном сегменте:

'Идут измерения' ;DS:SI ' message

;Смещение символа ;ОХ=адрес символа '7'

"Система команд процессоров Intel

237

mov mov lea

BX.offset msg

SI,9

SI,[BX][SI]

;Смещение символа '9' ;SI—адрес символа '9'

386+ Допустимо использование 32-битовых операндов и дополнитель-режимов адресации 32-разрядных процессоров.

386+ LEAVE Выход из процедуры высокого уровня

Команда leave выполняет действия, противоположные действиям пос-^(едней команды enter. Она логически уничтожает созданный командой enter стековый кадр со всеми содержащимися в нем локальными пере­менными и подготавливает стек к выполнению команды iret, завершаю­щей переход в вызывающую процедуру. Команда leave не имеет парамет­ров. Более подробное описание и пример см. в описании команды enter.

LES Загрузка указателя с использованием регистра ES

Команда les считывает из памяти по указанному адресу двойное слово (32 бит), содержащее указатель (полный адрес некоторой ячейки), и заг­ружает младшую половину указателя (т.е. относительный адрес) в указан­ный в команде регистр, а старшую половину указателя (т.е. сегментный адрес) в регистр ES. Таким образом, команда

les

reg,mem.

•ивалентна следующей группе команд:

mov reg,word ptr mem mov ES,word ptr mem+2

В качестве первого операнда команды les указывается регистр общего назначения; в качестве второго — ячейка памяти с двухсловным содержи­мым. Указатель, содержащийся в этой ячейке, может быть адресом как про­цедуры, так и поля данных. Команда не воздействует на флаги процессора.

Пример 1

; В полях данных:

addr dd myproc ;Двухсловный адрес процедуры

;myproc ;В программном сегменте:

les SI,addr ;ES:SI

myproc

Пример 2

;В полях данных: mem dw 25

;Ячейка памяти с произвольным содержимым ;Двухсловный адрес этой ячейки

addr dd myproc

;В программном сегменте:

mov BX,onset addr ;ВХ=адрес ячейки addr

238

Приложение

les DX,[BX]

;ОХ=смещение ячейки mem, ;Е5=сегментный адрес ячейки mem

Пример 3

;B полях данных: dptr dd proc 1

dd proc 2

dd ргосЗ ;B программном сегменте:

mov SI, 8

les DI,dptr[SI]

;Полный адрес процедуры prod ;Полный адрес процедуры procl ;Полный адрес процедуры procl

;Смещение к адресу ргосЗ ;ES:DI -* ргосЗ

386+ Допустимо использование 32-разрядного регистра-приемника и 32-битового смещения в памяти, а также дополнительных режимов адре­сации 32-разрядных процессоров. В защищенном режиме вместо сегмент­ного адреса сегмента выступает его селектор.

386+

LFS Загрузка указателя с использованием регистра FS LGS Загрузка указателя с использованием регистра FS LSS Загрузка указателя с использованием регистра FS

Команды считывают из памяти полный указатель, состоящий из се­лектора и 16-битового или 32-битового смещения, и загружают младшую половину указателя (т.е. относительный адрес) в указанный в команде регистр общего назначения, а старшую половину указателя (т.е. селектор) в сегментный регистр, указанный в мнемонике команды.

В качестве первого операнда всех перечисленных команд указывается 16- или 32-разрядный регистр общего назначения; в качестве второго — ячейка памяти с 32- или 48-битовым содержимым. Команда не воздей­ствует на флаги процессора.

Примеры см. в описании команд Ids и les.

386Р+ LGDT

Загрузка регистра таблицы глобальных дескрипторов

Команда Igdt загружает регистр таблицы глобальных дескрипторов (GDTR) из 48-битового псевдодескриптора, содержащего 32-битовый базовый адрес и 16-битовую границу таблицы глобальных дескрипторов, находящейся в памяти. В качестве операнда команды Igdt выступает отно­сительный адрес псевдодескриптора.

386Р+ LIDT

Загрузка регистра таблицы дескрипторов прерываний

Команда lidt загружает регистр таблицы дескрипторов прерываний (IDTR) из 48-битового псевдодескриптора, содержащего 32-битовый ба­ зовый адрес и 16-битовую границу таблицы глобальных дескрипторов, находящейся в памяти. В качестве операнда команды lidt выступает отно­ сительный адрес псевдодескриптора. _

г

Система команд процессоров Intel 239

386Р+ LLDT

Загрузка регистра таблицы локальных дескрипторов

Команда lldt загружает регистр таблицы локальных дескрипторов (LDTR) селектором, определяющим таблицу дескрипторов прерываний (LDT). Селектор LDT должен входить в таблицу глобальных дескрипторов. В качестве операнда команды lldt, содержащего селектор LDT, можно использовать 16- или 32-разрядный регистр общего назначения или 16-или 32-битовое поле памяти.

386Р+ LMSW Загрузка слова состояния машины

Команда Imsw загружает в регистр слова состояния машины (так на­зывается младшая половина управляющего регистра процессора CRO) слово состояния машины, взятое из указанного в команде операнда. В качестве операнда можно использовать 16- или 32-разрядный регистр об­щего назначения или 16- или 32-битовое поле памяти.

Команду Inisw можно использовать для перевода процессора из реаль­ного в защищенный режим или наоборот. В первом случае после чтения слова состояния командой smsw надо установить в нем бит 0 (бит РЕ) и загрузить назад в CRO командой Imsw. Во втором случае после после чте­ния слова состояния командой smsw надо сбросить в нем бит 0 и загрузить назад в CRO командой Imsw.

LOCK Запирание шины

Префикс lock, помещенный перед командой, устанавливает сигнал на линии LOCK системной шины и запрещает доступ к шине другим процессорам на время выполнения данной команды, Этот префикс пред­назначен для использования в многопроцессорных многозадачных систе­мах для обеспечения исключительного доступа к памяти данного процес­са (и данного процессора) на время проверки или модификации некото­рой ячейки памяти. Типичный пример операций такого рода — работа с семафорами.

Если два (или более) процесса, идущие на разных процессорах, ис­пользуют какой-либо общий ресурс, например, файл или лазерный диск, то необходимо обеспечить механизм, запрещающий одновременное об­ращение процессов к общему ресурсу. Эта задача решается с помощью семафора — ячейки памяти (байта или даже бита), состояние которого отражает доступность или, наоборот, занятость ресурса.

Если процессору понадобился общий ресурс, он читает состояние семафора и, если ресурс занят, продолжает опрашивать семафор до тех пор, пока другой процессор, использующий в настоящий момент общий ресурс, не освободит его. Обнаружив, что ресурс свободен, первый про­цессор устанаачивает семафор в состояние «занят» и использует ресурс. Закончив работу с ресурсом, процессор сбрасывает его семафор и дает возможность другому процессу обратиться к тому же ресурсу.

Описанный алгоритм будет работать только в том случае, если опера­ция чтения-модификации-записи семафора будет выполняться в непре-

240

рываемом режиме. В противном случае оба процесса могут, одновременно обратившись к семафору, увидеть, что ресурс свободен, и начать его со­вместное использование. Избежать такой ситуации и позволяет префикс lock в сочетании с командами типа btr или bts, выполняющими комплек- 1 сные операции проверки и сброса или проверки и установки бита.

Будем считать, что семафор расположен в бите 0 байта по адресу sem, причем сброшенное состояние бита свидетельствует о занятости ресурса, а установленное состояние о том, что ресурс свободен. Тогда типичная про­цедура ожидания освобождения ресурса выглядит следующим образом:

mov Sl.oftset sem ;Адрес байта с семафором getsem:

lock btr byte ptr [SI],1 ;Проверка и сброс бита О

jnc getsem

Проверка состояния семафора и его модификация (запись в бит сема­фора 0, т.е. признака «занят») осуществляется в одной команде btr. На время выполнения этой команды шина многопроцессорной системы бло­кируется префиксом lock,'и другой процессор обратиться к тому же сема­фору не может. Блокировка шины снимается уже после того, как семафор будет переведен в состояние занятости.

Если при обращении к байту sem оказывается, что в бите семафора записан 0, т.е. ресурс занят другим процессом, команда btr сбрасывает флаг CF (путем переноса в него содержимого анализируемого бита), что приводит к многократному повторению процедуры getsem, т.е. к циклу ожидания освобождения ресурса.

Типичная процедура освобождения занятого данным процессом ре­сурса выглядит следующим образом:

freesem:

lock bts byte ptr [SI],1 ;Проверка и установка бита О

Собственно говоря, никакая проверка здесь не выполняется, однако процесс будет освобождать ресурс лишь если он этот ресурс использует, и проверять состояние флага в этой операции нет необходимости. Однако и здесь необходимо запирание шины на время записи в бит семафора 1, чтобы исключить одновременное обращение двух процессов к одной ячейке памяти.

386+ Префикс lock может быть использован только со следующими командами (и лишь при условии, что при их выполнении происходит обращение к памяти): adc, add, and, bt, bts, btr, btc, or, sbb, sub, xor, xchg, dec, inc, neg, not.

команд процессоров Intel 241

i