Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

ПСМПС (лаб)

.pdf
Скачиваний:
20
Добавлен:
10.06.2015
Размер:
1.42 Mб
Скачать

21

P <n> – выполнение n команд программы с выполнением подпрограмм и циклов, как одной команды (по умолчанию n = 1).

T <n> – выполнение n команд со входом в подпрограммы и циклы (по умолчанию n = 1).

E – медленное последовательное выполнение команд до нажатия любой клавиши.

D<type> <seg:addr> L <n> – вывод дампа n байтов памяти в формате type начиная с адреса seg:addr. В качестве параметра seg может использоваться обозначение сегментного регистра или число. По умолчанию seg = DS.

Параметр type может принимать значения: A – только коды ASCII, B –

байты и коды ASCII, W – слова (например, DB DS:100h L 100h).

D<type> <seg:addr1> <addr2> – вывод дампа памяти от адреса seg:addr1 до seg:addr2.

R <reg> – вывод содержимого регистра reg и запрос на его измене-

ние;

R <reg> = <n> – занесение в регистр reg значения n.

E<type> <seg:addr> <n1>, <n2> ... – занесение в память начиная с адреса seg:addr значений n1, n2 в формате type.

N<radix> – изменение системы счисления в параметрах командной строки. Параметр может принимать значения 10 и 16. Данная команда без параметра выводит текущее значение системы счисления.

BP <seg:addr> – установка очередной точки останова по адресу seg:addr. По умолчанию seg = СS.

BP <seg:addr> <step> – установка точки останова по адресу seg:addr с пропуском ее при выполнении первые step раз. Используется для отладки многошаговых циклов.

BL – вывод списка точек останова с их адресами.

BC <n> – снятие точки останова с номером n.

BC * – снятие всех точек останова.

BD <n> – выключение (но не снятие) точки останова с номером n.

BС <n> – включение (но не установка новой точки останова) точки останова с номером n.

Для полного использования возможностей отладчика следует при компиляции программы указать ключ /ZI.

> MASM /ZI TEXT.ASM

Этот ключ управляет включением в объектный файл номеров строк исходной программы и другой информации, не требуемой при выполнении

22

программы, но используемой отладчиком. Для поддержки отладчика компилятор поддерживает еще одну опцию – /ZD. Этот ключ может быть использован для включения в отладочную информацию данных о нумерации строк исходного текста.

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

2.2. Команды пересылки данных

Исходя из общепринятой функциональной классификации инструкций современного микропроцессора Intel-архитектуры, все команды, которые включены в группу команд пересылки данных, подразделяются на три подгруппы: инструкции общего назначения, инструкции ввода/вывода, инструкции для работы со стеком и команды преобразования.

Рассмотрим подробно только основные, наиболее часто встречающиеся при программировании инструкции.

К подгруппе команд общего назначения относятся инструкции MOV, XCHG, BSWAP.

Команда MOV (move) имеет следующий формат:

mov <destination >, <source>

Здесь <source> – операнд-источник, а <destination> – операндприемник. Это базовая команда пересылки данных. Действия команды MOV заключаются в том, что она копирует содержимое источника в приемник, источник при этом не изменяется. Команда MOV действует аналогично операторам присваивания языков высокого уровня, то есть команда

mov AX,BX

эквивалентна выражению

АХ := BХ;

языка Паскаль или

АХ = BХ;

23

языка Си, за исключением того, что команда ассемблера позволяет работать не только с переменными в памяти, но и со всеми регистрами процессора.

В качестве источника для MOV могут использоваться: число (непосредственный операнд), регистр общего назначения, сегментный регистр или переменная (то есть операнд, находящийся в памяти). В качестве приемника – регистр общего назначения, сегментный регистр (кроме CS) или переменная. Оба операнда должны быть одного и того же размера – байт, слово или двойное слово. Нельзя выполнять пересылку данных с помощью MOV из одной переменной в другую, из одного сегментного регистра в другой и нельзя помещать в сегментный регистр непосредственный операнд – эти операции выполняют двумя командами MOV (из сегментного регистра в обычный и уже из него в другой сегментный) или с использованием команд для работы со стеком.

