написанные программы / asm lab # 5 / lab5new
.doc
Лабораторная Работа №5
„Макросы, процедуры и модульное программирование на языке Ассемблер“
Работу выполнил
Студент гр. 2100
Голубцов Евгений
2009
Цель работы:
научиться составлять многомодульные программы и обращаться к процедурам, расположенным в другом модуле; определить целесообразность расположения в программе макросов и научиться с ними работать.
Код основной программы:
.model small
.stack 512
.data
result db 7 dup(?)
inputdata db 10 dup(?)
errormessage db 'input data is not correct!$'
entmessage db 'Please, enter the number:$'
okmessage db 'The result number is:$'
.code
extrn my_proc:far
main proc
mov ax, @data
mov ds, ax
macros2 MACRO reg,type
mov reg, type
int 21h
ENDM
macros3 MACRO
mov ah, 02h
mov dx, 10 ;выводим символ перевода строки
int 21h
mov dx, 13 ;выводим символ возврата каретки
int 21h
ENDM
;-----------------Выводим приветствие-----------------------
macros3
lea dx, entmessage
;mov ah, 09h
;int 21h
macros2 ah,09h
;mov ah, 02h
;mov dx, 10 ;выводим символ перевода строки
;int 21h
;mov dx, 13 ;выводим символ возврата каретки
;int 21h
macros3
;-----------------Ввод числа--------------------------------
mov cx, 0
lea si, inputdata
mov ah, 01h
in2: ;цикл чтения цифр - пока не нажат Enter
int 21h
mov [si], al
inc cx
cmp cx,7; проверяем число элементов (меньше 7)
jg err_mess
inc si
cmp al, 0dh
jne in2
dec si
mov [si], BYTE PTR 64h
mov ah, 02h
;-----------------------------------------------------------
;---------------передача параметров-------------------------
;записываем в стек строку символов (передаем по значению)
cikl:
mov bl, BYTE PTR [si]
push bx
dec si
dec cx
cmp cx, 0
jne cikl
;записываем в стек адрес результата (передаем по адресу)
lea dx, result
push dx
;-----------------------------------------------------------
;---------вызов процедуры, проверка на ошибки---------------
call my_proc
cmp ax, 0
je success
err_mess:
macros3
macros3
lea dx, errormessage
jmp outputmessage
success:
macros3
macros3
lea dx, okmessage
macros2 ah,09h
macros3
lea dx, result
outputmessage:
;mov ah, 09h
;int 21h
macros2 ah,09h
macros3
;-----------------------------------------------------------
;mov ax, 4c00h
;int 21h
macros2 ax,4c00h
main endp
end main
end
Код подпрограммы:
.model small
.code
my_proc proc
macros1 MACRO x
add bp, 2
cmp BYTE PTR [bp], x
ENDM
mov bp, sp
;----------------получение начальных данных из стека---------------
add bp, 4 ;4 байта адрес возврата
mov bx, [bp]; ;адрес, куда записывать результат
mov ax, 0
;add bp, 2
;cmp BYTE PTR [bp], '-'
macros1 '-'
jne ex1
mov [bx], BYTE PTR 45
inc bx
add bp, 2
ex1:
push bx
;------------------------------------------------------------------
;--------чтение строки символов и преобразование в число-----------
mov bx, 10
cikl:
mul bx
cmp [bp], BYTE PTR '0'
jl exception
cmp [bp], BYTE PTR '9'
jg exception
add ax, [bp]
sub ax, 30h
;add bp, 2
;cmp BYTE PTR [bp], 'd'
macros1 'd'
jne cikl
;------------------------------------------------------------------
;-----------------------приведение к 16-ричной записи--------------
pop bx
mov cl, 4
rol ax, cl
mov cx, 4
cikl1:
mov dx, ax
and dx, 000Fh
cmp dl, 9
jg letters
add dl, 30h
jmp numbers
letters:
add dl, 55
numbers:
mov [bx], dl
push cx
mov cl, 4
rol ax, cl
pop cx
inc bx
loop cikl1
mov [bx], BYTE PTR 36
mov ax, 0
jmp return
;---------------------------------------------------------------------
;------------------------ошибка---------------------------------------
exception:
pop bx
mov ax, 1
;---------------------------------------------------------------------
return:
ret
my_proc endp
end
Результаты работы программы:
Программа корректно преобразовывает заданное число в шестнадцатеричный формат и выводит его. Если задано некорректное число, выводится сообщение об ошибке.
Основные использованные команды:
CALL - для вызова процедуры. Для обеспечения возможности возврата в основную программу после завершения процедуры (подпрограммы) выполнение команды CALL сопровождается сохранением адреса возврата в стеке. Адрес возврата состоит из содержимого IP при ближнем вызове (CALL NEAR) и дополнительно из CS при дальнем вызове CALL FAR.
Таким образом, команда CALL выполняет следующие действия:
-
cохраняет в стеке адрес возврата;
-
осуществляет безусловную передачу управления по адресу вызова (адрес первой команды процедуры).
Если вызов дальний, в стеке сохраняется два слова, в соответствии с принципом размещения слов в памяти: сначала в стек помещается CS , а потом IP.
RET (RETurn) - осуществляет возврат из процедуры в основную программу и является завершающей командой в процедуре. Вид возврата, ближний или дальний, совпадает с видом предшествующего вызова. Команда RET производит извлечение из стека адреса возврата в виде содержимого IP (ближний возврат), либо в виде пары IP:CS (дальний возврат).
LOOP осуществляет декремент регистра счётчика СХ и сравнение его нового содержимого с нулём. При равенстве осуществляется переход к следующей команде программы и выход из цикла. При невыполнении равенства осуществляется передача управления по адресу перехода в начало цикла. Для корректного применения команды LOOP необходимо перед первым входом в цикл загрузить в СХ число повторений этого цикла.
Команда LOOP является завершающей командой цикла. Поскольку переход в начало цикла осуществляется вверх по программе, то в качестве смещения (diff) задаётся отрицательное число. Команда LOOР и её модификации задаёт единый способ задания адреса перехода, короткий относительный типа SHORT (байтное смещение).
Выводы:
Программа корректно работает, компилируется из нескольких модулей. Была определена целесообразность использования макросов в программе.