- •6. Лекция. Язык программирования ассемблер ia-32 (Intel Architecture -32bit)
- •6. Язык программирования ассемблер ia-32
- •6.1. Структура программы на языке ассемблер
- •6.2. Директивы языка ассемблера ia-32
- •6.2.1. Псевдокоманды определения переменных
- •6.2.2. Организация программы
- •6.3. Управление потоком выполнения программы
- •6.3.1. Условные переходы и флаги кодов условий
- •6.3.2. Команды сравнения
- •6.3.3. Безусловный переход
- •6.4. Логические команды, команды сдвига и циклического сдвига
- •6.4.1. Логические операции
- •6.4.2. Операции сдвига и циклического сдвига
- •6.4.3. Программа упаковки цифр
- •6.5. Другие команды
- •6.5.1. Вычитание
- •6.5.2. Команды умножения и деления
- •Imul reg,src(исходный)
- •Imul src и mul src
- •Idiv src и div src
- •6.5.3. Команды мультимедийного расширения
- •6.5.4. Векторные команды
- •6.6. Подпрограммы
- •6.6.1. Вложенность подпрограмм и стек процессора
- •6.6.2. Организация стека
- •6.6.3. Передача параметров
- •6.7. Примеры программ
- •6.7.1. Программа для вычисления скалярного произведения двух векторов
- •6.7.2. Программа сортировки байтов
- •6.7.3. Подпрограммы для вставки и удаления элементов связного списка
- •6.8. Различия между программами в ехе - и сом - файлах
- •6.8.1. Пример программы типа сом
- •6.8.2. Пример программы типа ехе
6.2. Директивы языка ассемблера ia-32
6.2.1. Псевдокоманды определения переменных
Псевдокоманда— это директива ассемблера, которая приводит к включению данных или кода в программу, хотя сама она никакой команде процессора не соответствует. Псевдокоманды определения переменных указывают ассемблеру, что в соответствующем месте программы располагается переменная, определяют тип переменной (байт, слово, вещественное число и т.д.), задают ее начальное значение и ставят в соответствие переменной метку, которая будет использоваться для обращения к этим данным. Псевдокоманды определения данных записываются в общем виде следующим образом:
имя_переменной d* значение
где D* — одна из нижеприведенных псевдокоманд:
DB — определить байт;
DW — определить слово (2 байта);
DD — определить двойное слово (4 байта);
DF — определить 6 байт (адрес в формате 16-битный селектор: 32-битное смещение);
DQ — определить учетверенное слово (8 байт);
DT — определить 10 байт (80-битные типы данных, используемые FPU).
Поле значения может содержать одно или несколько чисел, строк символов (взятых в одиночные или двойные кавычки), операторов ? и DUP, разделенных запятыми. Все установленные таким образом данные окажутся в выходном файле, а имя переменной будет соответствовать адресу первого из указанных значений. Например, набор директив
text_string db 'Hello world!'
number dw 7
table db 1,2,3,4,5,6,7,8,9,0Ah,0Bh,0Ch,0Dh,0Eh,0Fh
float_number dd 3.5e7
заполняет данными 33 байта. Первые 12 байт содержат ASCII-коды символов строки «Hello world!», и переменная text_string указывает на первую букву в этой строке, так что команда
mov al,text_string
считает в регистр AL число 48h (код латинской буквы H). Если вместо точного значения указан знак ?, переменная считается неинициализированной и ее значение на момент запуска программы может оказаться любым. Если нужно заполнить участок памяти повторяющимися данными, используется специальный оператор DUP, имеющий формат счетчик DUP (значение). Например, вот такое определение:
table_512w dw 512 dup(?)
создает массив из 512 неинициализированных слов, на первое из которых указывает переменная table_512w. В качестве аргумента в операторе DUP могут выступать несколько значений, разделенных запятыми, и даже дополнительные вложенные операторы DUP.
6.2.2. Организация программы
Представленная на рис. 5.8. программа демонстрирует принципы использования базовых элементов языка ассемблера IA-32, связанные с определением кодов операции, адресацией и применением адресных меток. Для определения областей данных программы и установления соответствия между символическими именами и реальными физическими значениями адреса существуют специальные директивы ассемблера.
Оформление ассемблерной программы сложения нескольких чисел приведен на рис. 6.1. Ассемблерные директивы .data и .code определяют начало областей данных и кода (то есть команд) программы. Директива DD (Definition Double (Double word)) выделяет в области данных 4-байтовое двойное слово. NUM1 — это метка, назначенная адресу первого из двойных слов, которые инициализированы значениями 17, 3, -51, 242 и -113. Адресам следующих двух двойных слов, инициализированных значениями 5 и 0, назначены метки N и SUM.
.data ; директивы асемблера инициируют данные в сегменте данных
NUMLIST DD 17,3,-51,242,-113
NUM1 EQU NUMLIST
N DD 5
SUM DD 0
.code : команды ассемблера в сегменте кода
MAIN:
Код программы сложения чисел, рис. 5.8., лекция 5.
END MAIN ;директива ассемблера
Рис. 6.1. Полный текст программы на языке ассемблера, для сложения пяти целых чисел
Три символических имени, объявленных в разделе данных, используются в командах в разделе кода. В частности, метка MAIN предназначена для определения точки начала выполнения программы, а также задается в ассемблерной директиве END, которой заканчивается текстовый файл программы. В ассемблере IA-32 имеются и другие директивы. Некоторые из них будут рассмотрены позже.