Инструкция XCHG (exchange – обмен) выполняет обмен операндов между собой:

xchg <operand1>, <operand2>

Содержимое второго операнда копируется в первый операнд, а старое содержимое первого операнда во второй. XCHG можно выполнять над двумя регистрами или над регистром и переменной. Инструкция

xchg EAX,EBX;

эквивалентна трем операторам присваивания на языке Си:

temp = EAX; EAX = EBX; EBX = temp;

Тогда как выполнение следующей команды не приводит к каким-либо действиям:

xchg AL, AL

Другой весьма полезной инструкцией, выполняющей обмен данных, является команда BSWAP (bytes swap – обмен байтов):

24

bswap <reg32>

Данная команда обращает порядок байтов в 32-битном регистре. Биты 0 – 7 (младший байт младшего слова) меняются местами с битами 24 – 31 (старший байт старшего слова), а биты 8 – 15 (старший байт младшего слова) меняются местами с битами 16 – 23 (младший байт старшего слова). Например:

mov EAX,12345678h

bswap EAX

; теперь в ЕАХ находится 78563412h

Для обращения порядка байтов в 16-битном регистре следует использовать команду XCHG:

xchg AL,AH

; обратить порядок байт в АХ

В процессорах Intel команду BSWAP можно использовать и для обращения порядка байт в 16-битных регистрах, но в некоторых совместимых процессорах других фирм этот вариант BSWAP не реализован.

Вторая по важности подгруппа команд пересылки данных предназначена для работы со стеком. Это команды PUSH, POP, PUSHA, POPA, PUSHAD, POPAD.

Инструкция PUSH (push – толчок, пихание) размещает данные в стеке:

push <source>

Операндом-источником данной инструкции может быть регистр, сегментный регистр, непосредственный операнд или переменная. Фактически эта команда копирует содержимое источника в память по адресу SS:[SP] и уменьшает SP на размер источника в байтах (2 или 4). Команда PUSH практически всегда используется в паре с POP (pop up – выскочить наверх), которая извлекает из стека верхний элемент:

pop <destination>

Так, например, чтобы скопировать содержимое одного сегментного регистра в другой (что нельзя выполнить одной командой MOV), можно использовать такую последовательность команд:

25

push CS

 

pop DS

;теперь DS указывает на тот же сегмент, что и CS

Типичным применением команд PUSH/POP является временное хранение переменных, например:

push EAX

; сохраняет текущее значение ЕАХ

...

;

здесь располагаются какие-нибудь команды,

pop EAX

; которые используют ЕАХ

;

восстанавливает старое значение ЕАХ

Начиная с 80286, команда

push ESP

помещает в стек значение ESP до того, как эта же команда его уменьшит, в то время как в процессоре 8086 SP помещался в стек уже уменьшенным на два.

Команда POP помещает в приемник слово или двойное слово, находящееся в вершине стека, увеличивая ESP на 2 или 4 соответственно. Инструкция POP выполняет действие, полностью обратное PUSH. Приемником может быть регистр общего назначения, сегментный регистр, кроме CS (чтобы загрузить CS из стека, надо воспользоваться командой RET), или переменная. Если в роли приемника выступает операнд, использующий ESP для косвенной адресации, команда POP вычисляет адрес операнда уже после того, как она увеличивает ESP.

Инструкции PUSHA/PUSHAD позволяют разместить в стеке регистры общего назначения. Команда PUSHA помещает в стек регистры в следующем порядке: АХ, СХ, DX, BХ, SP, BР, SI И DI. Команда PUSHAD помещает в стек ЕАХ, ЕСХ, EDX, ЕBХ, ESP, EBP, ESI И EDI. (В случае SP и ESP ис-

пользуется значение, которое находилось в этом регистре до начала работы команды). Инструкции POPA/POPAD выполняют прямо противоположные действия предыдущим инструкциям.

Взаимодействие микропроцессора с периферийными устройствами

осуществляется

посредством

исполнения

специальных

инструк-

ций ввода/вывода,

