Разработка и отладка подпрограмм на языке Ассемблера
Введение
Язык ассе́мблера
(англ. assemblylanguage) - машинно-ориентированный язык низкого уровня с
командами, обычно соответствующими командам машины, который может обеспечить
дополнительные возможности вроде макрокоманд[1]; автокод, расширенный конструкциями
языков программирования высокого уровня, такими как выражения, макрокоманды,
средства обеспечения модульности программ[2].
Автокод - язык программирования, предложения
которого по своей структуре в основном подобны командам и обрабатываемым данным
конкретного машинного языка[2].
Язык ассемблера - система обозначений,
используемая для представления в удобочитаемой форме программ, записанных в
машинном коде. Язык ассемблера позволяет программисту пользоваться алфавитными
мнемоническими кодами операций, по своему усмотрению присваивать символические
имена регистрам ЭВМ и памяти, а также задавать удобные для себя схемы адресации
(например, индексную или косвенную). Кроме того, он позволяет использовать
различные системы счисления (например, десятичную или шестнадцатеричную) для
представления числовых констант и даёт возможность помечать строки программы
метками с символическими именами с тем, чтобы к ним можно было обращаться (по
именам, а не по адресам) из других частей программы (например, для передачи управления)[3].
Перевод программы на языке ассемблера в
исполнимый машинный код (вычисление выражений, раскрытие макрокоманд, замена
мнемоник собственно машинными кодами и символьных адресов на абсолютные или
относительные адреса) производится ассемблером - программой-транслятором,
которая и дала языку ассемблера его название.
Команды языка ассемблера один к одному
соответствуют командам процессора. Фактически, они и представляют собой более
удобную для человека символьную форму записи - мнемокоды - команд и их
аргументов. При этом одной команде языка ассемблера может соответствовать
несколько вариантов команд процессора[4].
Кроме того, язык ассемблера позволяет
использовать символические метки вместо адресов ячеек памяти, которые при
ассемблировании заменяются на вычисляемые ассемблером или компоновщиком
абсолютные или относительные адреса, а также так называемые директивы (команды
ассемблера, не переводимые в машинные команды процессора, а выполняемые самим
ассемблером).
Директивы ассемблера позволяют, в частности,
включать блоки данных, задать ассемблирование фрагмента программы по условию,
задать значения меток, использовать макрокоманды с параметрами.
Каждая модель (или семейство) процессоров имеет
свой набор - систему - команд и соответствующий ему язык ассемблера. Наиболее
популярные синтаксисы языков ассемблера - Intel-синтаксис и AT&T-синтаксис.
Существуют компьютеры, реализующие в качестве
машинного язык программирования высокого уровня (Форт, Лисп, Эль-76).
Фактически, в таких компьютерах они выполняют роль языков ассемблера.
1. Системный анализ
Целью курсового проекта является закрепление
полученных знаний и профессиональных навыков разработки и отладки подпрограмм
на языке Ассемблера. Курсовой проект выполняется в соответствии с этапами
разработки программного обеспечения: анализ и постановка задачи для решения на
ЭВМ, проектирование, кодирование, отладка и тестирование разработанной
программы. Проектирование ведется в соответствии с методологией структурного
программирования.
Требуется рассчитать выражение (1):
(1)
Необходимо разработать программы для её
вычисления на языках Си, Ассемблер УМ и Ассемблер IBMPC. С клавиатуры вводятся
2 переменные и значения массива, после выполняется расчет 2 констант 2c и
(a*a+1) данной функции и расчет z. Далее выполняется вывод результата на экран
монитора. Программа состоит из 4-х функций: функция ввода переменных, две
функция расчета констант, функция вывода результата.
2. Структурное программирование.
Схема алгоритма. Программа на языке Си для int, float
Программа на языке программирования Си для int
#include"stdafx.h"
#include<iostream>
#include<conio.h>;N
= 4;(int a, int c, int d[])
{int g, k, l, z;Y =
0;= 2 * c;= a*a + 1;<<"g = "<<"2 * "<< c
<<" = "<< g <<endl;<<"k = "<<
a*a <<" + 1"<<" = "<< k
<<endl;(inti = 1; i<= N; i++)
{l = d[i] /
4;<<i<<") "<<"l["<< d[i]
<<"] = "<< d[i] <<" / 4 = "<< l
<<endl;= (g - l) / k;<<" z["<< d[i] <<"]
= "<< z <<endl;= Y + z;<<endl;}<<"Y =
"<< Y <<endl;}main()
{setlocale(LC_ALL,
"Russian");a, c, d[N];<<"Введите a =
";>> a;<<"Введитес
= ";
cin>> c;<<"Введите элементы массива"<<endl;
for (inti = 1;
i<= N; i++)
{cout<<"d["<<i<<"]
= ";>> d[i];}(a, c, d);
_getch();
return 0;}
Программа на языке программирования Си для float
#include"stdafx.h"
#include<iostream>
#include<conio.h>;N
= 4;(floata, floatc, floatd[])
{float g, k, l, z;Y
= 0;= 2 * c;= a*a + 1;<<"g = "<<"2 *
"<<c<<" = "<< g <<endl;<<"k =
"<<a*a<<" + 1"<<" = "<< k
<<endl;(inti = 1; i<= N; i++)
{l = d[i] /
4;<<i<<") "<<"l["<<d[i] <<"]
= "<<d[i] <<" / 4 = "<< l <<endl;= (g -
l) / k;<<" z["<<d[i] <<"] = "<< z
<<endl;= Y + z;<<endl;}<<"Y = "<< Y
<<endl;}main()
{setlocale(LC_ALL,
"Russian");a, c, d[N];<<"Введите a =
";>> a;<<"Введитес
= ";
cin>> c;<<"Введите элементы массива"<<endl;
for (inti = 1;
i<= N; i++)
{cout<<"d["<<i<<"]
= ";>> d[i];}(a, c, d);
_getch();
return 0;}
Блок схема
Рис. 1
3. Программирование
.1 Программа на Ассемблере УМ
start 0
lda cc2pc0c0comp
c12artart,a;i:=i+1c3,xlda yword 20word 2word 0word 1word 3word 4word 12word
2word 0word 20124-16333eec1k,xc4opokyyEx77
Блок схема
Рис. 2
3.2 Подпрограмма ввода и вывода
целых чисел на Ассемблере IBM
Подпрограмма ввода
Блок схема
Рис. 3
Подпрограмма на языке программирования Ассемблер
IBMPC
InputIntprocah,
0ahdi, didx, offset buff; адресбуфера21h; принимаем строку
movdl, 0ah, 0221h
; выводим перевод строки и
обрабатываем
; содержимое буфера, offset
buff+2; берем адрес начала строки[si], "-"; если первый символ
минусii1, 1; устанавливаем флаг; и пропускаем его: xorax, ax, 10; основание сc:
movcl, [si]; берем символ из буфера, 0dh; проверяем не последний ли он
; если символ не последний, то
проверяем его
; на правильность, '0'; если
введен неверный символ <0, '9'; если введен неверный символ >9, '0';
делаем из символа число; умножаем на 10, cx; прибавляем к остальным; указатель
на следующий символii2; повторяем: movdx, offseterror; если была ошибка, то
выводим сообщение об
; этом и выходимah,0921h20h;
все символы из буфера обработаны число
; находится в ax: cmp di,1;
если установлен флаг, тоii3; делаем число отрицательным
ii3:
ret"incorrect number$"
buffdb 6,7 Dup(?)
3.2 Подпрограмма на языке
программирования Ассемблер IBMPC
Процедура вывода
OutIntprocnear;=====Процедура
вывода, ax; проверяем число на знак.oi1, ax;eсли оно отрицательное, выведем
минус и
; оставим его модуль, 02hdl,
'-'21h, cx: xorcx, cx; количество цифр будем держать в CX, 10; основание сс. 10
для десятеричной и т.п.: xordx, dx; делим число на основание сс, в остатке
; её в стэке
; а с частным повторяем то же
самое, отделяя
; от него очередную, ax; цифру
справа, пока не останется ноль, что
;значит, что дальшеoi2; слева
только нули
;========Вывод=========
mov ah, 02h: pop dx
adddl, '0'; извлекаем очередную
цифру, переводим её в
; символ и выводим21hoi3;
повторим ровно столько раз, сколько цифр
; насчитали
Рис. 4
3.3 Программа на языке
программирования Ассемблер IBMPC
.modelsmall
.stack 200h
.data??4 dup (?,?,?,?)???8db
'0123456789ABCDEF'db 4 DUP (20h),13,10,'$'db 'Resultat',13,10,'$'
.code,
ax; Проверяем число на знак.oi1
; Если оно отрицательное, выведем
;минус и оставим его модуль.
mov cx, axah, 02hdl, '-'21h
movax, cx
; Количество цифр будем держать в CX:, cx, 10;
основание сс. 10 для десятеричной и т.п.:,dx
; Делим число на основание сс.
;В остатке получается последняя цифра.
; Сразу выводить её нельзя,
;поэтому сохраним её в стэке.
; А с частным повторяем то же самое,
;отделяя от него очередную
; цифру справа, пока не останется ноль,
; что значит, что дальше слева только нули.,
axoi2
; Теперь приступим к выводу., 02h:
; Извлекаем очередную цифру,
;переводим её в символ и выводим., '0'21h
; Повторим ровно столько раз,
;сколько цифр насчитали.oi3
retah,0ah,di,offset buff; аддресбуфера21h;
принимаем
строкуdl,0ahah,02
int 21h; выводим перевода строки
; обрабатываем содержимое буфера,offset buff+2;
берем аддрес начала строки[si],"-"; если первый символ минусii1di,1;
устанавливаем флаг; и пропускаем его:,axbx,10; основание сc:,[si]; берем символ
из буфераcl,0dh; проверяем не последний ли он
; если символ не последний, то
;проверяем его на правильностьcl,'0'; если
введен неверный символ <0cl,'9'; если введен неверный символ >9cl,'0';
делаем из символа число; умножаем на 10,cx; прибавляем к остальным; указатель
на следующий символii2; повторяем:; если была ошибка, то выводим
;сообщение об этом и выходим, offseterror
mov ah,0921h20h
; все символы из буфера
;обработаны число находится в ax:di,1; если
установлен флаг, тоii3; делаем число отрицательным
ii3:"incorrect number$"6,7
Dup(?)proc near;---------------------eAl,2,cBL,AXAX,0BX,06;???endpprocnear;fAX,0,aALDX,
1AX, DXf, AXAX,0DX,06;???endp:ax, @Datads, ax; вводчислаа,AL;
вводчислас,ALSI,0SI:
call InputIntSId[SI], ALSI,2,tSIl1PP1;вызовп\п
1PP2;вызовп\п
2SI,0CX,4AX,AX,AX: mov DX,0AH,0CL,0,d[SI]BL, ALAX,0m2CL,1AL, BLAL: mov
DL,4DLCL,0m3AL: mov
BX, eBX,AXAX,BXAX, BX,fBX ;AL=AL/fBX,AXAX, BX,yAX, DXy, AXSI,2,tforCX,0AX, yDX,
AX;DX:=AXAX,4c00h21h
END begin
Программа на языке программирования Ассемблер
IBMPC
Рис. 5
Рис. 6
4. Тестирование и отладка
Входные
данные
|
Си
Int (десятичная СС)
|
Си
float (десятичная СС)
|
Ассемблер
УМ (шестнадцатеричная СС)
|
Ассемблер
IBMPC (десятичная СС)
|
a
= 2 c = 20 d[0] = 20 d[1] =12 d[2] = 4 d[3] = -16
|
29
|
31
|
1D
|
29
|
a
=3 c =30 d[0] =51 d[1] =41 d[2] =24 d[3] =-21
|
20
|
21.625
|
14
|
20
|
a
= 2 c = 20 d[0] = 20 d[1] = 14 d[2] = 4 d[3] = 16
|
28
|
29.3
|
1C
|
Переведем результат работы Ассемблера УМ в
десятичную СС:
D = 29
= 20
C = 28.
Явно видим, что результат работы программ на Си
(для int), Ассемблер УМ и Ассемблер IBMPC совпадают на 100%. Результат работы
программ на Си (для float) немного отличается ввиду точности вычислений и
отличается от округленного значения максимум на 2 единицы.
5. Инструкция пользователя
Язык программирования Си (для int)
окно с запросом: «Введите а:». Необходимо ввести
нужное значение переменной «а», она может быть любым целым положительным или
отрицательным числом. Нажимаем Enter.
Далее в этом диалоговом окне появляется запрос:
«Введите с:». Необходимо ввести нужное значение переменной «с», она может быть
любым целым положительным или отрицательным числом. Нажимаем Enter.
Следующим появится новый запрос: «Введите 4
значений для массива:». Вводим 4 любых значений, которые могут быть любыми
целыми положительными или отрицательными значениями. После каждого введенного
числа нажимаем Enter.
В конечном итоге в этом диалоговом окне у нас
появится запись «y=…». Вместо многоточия будет стоять число-ответ, которое
получилось в результате подстановки в выражение (1) введенные Вами значений
«а», «с» и значений массива «d[0]», «d[1]», «d[2]», «d[3]». Ответ будет целым
положительным или отрицательным числом.
Язык программирования Си (для float)
При запуске программы на языке программирования
Си, появится диалоговое окно с запросом: «Введите а:». Необходимо ввести нужное
значение переменной «а», она может быть любым целым или десятичным
положительным или отрицательным числом. Нажимаем Enter.
Далее в этом диалоговом окне появляется запрос:
«Введите с:». Необходимо ввести нужное значение переменной «с», она может быть
любым целым положительным или отрицательным числом. Нажимаем Enter.
Следующим появится новый запрос: «Введите 4
значений для массива:». Вводим 4 любых значений, которые могут быть любыми
целыми или десятичным положительными или отрицательными значениями. После
каждого введенного числа нажимаем Enter.
В конечном итоге в этом диалоговом окне у нас
появится запись «y=…». Вместо многоточия будет стоять число-ответ, которое
получилось в результате подстановки в выражение (1) введенные Вами значений
«а», «с» и значений массива «d[0]», «d[1]», «d[2]», «d[3]». Ответ будет целым
или десятичным положительным или отрицательным числом.
Язык программирования Ассемблер УМ
Записываем код программы при помощи стандартного
приложения «Блокнот» в формате *.txt. При описании данных мы сразу должны
задать значения для переменных «а», «с» и сразу задать значения массива,
которые имеют размер в 1 слово.
Открываем этот файл в программеTCom.exe при
помощи вкладки «Asm», далее в отрывшемся окне выбираем вкладку «File» затем
«Open» и находим нужный файл с кодом в формате *.txt. Код программы загрузится
на вкладку «Sourcemodule». Нажимаем на вкладку «GoAsm», если в коде нет ошибок,
то приложение выведет синюю запись «Noerrorsdetected!»
Далеезагружаеммодульпрограммывпрограмме..exe при помощи вкладки «Load» в
основном окне.
Запускаем программу при помощи клавиши «Start» в
основном окне.
Результат подстановки значений «а», «с» и
массива «d» в выражение (1) будет находиться в Аккумуляторе, который
располагается во втором поле программе TCom.exe(смотреть рис. 1). Значением
Аккумулятора будет число в шестнадцатеричной СС.
Язык программирования Ассемблер IBMPC
Запускаем эмулятор DOSBox 0.74. С его помощью
переходим на необходимый диск (используем команду «mountc», смотреть рис. 2
(файл находится на диске С в папке с название «1», название файла «сс»)) и
отрываем папку, в которой расположен файл с кодом программы в формате *.asm, компоновщик
tasm.exeи редактор связей tlink.exe (ОБЯЗАЕЛЬНОЕ УСЛОВИЕ: все 3 файла должны
быть в 1(!) папке).
Рис. 7
Далее в эмуляторе DOSBox 0.74 вводим
«tasm.exe<название файла>..asm». Таким образом мы даем команду скомпилировать
код и показать ошибки, если они есть. Если их нет, то эмулятор выведет
отсутствие сообщений об ошибке и предупреждений. В результате удачной
компиляции будет создан файл формата *.obj.
Продолжаем вводить в окно эмулятора DOSBox0.74
команды. Вводим «tlink.exe<название файла>.obj». Этой командой мы создаем
приложение, которое далее будет считать наше выражение. Если все прошло удачно,
то DOSBox 0.74 выдаст об этом сообщение. В результате будет создан файл формата
*.exe.
Рис. 8
программирование ассемблер язык
тестирование
Последний этап трансляции. Вводим «<название
файла>.exe». В окне DOSBox 0.74 появится приглашение ко вводу, вводим
значения переменныхи массива, которые могут быть целыми положительными или отрицательными
числам, в следующей последовательности: а, c, d[0], d[1], d[2], d[3]. Между
каждым введенным значением жмем Enter.
Последняя появившаяся строка - ответ, который
будет целым положительным или отрицательным числом.
6. Параметры программы
Язык программирования Си (int)
Объем папки со всеми файлами, созданными при
компиляции = 14 Мб
Объем документа с кодом = 962 байт
Средняя продолжительность компиляции = 2.5 сек
Время расчета ответа = крайне мало, менее 1 сек
Язык программирования Си ( float)
Объем папки со всеми файлами, созданными при
компиляции = 14 Мб
Объем документа с кодом =1003 байта
Средняя продолжительность компиляции = 1.52 сек
Время расчета ответа = крайне мало, менее 1 сек
Язык программирования Ассемблер УМ
Объем документа с кодом =664 байт
Среднее время компиляции и расчета ответа = 15
сек.
Язык программирования Ассемблер IBMPC
Объем папки со всеми файлами, необходимыми и
созданными при компиляции = 203 142 байт
Объем документа *.asm = 6 594 байт
Объем документа *.obj = 707 байт
Объем документа *.exe =924 байт
Средняя продолжительность компиляции = крайне
мало, менее 1 сек
Время расчета ответа = крайне мало, менее 1 сек
Заключение
В ходе выполнения проекта, мы работали с тремя
языками программирования: Си, языком Ассемблера для Учебной Машины и языком
Ассемблера IBMPC на базе архитектуры Intel 8086.
В ходе проекта были изучены некоторые аспекты
языка Ассемблера и ЭВМ в целом. Для того, чтобы решить поставленную задачу,
были продуманы алгоритмы ее решения на языках программирования Си, Ассемблер УМ
и Ассемблер IBMPC, составлены блок-схемы этих решений и написаны программы на
каждом из языков программирования. В результаты были получены рабочие
программы, которые способны решить поставленную задачу, и примеры их работы.
Думаю, что для расширений возможностей данных
программ можно попробовать написать программу на языке Си со вставкой на языке
Ассемблера, что позволит сократить некоторое количество времени при написании и
отладке программы только на языке Ассемблера IBMPC.
Список использованной литературы
1. Галисеев
Г. В. Ассемблер для Win 32. Самоучитель. - М.: Диалектика, 2007. - 368 с. -
ISBN 978-5-8459-1197-1.
2. Зубков
С. В. Ассемблер для DOS, Windows и UNIX. - М. ДМК Пресс; СПб. Питер, 2006. -
608 с. - ISBN 5-94074-259-9.
. Кип
Ирвин. Язык ассемблера для процессоров Intel =
AssemblyLanguageforIntel-BasedComputers. - М.: Вильямс, 2005. - 912 с. - ISBN
0-13-091013-9.
. Калашников
О. А. Ассемблер? Это просто! Учимся программировать. - СПб.: БХВ-Петербург,
2007. - 384 с. - ISBN 978-5-94157-709.