Скачиваний:
11
Добавлен:
09.05.2014
Размер:
43.01 Кб
Скачать

Лабораторная Работа №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 выполняет следующие действия:

  1. cохраняет в стеке адрес возврата;

  2. осуществляет безусловную передачу управления по адресу вызова (адрес первой команды процедуры).

Если вызов дальний, в стеке сохраняется два слова, в соответствии с принципом размещения слов в памяти: сначала в стек помещается CS , а потом IP.

RET (RETurn) - осуществляет возврат из процедуры в основную программу и является завершающей командой в процедуре. Вид возврата, ближний или дальний, совпадает с видом предшествующего вызова. Команда RET производит извлечение из стека адреса возврата в виде содержимого IP (ближний возврат), либо в виде пары IP:CS (дальний возврат).

LOOP осуществляет декремент регистра счётчика СХ и сравнение его нового содержимого с нулём. При равенстве осуществляется переход к следующей команде программы и выход из цикла. При невыполнении равенства осуществляется передача управления по адресу перехода в начало цикла. Для корректного применения команды LOOP необходимо перед первым входом в цикл загрузить в СХ число повторений этого цикла.

Команда LOOP является завершающей командой цикла. Поскольку переход в начало цикла осуществляется вверх по программе, то в качестве смещения (diff) задаётся отрицательное число. Команда LOOР и её модификации задаёт единый способ задания адреса перехода, короткий относительный типа SHORT (байтное смещение).

Выводы:

Программа корректно работает, компилируется из нескольких модулей. Была определена целесообразность использования макросов в программе.

Соседние файлы в папке asm lab # 5