Автор: Пользователь скрыл имя, 11 Января 2011 в 17:41, курсовая работа
В данной курсовой работе предполагается разработать алгоритм решения задачи, в которой необходимо, с использованием двух модулей, написать программу конкатенации двух строк.
Для достижения поставленной цели необходимо решить следующие задачи:
o определить метод решения задачи
o определить подходящие для использования в работе средства ассемблирования и команды транслятора
o разработать алгоритм решения задачи
o реализовать разработанный алгоритм в виде программы
Введение 3
1 Постановка задачи 5
2 Модульное программирование 6
3 Описание программы 11
Заключение 16
Список литературы 17
Приложение А 18
Приложение Б 19
CALL PRINT
…
С помощью директивы EXTRN можно указать ассемблеру, что ссылка на процедуры COPY и PRINT имеет атрибут FAR, т.е. они определены в другом ассемблерном модуле, вспомогательном.
EXTRN COPY:FAR
EXTRN PRINT:FAR
Процедуры COPY и PRINT содержат директиву PUBLIC, которая указывает ассемблеру и компоновщику, что вспомогательный модуль должен "знать" адрес процедур COPY и PRINT.
PUBLIC COPY, PRINT
…
Во вспомогательном модуле будут находиться процедуры COPY(процедура копирования двух строк в буфер) и PRINT(процедура вывода полученной строки кодом), которые получают параметры через стек. Передача аргументов через стек при вызове процедур используется наиболее часто. Суть этого способа заключается в том, что вызывающая процедура самостоятельно заносит в стек передаваемые данные, после чего обращается к вызываемой процедуре. При передаче управления процедуре процессор автоматически записывает на вершину стека два (для процедур типа near) или четыре (для процедур типа far) байта. Эти байты являются адресом возврата в вызывающую программу. Если перед передачей управления процедуре командой CALL в стек были записаны переданные процедуре данные или указатели на них, то они окажутся под адресом возврата. Для произвольного доступа к данным в стеке архитектура процессора имеет специальный регистр ЕВР\ВР (Base Point — указатель базы). Так же как и для регистра ESP\SP, обращение к ЕВР\ВР автоматически предполагает работу с сегментом стека. Перед использованием этого регистра для доступа к данным стека содержимое стека необходимо правильно инициализировать, что предполагает формирование в нем адреса, который бы указывал непосредственно на переданные данные. Для этого в начало процедуры рекомендуется включить дополнительный фрагмент кода. Он имеет свое название — пролог процедуры.
COPY PROC
;начало пролога
PUSH ВР
MOV BP,SP
;конец пролога
Код пролога состоит всего из двух команд. Первая команда push bp сохраняет содержимое ВР в стеке с тем, чтобы исключить порчу находящегося в нем значения в вызываемой процедуре. Вторая команда пролога mov bp,sp настраивает ВР на вершину стека. После этого можно не волноваться о том, что содержимое SP перестанет быть актуальным, и осуществлять прямой доступ к содержимому стека. Что обычно и делается. Для процедур типа far эти значения необходимо скорректировать еще на 2, так как при вызове процедуры дальнего типа в стек записывается полный адрес — содержимое CS и IP.
Конец процедуры также должен быть оформлен особым образом, обеспечивая корректный возврат из процедуры. Фрагмент кода, выполняющего такие действия, имеет свое название — эпилог процедуры. Код эпилога должен восстановить контекст программы в точке вызова процедуры из вызывающей программы. При этом, в частности, нужно откорректировать содержимое стека, убрав из него ставшие ненужными аргументы, передававшиеся в процедуру. Это можно сделать несколькими способами:
В нашем случае выход из процедуры осуществляется командой RETF, возвращающей стек в исходное состояние.
;выход с освобождением стека
RETF 16
Кроме того, в процедуре COPY мы определим локальную переменную [ВР-2], типа WORD и будем ее использовать. Сначала обнулим нашу локальную переменную.
MOV WORD PTR [ВР-2],0
Затем поместим в неё первую строку STOKA1 и загрузим в буфер. После мы поместим в неё вторую строку STROKA2 и только в процедуре PRINT загрузим её в буфер.
Вызов и работа процедур будет весьма напоминать то, как это делается в языках высокого уровня.
В последнем шаге, мы оттранслируем оба модуля loc и loc1. Результаты трансляции приведены в соответствии с Рисунком 1 и Рисунком 2.
Рисунок
1 - Основной модуль
Рисунок 2 - Вспомогательный модуль
В результате на диске образуются два объектных модуля: loc .OBJ и loc1.OBJ . Теперь дело за редактором связей. В командной строке укажем: LINKloc+loc1. После этого отвечаем на вопросы как обычно. При просьбе указать имя МАР-файла, указываем loc (впрочем, имя не имеет никакого значения). В результате компоновки образуется загрузочный модуль loc.exe и loc.map, а также происходит вывод на экран полученной строки, результаты вывода данной строки приведены на Рисунке 3.
Рисунок 3 – Результат вывода на экран полученной строки
В
этом файле содержатся сведения о
сегментах (начальный и конечный
адрес, длина, имя, класс), скомпонованных
в один модуль в том порядке, как они
помещены в него (начиная с младших адресов).
Обращаем Ваше внимание, что вначале идут
сегменты модуля loc, а затем сегменты модуля
loc1. Именно так, как мы указали модули в
командной строке. Если бы в командной
строке было LINKloc1+loc, то порядок сегментов
был бы обратный. При этом сначала запустился
бы модуль loc1, что привело бы к катастрофе.
Итак, главный модуль должен быть первым,
порядок остальных модулей уже не так
важен.
Нам
удалось разработать алгоритм решения
задачи, использующей два модуля, для
написания программы
Особенностью данной задачи является то, что данные передаются в модулю через стек. Этот метод передачи данных практичен и удобен в применении.
Алгоритм
решения данной задачи разработан и
оформлен в виде программы и представлен
в приложении данной работы.
Листинг 1. Основной модуль
EXTRN COPY:FAR
EXTRN print:FAR
STE SEGMENT STACK
DB 100 DUP(0)
STE ENDS
DATA SEGMENT
STROKA1 DB "GRAND",0
STROKA2 DB "MOTHER",0
BUFER DB 100 DUP(?)
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE, DS:DATA, SS:STE
BEGIN
MOV AX,DATA
MOV DS,AX
PUSH DS
LEA AX,BUFER
PUSH AX
PUSH DS
LEA AX,STROKA1
PUSH AX
PUSH DS
LEA AX,STROKA2
PUSH AX
CALL COPY
MOV AX,03
INT 10H
PUSH DS
LEA AX,BUFER
PUSH AX
CALL PRINT
MOV AX,4C00H
INT 21H
CODE ENDS
END
BEGIN
Листинг 2. Вспомогательный модуль
PUBLIC COPY, PRINT
COD SEGMENT
ASSUME CS:COD
COPY PROC
PUSH ВР
MOV BP,SP
SUB SP,2
MOV WORD PTR [ВР-2],0
LDS SI,[ВР+10]
LDS DI,[ВР+14]
LO1:
MOV AL,DS:[SI]
CMP AL,0
JZ ZER1
MOV DS:[DI],AL
INC DI
INC SI
INC WORD PTR [ВР-2]
JMP SHORT L01
ZER1:
LDS SI,[BP+6]
L02:
MOV AL,DS:[SI]
CMP AL,0
JZ ZER2
MOV DS:[DI],AL
INC DI
INC SI
INC WORD PTR [ВР-2]
JMP SHORT LO2
ZER2:
MOV BYTE PTR DS:[DI],0
MOV AX,[ВР-2]
ADD SP,2
POP ВР
RETF 16
COPY ENDP
PRINT PROC
PUSH ВР
MOV ВР,SP
LDS SI,[BP+б]
LO3:
MOV DL,DS: [SI]
CMP DL,0
JZ ZER3
MOV AH, 2
INT 21H
INC SI
JMP SHORT L03
ZER3:
POP BP
RETF 4
PRINT ENDP
COD ENDS
END