Структура программы на языке ассемблер

      Комментарии к записи Структура программы на языке ассемблер отключены

Архитектура и система команд микропроцессора x86

Лабораторная работа 10

Начальные сведения о языке Ассемблер

Аппаратная поддержка языка

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

Программируемая структура процессора

Для организации вычислений микропроцессор i8086 имеет в своём составе 14 шестнадцатиразрядных регистров, которые обеспечивают выполнение программы:

Регистры общего назначения Сегментные регистры Специальные регистры
AH AL AX CS SP Указатель стека
BH BL BX DS BP Указатель базы стека
CH CL CX ES IP Указатель инструкций
DH DL DX SS FLAGS Регистр флагов
SI
DI

Регистры общего назначения:

AX(AH, AL), BX(BH, BL), CX(CH, CL), DX(DH, DL) делятся программно на пары однобайтных регистров и могут использоваться для хранения данных. Разбиение на однобайтные регистры позволяет увеличить общее число регистров;

SP, BP – указатель и база стека, соответственно, обеспечивают доступ к данным в стеке, могут использоваться для хранения данных, но делать это не рекомендуется, так как при этом возможно нарушение адресации в стеке, особенно при использовании SP.

SI, DI – шестнадцатиразрядные регистры для хранения данных.

CS, DS, ES, SS – хранят адреса сегментов в памяти, не могут использоваться для хранения данных.

IP – регистр инструкций – хранит адрес (смещение) следующей исполняемой команды.

FLAGS – регистр флагов содержит набор битовых флагов, определяющий текущее состояние процессора и результат выполнения предыдущей команды (таблица 2.1).

Таблица 2.1
Регистр флагов процессора
Флаг Название Назначение
О Переполнение Переполнение при выполнении арифметических операций
D Направление Направление пересылки данных при выполнении строковых команд
I Прерывание Разрешает/Запрещает внешние прерывания
T Пошаговый режим Останов после выполнения каждой команды(используется отладчиками)
S Знак Знак результата выполненной команды(0 – плюс, 1 – минус)
Z Ноль Значение результата выполненной команды(0 – ненулевой, 1 – нулевой)
A Внешний перенос Используется для специальных арифметических операций
P Контроль чётности Число единиц в операнде(0 – нечётное, 1 – нечётное)
C Перенос Содержит перенос из старшего бита при выполнении арифметических операциях

Структура памяти

Память, с которой взаимодействует процессор при обработке программ, называется Оперативным Запоминающим Устройством (ОЗУ) или Random Access Memory (RAM). Она состоит из набора однобайтных ячеек, обращение к которым происходит по их номерам (физическим адресам). Число ячеек зависит от ширины шины адреса и составляет для процессора i8086 (ширина шины адреса равна 20) 220 – ячеек (1Мбайт). Для современных процессоров с шириной шины адреса 32 объём ОЗУ может доходить до 4 Гбайт.

Данные можно читать или сохранять в ОЗУ байтами, указывая номер требуемой ячейки или словами (2 байта), указывая адрес младшей ячейки памяти и вводя специальный префикс.

Сегментация памяти

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

Один из них – сегментный, он хранит адрес начала блока памяти, который и называется сегментом. Если к шестнадцати разрядам сегмента мысленно справа дописать четыре двоичных нуля(16+4=20), то получим физический адрес начала сегмента в ОЗУ. Второй регистр хранит величину смещения адреса требуемой ячейки от начала сегмента. Адрес ячейки памяти записывается в виде двойного слова (4 байта): :.

Сегмент всегда начинается с ячейки, номер которой заканчивается на 4 двоичных (или один шестнадцатеричный) нуля. Минимальная длина сегмента 16 байтов (параграф). Максимальная длина определяется длиной регистра, хранящего смещение и равна 216(64 Кбайта).

Пара регистров CS:IP(:) определяют адрес следующей команды программы.

Для адресации данных используются сегментные регистры DS и ES, а в качестве регистров, хранящих смещение, используются регистры общего назначения BX, SI, DI. Для работы с сегментом стека используют сегментный регистр SS и регистр BP.

Структура программы на языке Ассемблер

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

segment

команды или директивы

ends

[

segment

команды или директивы

ends ]

end

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

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

Каждая программа содержит сегменты данных и команд, но минимально должна содержать сегмент команд.

Строка программы, в общем случае, состоит из четырех полей:

Поле метки Поле операции Поле операндов Поле комментария
M1: Add AX, BX ; сложение

Имена данных, процедур, сегментов или метки команд могут состоять не более чем из 31 латинских букв и цифр, причем первым символом должна быть обязательно буква. Большие и маленькие буквы не различаются.

