ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 18.06.2021

Просмотров: 130

Скачиваний: 2

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.

Тема 2. Основные стадии выполнения команды


Лекция 4. Команды обмена данными


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

2. Команды работы со стеком.

3. Команды передачи управления

4. Цепочечные команды




Алгоритм представляет собой формализованное описание логики работы программы. Способы такой формализации могут быть разными: от текстового описания последовательности действий до алгоритма развитых case-систем. Последовательность действий, описываемых алгоритмом, может быть:

линейной — все действия выполняются поочередно, друг за другом;

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

Линейные участки алгоритма обычно содержат команды манипуляции данными, вычисления значений выражений, преобразования данных. В точках ветвления размещают команды сравнения, различных видов перехода, вызова подпрограмм и некоторые другие.

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

команды пересылки данных;

арифметические команды;

логические команды;

команды управления состоянием процессора.

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

собственно пересылки данных;

ввода из порта и вывода в порт;

работы с адресами и указателями;

преобразования данных;

работы со стеком.

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


К группе команд пересылки данных относятся следующие команды:

mov <операнд назначения>, <операнд-источник>

xchg <операнд1>, <операнд2>

MOV — это основная команда пересылки данных.

Командой MOV нельзя осуществить пересылку из одной области памяти в другую. Если такая необходимость возникает, то нужно использовать в качестве промежуточного буфера любой доступный в данный момент регистр общего назначения. Пример (фрагмент программы для пересылки байта из ячейки fls в ячейку fid):

masm

model small

.data

fls db 5

fid db ?

.code

start:

mov al, fls

mov fld, al

end start

Нельзя загрузить в сегментный регистр значение непосредственно из памяти. Для такой загрузки требуется промежуточный объект. Это может быть регистр общего назначения или стек.


Нельзя переслать содержимое одного сегментного регистра в другой сегментный регистр. Это объясняется тем, что в системе команд нет соответствующего кода операции. Но необходимость в таком действии часто возникает. Выполнить такую пересылку можно, используя в качестве промежуточных регистры общего назначения.

Нельзя использовать сегментный регистр CS в качестве операнда назначения. Причина – в архитектуре процессора IA-32 пара CS:IP содержит адрес команды, которая должна выполняться следующей. Изменение командой MOV содержимого регистра CS фактически означало бы операцию перехода, а не пересылки, что недопустимо.

Особенность использования команды MOV определяет необходимо уточнения типа используемых операндов. Для этого существует специальный оператор ассемблера PTR. Правильно записать приведенные ранее команды можно следующим образом (inc-команда инкремента(+1), dec-декремент(-1)):

mov ax,word ptr[bx] ;если [bx] адресует слово в памяти

inc byte ptr[bx] ;если [bx] адресует байт в памяти

dec dword ptr[bx] ;если [bх] адресует двойное слово в памяти

mov word ptr[bx],0 ;если [bх] адресует слово в памяти

Оператор PTR используется во всех сомнительных относительно согласования размеров операндов случаях. Также этот оператор нужно применять, когда требуется принудительно поменять размерность операндов.


2. Команды работы со стеком



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

Для работы со стеком предназначены три регистра:

SS – регистр сегмента стека;

SP/ESP – регистр указателя стека;

ВР/ЕВР – регистр указателя базы кадра стека.

Размер стека зависит от режима работы процессора и ограничивается значением 64 Кбайт (или 4 Гбайт в защищенном режиме). В каждый момент времени доступен только один стек, адрес сегмента которого содержится в регистре SS. Этот стек называется текущим. Для того чтобы обратиться к другому стеку («переключить стек»), необходимо загрузить в регистр SS другой адрес. Регистр SS автоматически используется процессором для выполнения всех команд, работающих со стеком.

Особенности работы со стеком:

запись и чтение данных в стеке осуществляются в соответствии с принципом LIFO (Last In First Out — «последним пришел, первым ушел»);

по мере записи данных в стек последний растет в сторону младших адресов. Эта особенность заложена в алгоритм команд работы со стеком;

при использовании регистров ESP/SP и ЕВР/ВР для адресации памяти ассемблер автоматически считает, что содержащиеся в нем значения представляют собой смещения относительно сегментного регистра SS.


В общем случае стек организован так, как показано на рис. 3.

Регистры SS, ESP/SP и ЕВР/ВР используются комплексно, и каждый из них имеет свое функциональное назначение. Регистр ESP/SP всегда указывает на вершину стека, то есть содержит смещение, по которому в стек был занесен последний элемент. Команды работы со стеком неявно изменяют этот регистр так, чтобы он указывал всегда на последний записанный в стек элемент. Если стек пуст, то значение ESP равно адресу последнего байта сегмента, выделенного под стек. При занесении элемента в стек процессор уменьшает значение регистра ESP, а затем записывает элемент по адресу новой вершины. При извлечении данных из стека процессор копирует элемент, расположенный по адресу вершины, а затем увеличивает значение регистра указателя стека ESP. Таким образом, получается, что стек растет вниз, в сторону уменьшения адресов.


Рис.3 Схема организации стека



Для получения доступа к элементам не на вершине, а внутри стека применяют регистр ЕВР. Регистр ЕВР – регистр указателя базы кадра стека. Например, типичным приемом при входе в подпрограмму является передача нужных параметров путем записи их в стек. Если подпрограмма тоже активно работает со стеком, то доступ к этим параметрам становится проблематичным. Выход в том, чтобы после записи нужных данных в стек сохранить адрес вершины стека в указателе базы кадра стека — регистре ЕВР. Значение в ЕВР в дальнейшем можно использовать для доступа к переданным параметрам.

