Грудное вскармивание. ОргЭВМиС_лаб. Самостоятельная работа по написанию программы с использованием предлагаемых в качестве составных частей заготовленных фрагментов текста программы
Скачать 84.98 Kb.
|
Лабораторная работа 6. Процедуры. Цель: освоение средств, обеспечивающих модульное программирование. . Необходимые пояснения. Модуль – это структурно выделенная и поименованная часть прикладной программы, предназначенная для выполнения заданных функций (решения подзадачи). Модулей, составляющих программу, может быть несколько. В многомодульной программе выделяется один главный модуль, который задает порядок срабатывания остальных модулей. Программа имеет иерархическую структуру. main М1.1 М1.2 М1.3 М1 М1.4 М1.1.1 М1.1.2 При завершении описания модуля main в директиве end необходимо указать стартовую метку (только в main!). Когда создается многомодульная программа, требуются глобальные и локальные метки и переменные. Переменная – это информационный объект, имеющий текущее значение, имя, обозначающее адрес хранения текущего значения и структуру, которая может быть простой (из одного элемента) или составной. Для обеспечения взаимодействия модулей необходимо объявить глобальные метки и переменные. Объявление меток и переменных производится с помощью двух списков, задаваемых директивами EXTRN и PUBLIC. Список, задаваемый в модуле директивой EXTRN, содержит идентификаторы внешних переменных и меток, к которым осуществляется обращение из данного модуля. Второй список содержит внутренние идентификаторы, к которым разрешено обращаться из других модулей. Далее приводятся описания некоторых директив. Директива TITLE. Директива TITLE текст, представляющий заголовок листинга, инициирует печать на каждой странице листинга заголовка, включающего имя модуля (6 символов) и описание (60 символов) его назначения. Листинг представляет собой текстовый файл, содержащий описание исходной ассемблерной программы, код каждой ассемблированной команды, список используемых меток, описание перекрестных ссылок, сегментов и групп сегментов. Директивы EXTRN и PUBLIC. Необходимость использования директив EXTRN и PUBLIC возникает при описании взаимодействующих программных модулей. Пусть два модуля взаимодействуют следующим образом. В модуле 1 осуществляется изменение данных, хранимых в переменной F, определенной в модуле 2. Для объявления глобальной переменной F используются директивы EXTRN и PUBLIC. Для определения переменной F необходима директива, задающая тип переменной. В качестве такой директивы можно использовать, например, директиву DB – определить байт (define byte). Определение переменной задается строкой, разделенной пробелами на три части. В начале строки размещается идентификатор – имя переменной. Далее размещается аббревиатура директивы, указывающей тип именованной переменной. После аббревиатуры директивы следует перечень значений и специальных операторов, разделенных запятыми. В качестве значений используются четыре типа констант. Целые константы, заданные с помощью цифр требуемой системы счисления. Константы с плавающей запятой. Символьные константы, представленные символом, размещенным между двумя апострофами. Строковые литералы, представляемые последовательностью символов, размещенных между знаками двойных кавычек. В качестве специальных операторов используются оператор повторения константы DUP, который может быть вложенным и оператор ? задания неопределенного значения. При описании взаимодействующих модулей mod1 и mod2 необходимо в директиве EXTRN для объявляемых переменных и меток указать тип, который соответствует типу, заданному при определении переменных и меток. TITLE mod1 TITLE mod2 EXTRN F:BYTE; внешняя глобальная переменная. PUBLIC F DATA SEGMENT; начало сегмента с именем DATA. DATA SEGMENT DATA ENDS F DB ?; переменная F типа байт DATA ENDS CODE SEGMENT CODE SEGMENT ASSUME CS:CODE, DS:DATA CODE ENDS START: END MOV AX, DATA MOV DS, AX MOV F, 5 CODE ENDS END START Операнды директив EXTRN и PUBLIC разделяются запятыми. EXTRN имя:ТИП, …, имя:ТИП PUBLIC имя, …, имя Типы для переменных: byte, word, dword, а другие можно найти в справочнике. Типы для меток: NEAR – указывает на размещение метки внутри сегмента; FAR – указывает на размещение метки за пределами данного сегмента; SHORT – метки указанного типа используется в инструкциях перехода для задания адреса назначения. Пределы перехода от текущей команды ограничены величинами +127 и -128 байт. Процедура, или подпрограмма – это основная функциональная единица декомпозиции некоторой задачи. Процедура представляет собой группу команд для решения конкретной подзадачи и обладает средствами получения управления из точки вызова задачи более высокого уровня и возврата управления в эту точку. В простейшем случае программа может состоять из одной процедуры. Другими словами, процедуру можно определить как правильным образом оформленную совокупность команд, которая, будучи однократно описана, при необходимости может быть вызвана в любом месте программы. Директива описания процедуры. Процедура – это поименованная часть программы. Используется для структурирования программы. Вызывается с помощью команды: call имя_процедуры. При работе с процедурами необходимо следить за состоянием используемого стека. Для оформления процедуры используется директива PROC, имеющая следующий формат описания. имя proc атрибуты --------------------- операторы процедуры --------------------- ret; команда завершения процедуры имя endp При выполнении команды ret из стека извлекается на регистр IP адрес возврата, который был помещен в стек при выполнении команды call. Адрес возврата может быть дальний (far). Для его хранения используются 2 слова, которые из стека перемещаются в регистры CS:IP. Если адрес возврата ближний (near), тогда для хранения используется 1 слово, перемещаемое в регистр IP. Размер слова – 2 байта. Для указания типа адреса возврата используется атрибут в директиве proc. Тип атрибута определяется местоположением тела процедуры по отношению к оператору вызова процедуры call а) Если call и тело процедуры расположены в одном сегменте кода и в одном модуле, то используется near. Указывать явно необязательно. б) Если call и тело процедуры расположены в разных сегментах, но в одном модуле, то используется тип far и атрибутный оператор ptr (указатель). call FAR PTR имя в) Если call и тело процедуры расположены в разных сегментах и в разных модулях, то используется far и еще требуется в начале модуля основной программы, содержащей call, указать имя процедуры в списке extrn, а в модуле, содержащем тело процедуры, указывается имя процедуры в списке public. В операторе call использовать тип и атрибутный оператор FAR PTR не требуется. В теле процедуры сначала необходимо выполнить операции сохранения регистров в стеке (PUSH), а в конце процедуры восстановить (POP) содержимое регистров. Для передачи данных между процедурами существуют специальные методы. Простейший способ передачи данных в процедуру предусматривает использование глобальных переменных или регистров. Для обретения навыков использования процедуры предполагается выполнение следующего задания. Задание Необходимо создать основной модуль main программы, который после пуска программы осуществляет вывод на экран сообщения: “нажмите любую клавишу”, а затем вызывает call input процедуру, которая осуществляет ожидание нажатия клавиши. При нажатии клавиши процедура input вводит идентификатор нажатой клавиши и возвращает управление основному модулю main программы. В модуле main программы анализируется идентификатор нажатой клавиши. Если нажата клавиша, помеченная символом A, то модуль main программы осуществляет вызов процедуры output1, обеспечивающей печать сообщения “нажата клавиша A - взаимодействие завершено” и возвращающей управление основному модулю main программы, который завершает работу программы. Если идентификатор нажатой клавиши не соответствует символу A, то основной модуль main программы осуществляет вызов процедуры output2, которая осуществляет печать сообщения “нажмите клавишу A” и возвращает управление основному модулю main программы. Программа этого модуля в данном случае осуществляет безусловный переход (JMP) на существующую в программе команду CALL INPUT. Разработка и отладка многомодульной программы выполняется поэтапно. На первом этапе необходимо создать с помощью текстового редактора четыре программных модуля: MAIN, INPUT, OUTPUT1, OUTPUT2 и сохранить их в четырех соответствующих файлах с добавлением к именам так называемого расширения asm. Возможные варианты программных модулей input, output1, output2 приводятся ниже. TITLE INPUT TITLE OUTPUT1 PUBLIC INPUT PUBLIC OUTPUT1 .model small .model small .stack 100h .stack 100h .data .data .code mes1 DB 10, 13, ‘Нажата клавиша A - INPUT PROC far взаимодействие завершено $’ mov ax,@data .code mov ds,ax OUTPUT1 PROC far mov ah,1 mov ax,@data int 21h mov ds,ax ret mov ah,9 INPUT endp lea dx,mes1 End int 21h ret OUTPUT1 endp end TITLE OUTPUT2 PUBLIC OUTPUT2 .model small .stack 100h .data mes2 DB 10, 13, ‘Нажмите клавишу A $’ .code OUTPUT2 PROC far mov ax,@data mov ds,ax mov ah,9 lea dx,mes2 int 21h ret OUTPUT2 endp end На втором этапе для каждого исходного модуля необходимо построить объектный модуль. Для достижения этой цели необходимо четырежды задать и выполнить следующую командную строку, изменяя nameprog на соответствующее имя. >TASM/Z/ZI/L nameprog.asm На третьем этапе для построения исполняемого модуля с возможностью дальнейшей отладки создаваемой программы с помощью программы TD.EXE необходимо задать следующую командную строку. >TLINK/I/M/L/S/V main.obj vvod.obj vivod.obj,name.exe,name.map При разработке многомодульной программы командная строка может содержать четыре параметра, расположенных в фиксированных позициях командной строки. Параметры отделяются друг от друга запятыми. В первой позиции командной строки располагаются последовательно, начиная с головного, имена объектных модулей. Перечисляемые имена предварительно созданных объектных модулей должны быть разделены пробелом. После последнего из перечисленных имен ставится запятая, если предполагается использовать остальные параметры. При использовании только одного первого параметра имя создаваемого исполняемого модуля соответствует имени головного модуля. Второй параметр командной строки соответствует имени, выбранному для исполняемого модуля. В третьей позиции располагается имя, выбранное для так называемой карты распределения памяти. В четвертой позиции командной строки можно перечислить библиотеки, используемые в программе. В данной работе эта позиция не заполняется. На четвертом этапе необходимо осуществить отладку созданной программы, используя программу TD.EXE. После разработки и отладки рассмотренной выше многомодульной программы требуется модернизировать текст модулей созданной программы таким образом, чтобы обеспечить демонстрацию передачи параметров процедурам через стек. Модернизированную программу необходимо отладить и составить отчет о проделанной работе. Лабораторная работа 7. Ввод чисел, задаваемых в различных системах счисления. Цель: изучение систем счисления и средств ввода данных. Необходимые пояснения. При написании программы ввода информации с клавиатуры предполагается использование интерфейса прикладных программ (API), обеспечиваемого операционной системой. Для обращения к функциям интерфейса в языке ассемблера используются программные прерывания, задаваемые командой INT. Номер 01h вызываемой функции ввода данных с клавиатуры необходимо задать в регистре AH. После нажатия клавиши, помеченной буквенно-цифровым символом, осуществляется размещение ASCII-кода символа в регистре AL. Возможный вариант программы ввода с клавиатуры 16-ти битового двоичного числа приведен ниже. TITLE VVOD ввод 16 бит двоичного числа, начиная со старших. .Model Small .STACK 100h ;Public VVOD .data object dw ? message db 10,13,’ввод очередного бита $’ .code VVOD: mov ax,@data mov ds,ax mov object,0 lea di,object mov cx,16 vv_0_1: mov ah,9 lea dx,message int 21h mov ah,1 int 21h cmp al,31h jz vv1 cmp al,30h jz vv0 jmp vv_0_1 vv1: stc rcl word ptr[di],1; di содержит адрес переменной object, используемой для хранения вводимого числа. jmp loo vv0: clc rcl word ptr[di],1 loo: loop vv_0_1 mov ax,4C00h int 21h end VVOD Задание Требуется отладить приведенную программу и в отчете дать комментарий каждой строки приведенного выше текста программы. Затем необходимо модифицировать приведенный текст программы таким образом, чтобы модифицированная программа осуществляла ввод 8-ричного числа, состоящего из трех разрядов. Выполнить отладку модифицированной программы и составить отчет о работе. Лабораторная работа 8. Вывод на экран результатов вычислений. Цель: освоение средств операционной системы для осуществления вывода данных. Необходимые пояснения. Ниже приведен возможный вариант программного модуля вывода на экран результата вычисления, сохраняемого в переменной rezmask в двоичном коде. На экран результат вычисления выводится в виде двух разрядов десятичного числа. TITLE VIVOD вывод двоичного результата в виде двух разрядов десятичного числа. .Model Small .STACK 100h ;extrn resmask:byte ;в resmask хранится выводимый результат (двоичное число) ;Public VIVOD .data resmask db 14 mes1 db 10,13,’RESULT: $’ .code VIVOD: mov ax,@data mov ds,ax cmp resmask,10; в переменной resmask задается значение не более 19 jb m1 sub resmask,10 mov dl,’1’ mov ah,2 int 21h m1: mov dl,resmask or dl,30h mov ah,2 int 21h mov ax,4C00h int 21h End VIVOD Задание Необходимо отладить приведенную выше программу и включить ее в отчет, добавив комментарий к каждой строке программы. Затем требуется модифицировать приведенный текст программы таким образом, чтобы модифицированная программа осуществляла вывод результата вычисления из переменной resmask на экран в виде двоичного числа. Необходимо отладить модифицированную программу и составить отчет о работе. Лабораторная работа 9. Объединение программных модулей ввода и вывода данных. Цель: закрепление навыков разработки многомодульной программы. Предполагается выполнение четырех этапов, описанных в лабораторной работе 6. Необходимые пояснения Требуется тексты программных модулей VVOD и VIVOD, созданные при выполнении лабораторных работ 7, 8 оформить в виде процедур и создать программный модуль main, осуществляющий правильные и своевременные вызовы процедур VVOD и VIVOD, осуществляющих соответственно ввод числа в переменную OBJCT и вывод содержимого переменной resmask в виде двухразрядного десятичного числа. Причем, после ввода значения, сохраняемого в переменной object, введенное значение необходимо переместить в переменную resmask. Содержимое переменной rezmask необходимо проверить на допустимость. Если значение, сохраняемое в переменной rezmask, не попадает в диапазон от 0 до 19, то необходимо обнулить эту переменную. После завершения анализа переменной rezmask необходимо с помощью процедуры VIVOD распечатать на экране монитора содержимое этой переменной. Задание Требуется отладить созданные программные модули main, vvod, vivod и включить их в отчет о проделанной работе. Затем осуществить модернизацию процедуры VIVOD таким образом, чтобы измененная процедура обеспечивала возможность вывода содержимого переменной rezmask, допустимый диапазон десятичных значений которой задается от 0 до 99. Выполнить отладку модернизированной программы и составить отчет о проделанной работе. |