Директивы ассемблера

Директивой называется команда транслятору для выполнения определённых данной директивой действий, сама директива в текст транслированной программы не включается.

1. Директива задания исходных данных:

[] d [,, , . . .]

  • — имя массива данных, по которому к ним можно обратиться из команды;
  • d(define)– определяет начало массива данных;
  • — размер констант, входящих в массив:
b байт,
w Слово (два байта),
d двойное слово,
q учетверённое слово,
t десять байтов;
  • — числовой или символьный элемент массива данных.

В ассемблере используется несколько типов констант:

десятичные – последовательность цифр от 0 до 9;

шестнадцатеричные – последовательность шестнадцатеричных цифр от 0 до 9 и от А или а до F или f завершающаяся буквой H или h, первой должна быть десятичная цифра или 0;

восьмеричные – последовательность цифр от 0 до 7, завершающаяся буквами Q или q;

двоичные – последовательность цифр от 0 до 1, завершающаяся буквой B или b;

символьные – символ или группа символов, заключённые в кавычки;

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

Например,

data1 db 123, 0a2h, 75q, 110011b, ‘a’, ‘пример’, ?, ?

Для заполнения больших массивов используется директива dup (duplicate):

dup()

— задаёт количество размещаемых в памяти данных, определяемых образцом;

— любая допустимая группа констант.

Например,

data2 db 23 dup(1, 2, ‘x’)

выделяет в памяти 23 · 3=69 байтов и заносит в них образец 1, 2, ‘x’, 1, 2, ‘x’, … .

2. Директива использования сегментных регистров по умолчанию:

assume:[, :, …]

Как отмечалось выше, для задания адреса в памяти требуется два регистра, один из них всегда сегментный, поэтому в команде при обращении к памяти приходится набирать имя сегментного регистра, часто одного и того же. Директива assumeпозволяет избежать этого. Транслятор сопоставляет имя массива данных и автоматически подставляет сегментный регистр, заданный для сегмента, в котором расположен данный массив. Слово nothingпоказывает, что данный сегментный регистр не адресуется по умолчанию. Директива assume может использоваться в программе при каждом изменении сегмента для данного сегментного регистра, но обязательно в начале сегмента, где она задаёт по умолчанию сегментный регистр для сегмента кодов.

Например,

assumecs:code, ds:data1, es:nothing

Здесь code и data1 – имена сегментов кодов и данных, соответственно.

Режимы адресации

1. Регистровая прямая — операнд находится в регистре.

Обозначение — ,

— АХ, ВХ, СХ, DX, SI, DI, BP, SP, AL, BL, СL, DL, AH, BH, CH, DH.

Пример:

mov АХ,SI ; переслать содержимое регистра SI в регистр АХ.

2. Непосредственная -непосредственный операнд (константа) присутствует в команде.

Обозначение -.

Пример:

mov AX, 093Ah ; занести константу 093Ah в регистр АХ.

3. Прямая — исполнительный адрес операнда присутствует в команде.

Обозначение — +/-.

Пример:

mov AX, WW ; переслать в АХ слово памяти с именем WW

mov BX, WW+2 ; переслать в ВХ слово памяти отстоящее от переменной с именем WW на 2 байта.

4. Регистровая косвенная — регистр содержит адрес операнда.

Обозначение — [],

— ВХ. ВР. SI, DI.

Пример:

mov [ BX ], CL ; переслать содержимое регистра CL по адресу, находящемуся в регистре ВХ.

5. Регистровая относительная — адрес операнда вычисляется как сумма содержимого регистра и смещения.

Обозначение — [] или [],

— SI или DI индексная адресация, ВХ или ВР — базовая адресация.

Пример:

mov АХ, WW[SI] ; переслать в АХ слово из памяти, адрес которого вычисляется как сумма содержимого регистра SI и смещения WW.

6. Индексно — базовая — адрес операнда вычисляется как сумма содержимых базового и индексного регистров и смещения.

Обозначение — [][] или [][] или [][] константное выражение,

где- SI или DI,- ВХ или ВР.

Пример:

mov [BX+ SI+ 2], CL; переслать содержимое регистра CL по адресу, вычисляемому как сумма содержимого регистров ВХ, SI и константы 2.

Статьи к прочтению:

Как написать программу на Assembler часть 1


Похожие статьи:

  • Структура программы на языке pascal

    Введение Под языком программирования мы будем понимать совокупность средств и правил представления алгоритма в виде, приемлемом для компьютера….

  • Структура программы на языке си

    Программа на языке Си определяется как совокупность одного или нескольких модулей. Модулем является самостоятельно компилируемый файл. Модуль содержит…