которые позволяют обмениваться данными

с порта-

ми ввода/вывода. Порт ввода/вывода представляет собой регистр периферийного устройства, за которым так же, как и за ячейкой памяти, закреплен собственный адрес в отдельном адресном пространстве ввода/вывода.

26

К инструкциям ввода/вывода относятся две базовые команды IN и OUT. На командах IN и OUT строится все общение процессора с устройствами ввода-вывода – клавиатурой, жесткими дисками, различными контроллерами – и используются они, в первую очередь, в драйверах устройств.

Инструкция IN считывает данные из порта:

in <destination>, <source>

Она копирует данные из порта ввода/вывода, номер которого указан в источнике, в приемник. Приемником может быть только AL, АХ или ЕАХ. Источник – это или непосредственный операнд, или DX, причем непосредственно можно указывать только номера портов не больше 255.

Инструкция OUT копирует данные из источника (AL, АХ или ЕАХ) в порт ввода-вывода

out <destination>, <source>,

номер, которого указан в приемнике. Приемник может быть либо непосредственным номером порта, либо регистром DX. Например, чтобы включить динамик компьютера, достаточно выполнить команды:

in AL,61h or AL,3 out 61h,AL

Кроме рассмотренных выше инструкций пересылки данных в арсенале команд микропроцессоров Intel архитектуры имеется также значительное число других команд, предназначенных для этих целей. К ним относятся инструкции трансляции, пересылки со знаком, конвертирования и др.: XLAT, MOWSX, CWD, CBW.

Процессоры старших современных поколений в значительной степени расширили набор разнообразных инструкций, в том числе команд пересылки данных.

2.3. Логические команды и команды двоичной арифметики

Логические команды предназначены для побитовых логических операций «И», «ИЛИ», «НЕ», «ИСКЛЮЧАЮЩЕЕ ИЛИ». Логические команды

27

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

Команда AND выполняет побитовое «логическое И»:

and <destination>, <source>

над приемником (регистр или ячейка памяти) и источником (число, регистр или ячейка памяти; источник и приемник не могут быть ячейками памяти одновременно) и помещает результат в приемник. Любой бит результата равен «1», только если соответствующие биты обоих операндов были равны «1», и равен «0» в остальных случаях. Наиболее часто AND применяют для выборочного обнуления отдельных бит, например, команда

and al,00001111b

обнулит старшие четыре бита регистра AL, сохранив неизменными четыре младших.

Флаги OF и CF регистра флагов обнуляются, тогда как SF, ZF и PF устанавливаются в соответствии с результатом, а флаг AF остается неопределенным.

Команда OR выполняет побитовое «логическое ИЛИ» над приемником (регистр или переменная) и источником (число, регистр или переменная; источник и приемник не могут быть переменными одновременно) и помещает результат в приемник:

or < destination>, < source>

Любой бит результата равен «0», только если соответствующие биты обоих операндов были равны «0», и равен «1» в остальных случаях. Команду OR чаще всего используют для выборочной установки отдельных бит, например, команда

or al,00001111b

приведет к тому, что младшие четыре бита регистра AL будут установлены в 1. При выполнении команды OR флаги OF и CF обнуляются, SF, ZF и PF устанавливаются в соответствии с результатом, AF не определен.

Команда XOR выполняет побитовое «логическое исключающее ИЛИ» над приемником (регистр или переменная) и источником (число, регистр или

28

переменная; источник и приемник не могут быть переменными одновременно) и помещает результат в приемник:

xor <destination>, <source>

Любой бит результата будет равен «1», если соответствующие биты операндов различны, и нулю, если одинаковы. XOR используется для самых разных операций, например:

xor АХ,АХ ; обнуление регистра ах

или

xor АХ,BХ xor BХ,АХ

xor АХ,BХ ; меняет местами содержимое ах и bх

Оба этих примера могут выполняться быстрее, чем соответствующие очевидные команды

mov AX,0

или

xchg AX,BX

Исполнение команды NOT приводит к тому, что каждый бит приемника (регистр или переменная), равный нулю, устанавливается в «1», и каждый бит, равный «1», сбрасывается в «0»:

