написанные программы / asm lab # 5 / lab5v
.doc
Лабораторная Работа №5
„Макросы, процедуры и модульное программирование на языке Ассемблер“
Пермяков, 2100
2009
Цель работы: научиться составлять многомодульные программы и обращаться к процедурам, расположенным в другом модуле; определить целесообразность расположения в программе макросов и научиться с ними работать.
Код основной программы:
.model small
.stack 512
.data
result db 7 dup(?)
datainput db 10 dup(?)
problem db 'Data is incorrect$'
.code
extrn newproc:far
main proc
mov ax, @data
mov ds, ax
mov cx, 0 ;Ввод числа-с
lea si, datainput
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
povtor: ;Передача параметров-с
mov bl, BYTE PTR [si] ;Изволим помещать-с в стек строку символов
push bx
dec si
dec cx
cmp cx, 0
jne povtor
lea dx, result ;Помещаем-с в стек адрес на результат
push dx
call newproc ;Сие следует вызов процедуры-с с проверкою на ошибки
cmp ax, 0
je success
lea dx, problem
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
newproc proc
mov bp, sp
;Изволим получать-с данные из стека
add bp, 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
povtor:
mul bx
cmp [bp], BYTE PTR '0'
jl lie
cmp [bp], BYTE PTR '9'
jg lie
add ax, [bp]
sub ax, 30h
add bp, 2
cmp BYTE PTR [bp], 'd'
jne povtor
;Приводим-с к записи в системе счисления заморской, шестнадцатеричной
pop bx
mov cl, 4
rol ax, cl
mov cx, 4
povtor1:
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 povtor1
mov [bx], BYTE PTR 36
mov ax, 0
jmp return
;Ложь в данных изволит содержаться! Ошибка!
lie:
pop bx
mov ax, 1
return:
ret
newproc 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 (байтное смещение).
Выводы:
Программа корректно работает, компилируется из нескольких модулей. Была определена целесообразность использования макросов в программе.