написанные программы / asm lab # 5 / lab5
.doc
Лабораторная Работа №5
„Макросы, процедуры и модульное программирование на языке Ассемблер“
Работу выполнил
Студент гр. 2100
Голубцов Евгений
2009
Цель работы:
научиться составлять многомодульные программы и обращаться к процедурам, расположенным в другом модуле; определить целесообразность расположения в программе макросов и научиться с ними работать.
Код основной программы:
.model small
.stack 512
.data
result db 7 dup(?)
inputdata db 10 dup(?)
errormessage db 'input data is not correct$'
.code
extrn my_proc:far
main proc
mov ax, @data
mov ds, ax
;-----------------Ввод числа--------------------------------
mov cx, 0
lea si, inputdata
mov ah, 01h
in2: ;цикл чтения цифр - пока не нажат Enter
int 21h
mov [si], al
inc cx
inc si
cmp al, 0dh
jne in2
dec si
mov [si], BYTE PTR 64h
mov ah, 02h
mov dx, 10 ;выводим символ перевода строки
int 21h
mov dx, 13 ;выводим символ возврата каретки
int 21h
;-----------------------------------------------------------
;---------------передача параметров-------------------------
;записываем в стек строку символов
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
lea dx, errormessage
jmp outputmessage
success:
lea dx, result
outputmessage:
mov ah, 09h
int 21h
;-----------------------------------------------------------
mov ax, 4c00h
int 21h
main endp
end main
end
Код подпрограммы:
.model small
.code
my_proc proc
mov bp, sp
;----------------получение начальных данных из стека---------------
add bp, 4 ;4 байта адрес возврата
mov bx, [bp]; ;адрес, куда записывать результат
add bp, 2
mov ax, 0
cmp BYTE PTR [bp], '-'
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'
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 (байтное смещение).
Выводы:
Программа корректно работает, компилируется из нескольких модулей. Была определена целесообразность использования макросов в программе.