not <destination>

В результате выполнения данной инструкции флаги процессора не затрагиваются.

Инструкция TEST вычисляет результат действия побитового «логического И» над приемником (регистр или переменная) и источником (число, регистр или переменная; источник и приемник не могут быть переменными одновременно) и устанавливает флаги SF, ZF и PF в соответствии с полученным результатом, не сохраняя результат (флаги OF и CF обнуляются, значение AF не определено). Инструкция имеет следующий синтаксис:

test <destination>, <source>

29

Инструкция TEST, так же, как и СMР, используется в основном в сочетании с командами условного перехода (JXX), условной пересылки данных (CMOVXX) и условной установки байт (SETXX).

Двоичные арифметические команды имеют некоторые особенности, которые должны быть учтены при программировании на ассемблере.

Микропроцессор выполняет сложение операндов по правилам сложения двоичных чисел. Результаты такого сложения верны до тех пор, пока значение этого результата не превышает размерности поля операнда. В противном случае происходит перенос старшего разряда. Так, при сложении операндов в один байт результат не должен превышать 255. Сложение двух чисел 253 и 6 в двоичном коде выглядит следующим 11111101 + 00000110 = 1 00000011. Результат вышел за пределы восьми бит, и правильное его значение укладывается в 9 битов, в 8-битном поле операнда осталось значение 3, что является неверным результатом. Микропроцессор фиксирует выполнение такой операции установкой флага переноса CF.

Команда ADD выполняет арифметическое сложение приемника и источника, помещает сумму в приемник, не изменяя содержимое источника:

add <destination>, <source>

Приемник может быть регистром или ячейкой памяти (переменной), источник может быть числом, регистром или переменной, но нельзя использовать переменную одновременно и для источника, и для приемника. Команда ADD никак не различает числа со знаком и без знака, но, употребляя значения флагов CF (перенос при сложении чисел без знака), OF (перенос при сложении чисел со знаком) и SF (знак результата), можно использовать ее и для тех, и для других.

Команда вычитает источник из приемника и помещает разность в приемник:

sub <destination>, <source>

Приемник может быть регистром или переменной, источник может быть числом, регистром или переменной, но нельзя использовать переменную одновременно и для источника, и для приемника. Точно так же, как и команда ADD, SUB не делает различий между числами со знаком и без знака, но флаги позволяют использовать ее как для тех, так и для других.

30

Команда MUL выполняет умножение содержимого источника (регистр или переменная) и регистра AL, АХ, ЕАХ (в зависимости от размера источника) и помещает результат в АХ, DX:AX, EDX:EAX соответственно:

mul <source>

Если старшая половина результата (АН, DX, EDX) содержит только нули (результат целиком поместился в младшую половину), флаги CF и OF устанавливаются в 0, иначе – в 1. Значение остальных флагов (SF, ZF, AF и PF) не определено.

Команда DIV выполняет целочисленное деление без знака AL, АХ или ЕАХ (в зависимости от размера источника) на источник (регистр или переменная) и помещает результат в AL, АХ или ЕАХ, а остаток – в АН, DX или EDX соответственно

div < source>

Результат всегда округляется в сторону нуля, абсолютное значение остатка всегда меньше абсолютного значения делителя. Значения флагов CF, OF, SF, ZF, AF и PF после этой команды не определены, а переполнение или деление на ноль вызывает исключение #DE (ошибка при делении) в защищенном режиме и прерывание 0 – в реальном.

Команда INC увеличивает приемник (регистр или переменная) на 1:

inc <destination>

Единственное отличие этой команды от ADD состоит в том, что флаг CF не затрагивается. Остальные арифметические флаги (OF, SF, ZF, AF, PF) устанавливаются в соответствии с результатом сложения.

Команда уменьшает приемник (регистр или переменная) на 1

dec <destination>

Единственное отличие этой команды от SUB состоит в том, что флаг CF не затрагивается. Остальные арифметические флаги (OF, SF, ZF, AF, PF) устанавливаются в соответствии с результатом вычитания.