Начало стека расположено в старших адресах памяти. На рис. 3 этот адрес обозначен парой SS:ffff. Смещение ffff приведено здесь условно. Реально это значение определяется величиной, которая задается при описании сегмента стека в программе. Адресная пара SS:ffff — это максимальное для реального режима значение адреса начала стека, так как размер сегмента в нем ограничен величиной 64 Кбайт (0ffffh).

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

команда PUSH выполняет запись значения <источник> в вершину стека: push <источник>

Алгоритм работы этой команды включает в себя два действия (рис. 4):

1. значение SP уменьшается на 2 – (SP) = (SP) – 2;

2. значение источника записывается по адресу, указываемому парой SS:SP;

команда POP выполняет запись значения из вершины стека по месту, указанному операндом <приемник> (значение при этом «снимается» с вершины стека): pop <приемник>



Рис. 4 Принцип работы команды PUSH


Алгоритм работы команды POP обратен алгоритму команды PUSH (рис.5).

Рис. 5. Принцип работы команды POP


  1. Запись содержимого вершины стека по месту, указанному операндом <приемник>;

  2. Увеличение значения SP – (SP) = (SP) + 2;

команда PUSHA предназначена для групповой записи в стек. По этой команде в стек последовательно записывается содержимое регистров АХ, СХ, DX, BX, SP, BP, SI, DI. Причем записывается оригинальное содержимое SP, то есть то, которое было до выдачи команды PUSHA (рис. 6);


команда PUSHAW почти идентична команде PUSHA. Отличия заключаются в следующем:

при значении атрибута сегмента use16 — алгоритм работы PUSHAW аналогичен алгоритму PUSHA;

при значении атрибута сегмента use32 — алгоритм работы команды PUSHAW не меняется (то есть она нечувствительна к разрядности сегмента и всегда работает с регистрами размером в слово — АХ, СХ, DX, BX, SP, BP, SI, DI), а команда PUSHA чувствительна к разрядности сегмента и при указании 32-разрядного сегмента работает с соответствующими 32-разрядными регистрами (то есть ЕАХ, ЕСХ, EDX, EBX, ESP, EBP, ESI, EDI).



Рис. 6. Принцип работы команды PUSHA


Представленная далее группа команд позволяет сохранить в стеке регистр флагов и записать слово или двойное слово. При этом перечисленные команды – единственные в системе команд процессора, которые позволяют получить доступ (и которые нуждаются в этом доступе) ко всему содержимому регистра флагов:

Команда PUSHF сохраняет регистр флагов в стеке. Работа этой команды зависит от атрибута размера сегмента:

use16 — в стек записывается регистр FLAGS размером два байта;

use32 — в стек записывается регистр ЕFLAGS размером четыре байта.

Команда PUSHFW сохраняет в стеке регистр флагов размером в слово. С атрибутом use16 всегда работает так же, как команда PUSHF.

Команда PUSHFD сохраняет в стеке регистр флагов FLAGS или EFLAGS в зависимости от атрибута размера сегмента (то есть то же, что и PUSHF).

Следующие три команды также выполняют действия, обратные действиям рас­смотренных выше команд:

POPF

POPFW

POPFD

Использование стека практически неизбежно при: вызов подпрограмм; временное сохранение значений регистров; определение локальных переменных в процедуре.


3. Классификация команд передачи управления


Принятие решения о том, какая команда должна выполняться следующей может быть:

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

условным — решение о том, какая команда должна выполняться следующей, принимается на основе анализа некоторых условий или данных.

То, какая команда программы должна выполняться следующей, процессор узнает по содержимому пары регистров CS:(E)IP, в которой:

CS — регистр сегмента кода, в котором находится физический (базовый) адрес текущего сегмента кода;

EIP/IP — регистр указателя команды, в котором находится значение, представляющее собой смещение в памяти следующей выполняемой команды относительно начала текущего сегмента кода.

Таким образом, команды передачи управления изменяют содержимое регистров CS и EIP, в результате чего процессор выбирает для выполнения не следующую по порядку команду программы, а команду в некотором другом участке программы. Конвейер внутри процессора при этом сбрасывается.

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


Команды безусловной передачи управления:

безусловного перехода;

вызова процедуры и возврата из процедуры;

вызова программных прерываний и возврата из программных прерываний.

Команды условной передачи управления:

перехода по результату команды сравнения;

перехода по состоянию определенного флага;

перехода по содержимому регистра ЕСХ/СХ.

Команды управления циклом:

организации цикла со счетчиком ЕСХ/СХ;

организации цикла со счетчиком ЕСХ/СХ с возможностью досрочного выхода из цикла по дополнительному условию.

Решение о том, куда необходимо передать управление в языке ассемблера осуществляется с помощью меток. Метка — это символическое имя, обозначающее определенную ячейку памяти и предназначенное для использования в качестве операнда в командах передачи управления.

Подобно переменной, транслятор ассемблера присваивает любой метке три атрибута:

имя сегмента кода, где эта метка описана;

смещение – расстояние в байтах от начала сегмента кода, в котором описана метка;

тип, или атрибут расстояния, метки.

Последний атрибут может принимать два значения:

near — переход на метку возможен только в пределах сегмента кода;

far — переход на метку возможен только в результате межсегментной передачи управления.

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

Транслятор ассемблера обеспечивает две возможности работы с этим счетчиком:

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

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

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

Команды перехода модифицируют регистр указателя команды EIP/IP и, возможно, сегментный регистр кода CS. Что именно должно подвергнуться модификации, зависит:

от типа операнда в команде безусловного перехода (ближний или дальний);

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

NEAR PTR — прямой переход на метку внутри текущего сегмента кода, при этом модифицируется только регистр EIP/IP (в зависимости от заданного типа сегмента кода use16 или use32) на основе указанного в команде адреса (метки) или выражения, использующего символ извлечения значения счетчика адреса команд ($);