Практическая работа специальности 09.02.01.

  • docx
  • 28.11.2022
Публикация на сайте для учителей

Публикация педагогических разработок

Бесплатное участие. Свидетельство автора сразу.
Мгновенные 10 документов в портфолио.

Иконка файла материала ПЗ13_Составление программ на языке ассемблера для микропроцессорных систем.docx

Практическое занятие 13

Тема: «Составление программ на языке ассемблера для микропроцессорных систем»

Цель: получение знаний о структуре и основных правилах записи программ на языке Ассемблера для ЭВМ типа IBM PC, а также приобретение практических навыков по составлению простейших программ на языке Ассемблера, их выполнению и отладке.

Теория

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

Формат команды языка Ассемблера в общем случае содержит до 4-х полей:

[метка:] команда [поле операндов] [; комментарий]

Обязательным является только поле команды. По крайней мере, один пробел между полями обязателен. Максимальная длина строки - 132 символа.

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

- буквы от A до Z, причем Ассемблер не делает разницы между строчными и прописными буквами;

- цифры от 0 до 9;

- спец. символы: '?', '.'(только первый символ), '@'(коммерческое эт), '$', '_'.

Первым символом в метке должна быть буква или специальный символ. Максимальная длина метки - 31 символ.

Поле команды содержит имя команды, например, MOV - команда пересылки, ADD - команда сложения и другие.

Операнды определяют:

- начальные значения данных;

- элементы, над которыми выполняется действие.

Пример:

MOV AX, 5; команда MOV заносит в регистр AX значение 5.

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

Комментарий начинается с символа ';' в любом месте программы. Все символы справа от символа ';' до конца строки воспринимаются Ассемблером как комментарий.

Директивы могут иметь до 4-х полей:

[метка] директива [операнд] [; комментарий]

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

- директивы определения идентификаторов;

- директивы определения данных;

- директивы внешних ссылок;

- директивы определения сегмента/процедуры;

Существует две директивы определения идентификаторов: EQU и '='. EQU присваивает имя выражению постоянно, а '=' - временно и его можно переопределить.

Существуют следующие директивы определения данных:

- DB - определить байт;

- DD - определить двойное слово;

- DW - определить слово;

- DT - определить 10 байт.

Обычно DB и DW резервируют память под переменные, а DD и DT - под адреса. В любом случае можно указать начальное значение или знак '?' только для резервирования памяти. Операция DUP позволяет повторять одно и тоже значение несколько раз.

Пример:

PEREM DB 4 DUP(?); директива резервирует четыре байта в памяти под переменную PEREM.

Если перечислять значения переменной через запятую, то тем самым определяется таблица данных.

Пример:

TABL DW 3,4,5 ; директива выделяет область памяти с именем TABL длиной три слова

;и заносит в первое слово значение 3, во второе значение 4, в третье слово - значение 5.

Директивы определения сегмента делят исходную программу на сегменты. В программе на языке Ассемблера возможно 4 вида сегментов:

- сегмент данных;

- сегмент стека;

- сегмент команд;

- дополнительный сегмент.

По крайней мере один сегмент - сегмент команд - должен присутствовать в каждой программе.

Существует две директивы определения сегмента: SEGMENT и ENDS, а также директива ASSUME, которая устанавливает для Ассемблера соответствие между конкретными сегментами и сегментными pегистpами.

Пример:

DATASG SEGMENT PARA 'DATA' ;директива определяет начало сегмента с именем DATASG, а ;директива

DATASG ENDS ;конец этого сегмента.

Директива

ASSUME CS:CODESG,DS:DATASG

указывает Ассемблеру, что сегмент CODESG будет адресоваться с помощью сегментного регистра CS, а сегмент DATASG - с помощью сегментного регистра DS.

Директивы PROC и ENDP определяют начало и конец процедуры. Процедура может иметь атрибут дистанции NEAR или FAR. Процедура с атрибутом NEAR может быть вызвана только из того сегмента команд, в котором она определена, а процедура с атрибутом FAR может быть вызвана и из другого сегмента команд. Например, директива

FUN PROC NEAR

определяет начало процедуры FUN с атрибутом дистанции NEAR, а

директива

FUN ENDP

конец этой процедуры. Программа на Ассемблере имеет атрибут FAR.

Директивы внешних ссылок PUBLIC и EXTRN делают возможным использование переменных и процедур, определенных в разных файлах.

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

Директивы управления листингом PAGE и TITLE могут быть использованы для определения формата вывода распечаток программ и выдачи заголовков.

Таким образом, типовая структура программы на языке Ассемблера для ЭВМ типа IBM PC выглядит следующим образом:

TITLE ;заголовок программы

PAGE 60,132 ; определение сегмента стека

STACKSG SEGMENT PARA STACK 'STACK'

DB 64 DUP(?) ; область стека, не менее 32 слов

STACKSG ENDS ; конец сегмента стека

DATASG SEGMENT PARA 'DATA' ; определение сегмента данных

; здесь можно поместить, если необходимо, директивы определения

DATASG ENDS ;конец сегмента данных

; Определение сегмента команд (основная программа)

CODESG SEGMENT PARA 'CODE'

ASSUME CS:CODESG, DS:DATASG, SS:STACKSG

ENTRY PROC FAR

; Инициализировать программу

PUSH DS ; сохранить в стеке адрес возврата

SUB AX,AX ; обнулить регистр AX

