C=A+B
Возврат из подпрограммы возвращаемся в то место, откуда вызывали
Конец подпрограммы
В данном примере мы дважды вызвали подпрограмму Сложение, которая сложила два числа, переданные ей в переменных A и B. Результат помещается в переменную С. Когда вызывается подпрограмма, компьютер запоминает с какого места она была вызвана, а затем, когда закончила работу подпрограмма, компьютер возвращается в то место, откуда она вызывалась. Т.о. можно вызывать подпрограммы неопределенное количество раз с любого места.
Команда RET пользуется обычно для возвращения из процедуры. DOS вызывается COM-программы так, что команда RET корректно завершает программу.
DOS при вызове СОМ-файла помещает в стек сегментный адрес программы и ноль, так что RET передает управление на нулевой адрес текущего сегмента, то есть на первый байт PSP. Там находится код команды INT 20H, которая и используется для возвращения управления в DOS. Можно сразу заканчивать программу командой INT 20h, хотя это длиннее на 1 байт.
Следующая строка примера определяет строку данных, содержащую текст “ПРИВЕТ" управляющий символ ASCII возврат каретки с кодом ODh, управляющий символ ASCII перевод строки с кодом 0Ah и символ $ завершающий строку (если мы его уберем, то 21h прерывание продолжит вывод до тех пор, пока не встретится где-нибудь в памяти символ $, на экране мы увидим “мусор). Первое слово (message - сообщение) - название сообщения. Оно может быть любым (например, mess или string и пр).
Управляющие символы (ODh и 0Ah) переводят курсор на первую позицию следующей строки.
Директива END завершает программу, одновременно указывая, с какой метки должно начинаться ее выполнение.
В качестве дополнительного примера создадим еще одну строку, которую назовем message1. Затем, начиная со строки (9) вставим следующие команды и скомпилируем программу заново.
9 | mov dx,offset message1 |
10 | int 21h |
11 | int 20h |
12 | message db "Привет", 0dh, 0ah, '$' |
13 | message1 db "Группа", 0dh, 0ah, '$' |
14 | end begin |
2. Задание для выполнения
2.1 Запустить эмулятор EMU8086.
2.2 Пользуясь правилами оформления ассемблерных программ, наберите код, приведенный в примере 1, запустите код на выполнение.
2.3 Откомпилируйте пример №2;
2.4 Вернитесь в главное окно формы, предварительно закрыв все открытые окна, далее нажмите кнопку “Compile".
2.5 Полученный com-файл запустите в сеансе dos.
2.6 Создайте на языка Pascal программу выводящую на экран слово “Привет" и сравните размеры получаемых файлов (Pascal и Assembler).
3. Контрольные вопросы
3.1 Характеристика структуры файла типа *.com?
3.2 Какова структура ассемблерной программы?
3.3 С какой целью в код программы на ассемблере для DOS вводится строка ORG 100h?
3.4 Назначение команды MOV?
3.5 Прерывания 21h и 20h. Назначение?
3.6 Сущность и целесообразность использования команды RET вместо прерывания 20h?
3.6. Символ ‘$’ методика применения?
3.7. Связка “BEGIN: - END BEGIN". Правила применения?
ЛАБОРАТОРНАЯ РАБОТА №3
СТРУКТУРА ИСПОЛНИМЫХ ФАЙЛОВ ТИПА *. EXE.
ПРОСТЫЕ АРИФМЕТИЧЕСКИЕ ДЕЙСТВИЯ НА ЯЗЫКЕ АССЕМБЛЕРА
Цель работы: Изучение принципов составления простейших*. exe программ. Изучение приемов работы с простейшими операторами арифметических действий.
Краткие теоретические сведения (программа типа *. ЕХЕ).
Файлы типа ЕХЕ содержат заголовок, в котором описывается размер файла, требуемый объем памяти, список команд в программе, использующих абсолютные адреса, которые зависят от расположения программы в памяти, и т.д. ЕХЕ-файл может иметь любой размер. Формат ЕХЕ также используется для исполнимых файлов в различных версиях DOS-расширителей и Windows, но со значительными изменениями.
Операционная система DOS не использует расширения для определения типа файла. Первые два байта заголовка ЕХЕ-файла - символы "MZ" или "ZM", и если файл начинается с этих символов и длиннее некоторого порогового значения, разного для разных версий DOS, он загружается как ЕХЕ, если нет - как СОМ.
ЕХЕ-программы немного сложнее в исполнении, но для них отсутствует ограничение размера в 64 килобайта, так что все достаточно большие программы используют именно этот формат. Конечно, ассемблер позволяет уместить и в 64 килобайтах весьма сложные и большие алгоритмы, а все данные хранить в отдельных файлах, но ограничение размера все равно очень серьезно, и даже чисто ассемблерные программы могут с ним сталкиваться.
Простой пример ЕХЕ-файла:
. model small | ; сегмент стека размером в 256 байт |
. stack 100h | ; сегмент стека размером в 256 байт |
. code | ; сегмент кода, который содержит и данные. |
Begin: | ; метка начала кода программы |
mov ax,@data; | ; сегментный адрес строки message помещается в DS |
mov ds,ax | |
mov dx,offset string | помещает в регистр DX смещение метки String относительно начала сегмента данных |
mov ah,9 | ; помещаем номер функции DOS "вывод строки (9)" в регистр АН. |
int 21h | ; функция DOS "вывод строки" |
mov ax,4C00h | ; завершение программы типа - exe |
int 21h | ; функция DOS "завершить программу" |
. data | ; начало сегмента данных |
string db "Privet", 0Dh,0Ah,'$' | ; cтрока с содержащая выводимые данные. |
end begin | ; метка окончания кода программы |
В примере определяются три сегмента - сегмент стека директивой. STACK размером в 256 байт, сегмент кода, начинающийся с директивы. CODE, и сегмент данных, начинающийся с. DATA. При запуске ЕХE-программы регистр DS уже не содержит адреса сегмента со строкой string (он указывает на сегмент, содержащий блок данных PSP), а для вызова используемой функции DOS этот регистр должен иметь сегментный адрес строки. Команда MOV AX,@DATA загружает в АХ сегментный адрес группы сегментов данных @DATA, a MOV DS,AX копирует его в DS. Программы типа ЕХЕ должны завершаться системным вызовом DOS 4Ch: в регистр АН помещается значение 4Ch, в регистр AL помещается код возврата (в данном примере код возврата 0 и регистры АН и AL загружаются одной командой MOV AX,4C00h), после чего вызывается прерывание 21h.
Простые арифметические операторы.
Арифметические команды любого микропроцессора привлекают к себе наибольшее внимание. Каждый заинтересован в выполнении арифметических вычислений, и именно эти команды проделывают такую работу. Хотя их немного, они выполняют большинство преобразований данных, а микропроцессоре. В реальных же условиях арифметические команды занимают лишь малую часть всех исполняемых команд.
2.1 Сложение.
Команда ADD (Addition - сложение (гл. to add - сложить)) осуществляет сложение первого и второго операндов. Исходное значение первого операнда (приемника) теряется, замещаясь результатом сложения. Второй операнд не изменяется. В качестве первого операнда команды ADD можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами и представлять числа со знаком или без знака. Команду ADD можно использовать для сложения как обычных целых чисел, так и двоично-десятичных (с использованием регистра АХ для хранения результата). Команда воздействует на флаги OF, SF, ZF, AF, PF и CF.
Команда | Назначение | Процессор |
ADD приемник, источник | Сложение | 8086 |
Примеры:
mov al,10 - --> загружаем в регистр AL число 10
add al,15 - --> al = 25; al - приемник, 15 - источник
mov ax,25000 - --> загружаем в регистр AX число 25000
add ax,10000 - --> ax = 35000; ax - приемник, 10000 - источник
mov cx, 200 - --> загружаем в регистр CX число 200
mov bx,760 - --> а в регистр BX - 760
add cx,bx - --> cx = 960, bx = 760 (bx не меняется); cx - приемник, bx - источник
2.2 Вычитание.
Команда SUB (Subtraction - вычитание) вычитает второй операнд (источник) из первого (приемника) и помещает результат на место первого операнда. Исходное значение первого операнда (уменьшаемое) теряется. Таким образом, если команду вычитания записать в общем виде
SUB операнд1, операнд2
то ее действие можно условно изобразить следующим образом:
операнд1 - операнд2 - > операнд1
В качестве первого операнда можно указывать регистр (кроме сегментного) или ячейку памяти, в качестве второго - регистр (кроме сегментного), ячейку памяти или непосредственное значение, однако не допускается определять оба операнда одновременно как ячейки памяти. Операнды могут быть байтами или словами и представлять числа со знаком или без знака. Команда воздействует на флаги OF, SF, ZF, AF, PF и CF.
Команда | Назначение | Процессор |
SUB приемник, источник | Вычитание | 8086 |
Примеры:
mov al,10
sub al,7 - --> al = 3; al - приемник, 7 - источник
mov ax,25000
sub ax,10000 - --> ax = 15000; ax - приемник, 10000 - источник
mov cx,100
mov bx,15
sub cx,bx - --> cx = 85, bx = 15 (bx не меняется); cx - приемник, bx - источник
2.3 Инкремент (увеличение на 1).
Команда INC (Increment - инкремент) прибавляет 1 к операнду, в качестве которого можно указывать регистр (кроме сегментного) или ячейку памяти размером как в байт, так и в слово.
Не допускается использовать в качестве операнда непосредственное значение. Операнд интерпретируется как число без знака. Команда воздействует на флаги OF, SF, ZF, AF и PF. Команда не воздействует на флаг CF; если требуется воздействие на этот флаг, необходимо использовать команду Add Op,l.
Команда INC (Increment - инкремент) увеличивает на единицу регистр или значение операнда в памяти.
Она эквивалентна команде ADD источник, 1 только выполняется гораздо быстрее.
Команда | Назначение | Процессор |
INC приемник | Увеличение на единицу | 8086 |
Примеры: