Структурное программирование, схема алгоритма. Программа на языке Си для int, float. Подпрограмма ввода и вывода целых чисел на Ассемблере IBM. Тестирование и отладка, инструкция пользователя. Язык программирования Си (для int и float), этапы трансляции.
Аннотация к работе
Перевод программы на языке ассемблера в исполнимый машинный код (вычисление выражений, раскрытие макрокоманд, замена мнемоник собственно машинными кодами и символьных адресов на абсолютные или относительные адреса) производится ассемблером - программой-транслятором, которая и дала языку ассемблера его название. Кроме того, язык ассемблера позволяет использовать символические метки вместо адресов ячеек памяти, которые при ассемблировании заменяются на вычисляемые ассемблером или компоновщиком абсолютные или относительные адреса, а также так называемые директивы (команды ассемблера, не переводимые в машинные команды процессора, а выполняемые самим ассемблером). Необходимо разработать программы для ее вычисления на языках Си, Ассемблер УМ и Ассемблер IBMPC. Ex77 start 0 lda c mul c2 sta p ldx c0 lda c0 usl comp c12 jgt art jeq art jsubinc rmox,a;i:=i 1 add c3 rmoa,x jusl art lda y hlt c word 20 e word 2 c0 word 0 c1 word 1 c3 word 3 c4 word 4 c12 word 12 c2 word 2 y word 0 d word 20 word 12 word 4 word-16 oresb 3 kresb 3 presb 3 inclda e mul e add c1 sta k ldad,x div c4 sta o lda p sub o div k add y sta y rsub end Ex77 ; на правильность cmpcl, "0"; если введен неверный символ <0 jler cmpcl, "9"; если введен неверный символ >9 jaer subcl, "0"; делаем из символа число mulbx; умножаем на 10 addax, cx; прибавляем к остальным incsi; указатель на следующий символ jmp ii2; повторяем er: movdx, offseterror; если была ошибка, то выводим сообщение обВ ходе выполнения проекта, мы работали с тремя языками программирования: Си, языком Ассемблера для Учебной Машины и языком Ассемблера IBMPC на базе архитектуры Intel 8086.
Введение
Язык ассемблера (англ. 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
Ex77 start 0 lda c mul c2 sta p ldx c0 lda c0 usl comp c12 jgt art jeq art jsubinc rmox,a;i:=i 1 add c3 rmoa,x jusl art lda y hlt c word 20 e word 2 c0 word 0 c1 word 1 c3 word 3 c4 word 4 c12 word 12 c2 word 2 y word 0 d word 20 word 12 word 4 word -16 oresb 3 kresb 3 presb 3 inclda e mul e add c1 sta k ldad,x div c4 sta o lda p sub o div k add y sta y rsub end Ex77
Блок схема inc
Рис. 2
3.2 Подпрограмма ввода и вывода целых чисел на Ассемблере IBM
Подпрограмма ввода
Блок схема
Рис. 3
Подпрограмма на языке программирования Ассемблер IBMPC
INPUTINTPROC mov ah, 0ah xor di, di mov dx, offset buff; адресбуфера int 21h; принимаем строку movdl, 0ah movah, 02 int 21h
; выводим перевод строки и обрабатываем
; содержимое буфера movsi, offset buff 2; берем адрес начала строки cmpbyteptr [si], "-"; если первый символ минус jnz ii1 movdi, 1; устанавливаем флаг incsi; и пропускаем его ii1: xorax, ax movbx, 10; основание сс ii2: movcl, [si]; берем символ из буфера cmpcl, 0dh; проверяем не последний ли он jzendin
; если символ не последний, то проверяем его
; на правильность cmpcl, "0"; если введен неверный символ <0 jler cmpcl, "9"; если введен неверный символ >9 jaer subcl, "0"; делаем из символа число mulbx; умножаем на 10 addax, cx; прибавляем к остальным incsi; указатель на следующий символ jmp ii2; повторяем er: movdx, offseterror; если была ошибка, то выводим сообщение об
; этом и выходим mov ah,09 int 21h int 20h; все символы из буфера обработаны число
; находится в ax endin: cmp di,1; если установлен флаг, то jnz ii3 negax; делаем число отрицательным ii3: ret errordb "incorrect number$" buffdb 6,7 Dup(?)
INPUTINTENDP
3.2 Подпрограмма на языке программирования Ассемблер IBMPC
Процедура вывода
OUTINTPROCNEAR;=====Процедура вывода testax, ax; проверяем число на знак. jns oi1 movcx, ax;если оно отрицательное, выведем минус и ; оставим его модуль movah, 02h mov dl, "-" int 21h movax, cx negax oi1: xorcx, cx; количество цифр будем держать в CX movbx, 10; основание сс. 10 для десятеричной и т.п. oi2: xordx, dx divbx; делим число на основание сс, в остатке
; получается последняя цифра pushdx; сразу выводить ее нельзя, поэтому сохраним
; ее в стэке inccx
; а с частным повторяем то же самое, отделяя
; от него очередную testax, ax; цифру справа, пока не останется ноль, что ;значит, что дальше jnz oi2; слева только нули
;========Вывод========= mov ah, 02h oi3: pop dx adddl, "0"; извлекаем очередную цифру, переводим ее в
; символ и выводим int 21h loop oi3; повторим ровно столько раз, сколько цифр
; насчитали ret
OUTINTENDP
Рис. 4
3.3 Программа на языке программирования Ассемблер IBMPC
BUF db 4 DUP (20h),13,10,"$" str1 db "Resultat",13,10,"$"
.code
OUTINTPROC testax, ax; Проверяем число на знак. jns oi1
; Если оно отрицательное, выведем
;минус и оставим его модуль. mov cx, ax mov ah, 02h mov dl, "-" int 21h movax, cx negax
; Количество цифр будем держать в CX oi1: xorcx, cx movbx, 10; основание сс. 10 для десятеричной и т.п. oi2: xordx,dx divbx
; Делим число на основание сс.
;В остатке получается последняя цифра.
; Сразу выводить ее нельзя, ;поэтому сохраним ее в стэке. pushdx inccx
; А с частным повторяем то же самое, ;отделяя от него очередную
; цифру справа, пока не останется ноль, ; что значит, что дальше слева только нули. testax, ax jnz oi2
; Теперь приступим к выводу. movah, 02h oi3: popdx
; Извлекаем очередную цифру, ;переводим ее в символ и выводим. adddl, "0" int 21h
; Повторим ровно столько раз, ;сколько цифр насчитали. loop oi3 ret
OUTINTENDP
INPUTINTPROC mov ah,0ah xordi,di movdx,offset buff; аддресбуфера int 21h; принимаем строку mov dl,0ah mov ah,02 int 21h; выводим перевода строки
; обрабатываем содержимое буфера movsi,offset buff 2; берем аддрес начала строки cmpbyteptr [si],"-"; если первый символ минус jnz ii1 mov di,1; устанавливаем флаг incsi; и пропускаем его ii1: xorax,ax mov bx,10; основание сс ii2: movcl,[si]; берем символ из буфера cmp cl,0dh; проверяем не последний ли он jzendin
; если символ не последний, то ;проверяем его на правильность cmp cl,"0"; если введен неверный символ <0 jler cmp cl,"9"; если введен неверный символ >9 jaer sub cl,"0"; делаем из символа число mulbx; умножаем на 10 addax,cx; прибавляем к остальным incsi; указатель на следующий символ jmp ii2; повторяем er:; если была ошибка, то выводим
;сообщение об этом и выходим movdx, offseterror mov ah,09 int 21h int 20h
; все символы из буфера
;обработаны число находится в ax endin: cmp di,1; если установлен флаг, то jnz ii3 negax; делаем число отрицательным ii3: ret errordb "incorrect number$" buffdb 6,7 Dup(?)
CMPSI,t jne for mov CX,0 mov AX, y mov DX, AX;DX:=AX
CALLOUTINT mov AX,4c00h int 21h
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 28
Переведем результат работы Ассемблера УМ в десятичную СС: 1D = 29
14 = 20
1C = 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 слово.
Открываем этот файл в ПРОГРАММЕТСОМ.exe при помощи вкладки «Asm», далее в отрывшемся окне выбираем вкладку «File» затем «Open» и находим нужный файл с кодом в формате *.txt. Код программы загрузится на вкладку «Sourcemodule». Нажимаем на вкладку «GOASM», если в коде нет ошибок, то приложение выведет синюю запись «Noerrorsdetected!» Далеезагружаеммодульпрограммывпрограмме.
TCOM.exe при помощи вкладки «Load» в основном окне.
Запускаем программу при помощи клавиши «Start» в основном окне.
Результат подстановки значений «а», «с» и массива «d» в выражение (1) будет находиться в Аккумуляторе, который располагается во втором поле программе TCOM.exe(смотреть рис. 1). Значением Аккумулятора будет число в шестнадцатеричной СС.
Язык программирования Ассемблер IBMPC
Запускаем эмулятор DOSBOX 0.74. С его помощью переходим на необходимый диск (используем команду «mountc», смотреть рис. 2 (файл находится на диске С в папке с название «1», название файла «сс»)) и отрываем папку, в которой расположен файл с кодом программы в формате *.asm, компоновщик tasm.ехеи редактор связей 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.
3. Кип Ирвин. Язык ассемблера для процессоров Intel = ASSEMBLYLANGUAGEFORINTEL-BASEDCOMPUTERS. - М.: Вильямс, 2005. - 912 с. - ISBN 0-13-091013-9.
4. Калашников О. А. Ассемблер? Это просто! Учимся программировать. - СПБ.: БХВ-Петербург, 2007. - 384 с. - ISBN 978-5-94157-709.