PUSH AX ; занести в стек нулевое смещение для адреса возврата

; Инициализировать адрес сегмента данных

MOV AX,DATASG ; занести адрес сегмента

MOV DS,AX ; данных в регистр DS

; Программа

...

POP AX;

POP DS; восстановили регистры AX и DS

RET ; вернутся в MS-DOS

ENTRY ENDP

CODESG ENDS

END ENTRY

В данном фрагменте показана группа команд PUSH DS ... MOV DS,AX, которая является стандартной для программ на Ассемблере и обеспечивает возврат управления в MS-DOS после выполнения программы. Команда RET обеспечивает выход из программы и передачу управления MS-DOS.

Пример выполнения задания

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

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

2.    Разработка алгоритма программы (построение блок-схемы, текстовое или математическое описание решения);

3.    Формализация алгоритма (запись алгоритма на языке программирования). Создание текстового файла программы с расширением .asm (например, my.asm). Отсутствие среды разработки позволяет программисту самостоятельно выбрать текстовый редактор для написания кода программы. Для этой цели подойдет любой текстовый редактор с нумерацией строк, например Блокнот или редактор, встроенный в оболочку FAR-менеджер.

4.    Трансляция программы. Трансляция - процесс перевода программы из текстового вида в машинный код. При использовании транслятора фирмы Borland необходимо выполнить команду:

tasm my.asm

т.е. запускаем транслятор tasm и передаем с командной строки имя файла, содержащего программу. Если программа имеет синтаксические ошибки, транслятор выдаст сообщение об ошибке с указанием номера строки и описанием для каждой ошибки (нужно вернуться на этап №3 и исправить синтаксические ошибки). В случае успешной трансляции будет создан файл, содержащий объектный код программы my.obj, который ещё не является исполняемым модулем.

5.    Компоновка программы. Компоновка - создание из файла объектного кода исполняемого модуля.

tlink my.obj

В качестве параметра компоновщик tlink принимает имя файла содержащего объектный код программы (в нашем случае - my.obj). В случае успешной компоновки будет создан исполняемый модуль my.exe

6.    Запуск и тестирование исполняемого модуля программы. На данном этапе необходимо проверить, соответствует ли написанная программа постановке задачи, выполненной на этапе №1. Неправильная работа программы говорит об алгоритмической ошибке (семантическая ошибка), поэтому для успешного её устранения следует вернуться на этап разработки алгоритма (этап №2).

Написание первой программы на языке ассемблера

1.    Постановка задачи. Написать программу, которая выводит на экран строчку "Привет!".

2.    Разработка алгоритма программы. Алгоритм линейный, разработки не требует.

3.    Формализация (запись) алгоритма

В текстовом редакторе создаем файл privet.asm и записываем в него следующий код (без номеров строк) :

Вариант 1:

1

   

data segment

;описание сегмента данных

2

 

       

mes db 'Привет!$'

;строка для вывода на экран. '$' - признак конца строки

3

 

data ends

;конец сегмента данных

4

 

code segment

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

5

 

start:

;метка start - начало нашей программы

6

 

 

assume cs:code, ds: data    

;директива компилятора

7

 

 

mov ax, data

;настройка сегмента данных

8

 

 

mov ds, ax

9

 

 

mov ah, 9

;функция №9 прерывания 21h - вывод строки на экран

10

 

 

lea dx, mes

;берём адрес строки

11

 

 

int 21h

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

12

 

 

mov ax, 4c00h

;функция завершения программы

13

 

 

int 21h

;завершаем программу

14

 

code ends

;конец сегмента кода

15

 

end start

;конец программы с точкой входа start

4.    Компиляция программы
tasm privet.asm

5.    Компоновка программы
tlink privet.obj

6.    Запуск и тестирование
privet.exe

Переход на новую строку

Для организации перехода на новую строку достаточно вывести на экран символы перевода строки и возврата каретки (CR/LF). Эти символы имеют коды 10 и 13. Если в нашей программе необходимо после вывода строки перейти на новую, то для этого достаточно переписать вторую строку программы:

mes2 db 'Выводим строку и переходим на новую...', 10, 13, '$'

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

mes3 db 10, 13, 'Выводим с новой строки...$'

Вариант 2:

text segment

;Начало сегмента команд

assume CS:text,DS:data

;Сегментный регистр CS будет указывать на сегмент команд, а сегментный регистр DS - на сегмент данных

start: mov AX,data

;Адрес сегмента данных сначала загрузим в АХ,

mov DS,AX

;а затем перенесем из АХ в DS

mov AH,09h

;Функция MS-DOS 9h вывода на экран

mov DX,offset mesg

;Адрес выводимого сообщения должен быть в DX

int 21h

;Вызов MS-DOS

mov AH,4Ch

;Функция 4Ch завершения программы

mov AL, 0

;Код 0 успешного завершения

int 21h

;Вызов MS-DOS

text ends

;Конец сегмента команд

data segment

;Начало сегмента данных

mesg db 'Hello world!$'

;Выводимый текст

data ends

;Конец сегмента данных

stk segment stack

;Начало сегмента стека

db 256 dup (0)

;Резервируем 256 байт для стека

stk ends

;Конец сегмента стека

end start

;Конец текста программы с точкой входа start

 

Ход работы

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

Привет!

Меня зовут ФИО студента!

Я с удовольствием буду изучать Ассемблер!