Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология Образование Политология Производство Психология Стандартизация Технологии |
Передача и возврат управления и данных ⇐ ПредыдущаяСтр 6 из 6
При рассмотрении передачи и возврата управления и данных необходимо учитывать следующие моменты: · тип команд вызова и возврата; · способы передачи параметров – по ссылке, по значению, для передачи по ссылке – тип адресации, передача сложных типов данных – массивов и структур; · доступ к данным в подпрограмме; · при передаче параметров через стек, в каком порядке помещать параметры в стек и какая из программ ответственна за очистку стека; · как располагаются многомерные массивы в памяти; · выполняется ли выравнивание полей структур на границу слова, двойного слова и т.п.; · СП могут осуществлять обязательное преобразование данных некоторых типов при использовании их в качестве фактических параметров; · как представляются сложные типы данных: структуры, записи и объекты (C++), записи, записи с вариантами, множества (Pascal). Сохранение регистров В СП для языков Pascal и C фирм MicroSoft и Borland для компьютеров типа IBM PC подпрограммы обязаны сохранять содержимое регистров CS, DS, SS, SP, BP. В других СП требования могут отличаться. 2.4. Соглашение о связях языка Pascal (сводка) Преобразование имен Значащая длина идентификатора может быть от 8 до 250 символов, умолчание – 32. Для изменения служит команда Options+Compiler+Source. Строчные буквы преобразуются в прописные. Передача и возврат управления Тип подпрограмм (near или far) и, следовательно, команд call и ret зависит от двух факторов: · обращение к внешним подпрограммам всегда осуществляется как к far подпрограммам; · если включен режим Force Far Calls (команда Options+Compiler), то и подпрограммы внутри единицы трансляции рассматриваются как far, в противном случае такие подпрограммы рассматриваются как near. Передача и возврат данных Параметры передаются в стеке. Помещаются в стек в порядке, соответствующем порядку записи в тексте подпрограммы, т.е. последний в тексте будет на самом верху стека. По умолчанию параметры передаются по значению, при наличии модификатора var – по ссылке, при этом размер указателя – far. Скалярные и структурные данные, помещающиеся в байт, возвращаются в AL, помещающиеся в слово – в AX, помещающиеся в двойное слово – в паре DX: AX. Табл. 4 поясняет соответствие типов возвращаемых данных языка Pascal и регистров процессора. Таблица 4
Многомерные массивы располагаются в памяти таким образом, что быстрее изменяется последний индекс. При передаче по значению массива, записи или строки компилятор формирует код, который обеспечивает передачу через стек far-адреса, выделение необходимой памяти в подпрограмме и копирование туда параметра. Трансляция и компоновка Для подключения внешней ассемблерной подпрограммы к программе на Pascal следует: оттранслировать ассемблерную программу и получить ОМ; в программе на Pascal описать внешнюю подпрограмму в программу на Pascal с помощью команды {$L имяОМ } включить ОМ. 2.5. Соглашение о связях языка C (сводка) Преобразование имен Значащая длина идентификатора может быть от 8 до 250 символов, умолчание – 32. Для изменения служит команда Options+Compiler+Source. Прописные и строчные буквы различаются. В начало каждого имени включается символ подчеркивания, отменить это можно с помощью команды Options+Compiler+Advanced code generation. Передача и возврат управления Тип подпрограмм (near или far) и, следовательно, команд call и ret зависит от используемой модели памяти. Установка модели памяти осуществляется командой Options+Compiler+Code generation. Подробнее о моделях памяти см. лабораторную работу «Использование подпрограмм» настоящего сборника или документацию по СП. Передача и возврат данных Параметры передаются в стеке. Помещаются они в стек в порядке, обратном порядку записи в тексте программы, т.е. первый в тексте будет на самом верху стека. Скалярные типы данных передаются по значению, массивы – по ссылке. Размер указателя (near или far) зависит от используемой модели памяти. Скалярные и структурные данные, помещающиеся в байт, возвращаются в AL, помещающиеся в слово – в AX, помещающиеся в двойное слово – в паре DX: AX. Табл. 5 поясняет соответствие типов возвращаемых данных языка C и регистров процессора. Таблица 5
Многомерные массивы располагаются в памяти таким образом, что быстрее изменяется последний индекс. При определении размеров структур и доступа к ним необходимо учитывать возможность выравнивания полей структур на границу слова (команда Options+Compiler+Advanced code generation). Преобразование данных При вызове подпрограммы скалярные данные типа float всегда преобразовываются в данные типа double. Поля типа float в структуре преобразованию не подвергаются. Трансляция и компоновка Модели памяти взаимодействующих подпрограмм должны быть согласованы. Этого можно достигнуть, либо установив одинаковые модели для C-компилятора (команда Options+Compiler+ Code generation) и ассемблера (директива model), либо указав явно модификаторы подпрограмм и параметров-указателей (атрибуты near или far). Компоновка может быть выполнена в интегрированной среде Borland C++. В этом случае следует использовать файл проекта, в который включить ОМ или ИМ ассемблерной ПП. В первом случае потребуется только настройка компоновщика, во втором – и ассемблера. При настройке компоновщика с помощью команды Options+Linker+Settings следует обязательно включить режим Case-sensitive link (различение прописных и строчных букв). При настройке ассемблера с помощью команды Options+Transfer следует в список Program Titles внести ассемблер (он там наверняка уже будет) и правильно задать для него путь доступа (Program Path) и командную строку (Command Line), которая может выглядеть так – /MX /ZI $TASM. Здесь ключи задают, соответственно, для глобальных имен различать строчные и прописные буквы и включать полную отладочную информацию. Параметр $TASM обязателен. Допустимо использование для компоновки непосредственно компоновщика TLINK, в этом случае в командной строке обязательно следует задать ключ различения строчных и прописных букв в именах – /c. ПРИМЕР ВЫПОЛНЕНИЯ РАБОТЫ В разделе приведен пример ассемблерной подпрограммы, выполняющей подсчет количества символов и количества строк (в смысле последовательность символов, завершающаяся \n) в строке (массиве символов), завершающейся нулевым байтом. Пример представлен в двух вариантах: с интерфейсом Pascal и C. Интерфейс Pascal Файл: COUNT.PAS
program Count; {$L count.obj} const StringToCount = 'Строка 1'+#10+'Строка 2'+#10+'Строка 3'; var LCount: integer; CCount: integer;
function LineCount( StringToCount: string; var CharacterCountPtr: integer): integer; external;
Begin LCount: = LineCount(StringToCount, CCount); writeln('Стpок: ', LCount); writeln('Символов: ', CCount); End.
Файл: COUNT.ASM
; Действие: ; подсчет количества символов и количества строк (в смысле - ; последовательность символов, завершающаяся \n) ; в строке (массиве символов), завершающейся нулевым байтом ; ; Интерфейс: ; Borland Pascal, модель - small ; function LineCount( ; TestString: string; ; var CharacterCountPtr: integer): integer; external; ; ; Параметры и возвращаемые значения: ; StringToCount - указатель на строку, в которой выполняется подсчет ; CharacterCountPtr - указатель на переменную - количество символов ; возвращает - количество строк ; NEWLINE equ 0Ah; LF - символ новой строки
dosseg model SMALL
codeseg public LineCount LineCount proc push BP; +пролог mov BP, SP push SI push DS; -пролог
xor CX, CX mov DS, [BP + 10] mov SI, [BP+8]; DS: SI - указатель на длину входной строки mov CL, [SI]; счетчик символов inc SI; указатель на входную строку xor DX, DX; счетчик строк xor BX, BX; счетчик символов LineCountLoop: lodsb; очередной символ входной строки в AL and AL, AL; а не нулевой ли это символ? jz EndLineCount; да, конец входной строки inc BX; нет, увеличиваем счетчик символов cmp AL, NEWLINE; а не символ ли это новой строки? jnz EndLoop; нет, продолжаем просмотр строки inc DX; да, увеличиваем счетчик строк EndLoop: loop LineCountLoop EndLineCount: cmp byte ptr [SI-2], NEWLINE; есть ли в хвосте символ LF je NoLastLine; есть, не будем увеличивать счетчик строк inc DX; нет, будем увеличивать счетчик строк NoLastLine: mov CX, BX; CX = BX сохраняем BX в CX mov DS, [BP+6] mov BX, [BP+4]; DS: BX - указатель на счетчик символов mov [BX], CX mov AX, DX; возвращаемое значение - счетчик строк
pop DS; +эпилог pop SI pop BP ret 8; -эпилог LineCount ENDP end Интерфейс C Файл: COUNT.CPP
/* Файл: COUNT.CPP Действие: Тестирование ассемблерной функции LineCount (файл: COUNT.ASM) Модель: small */
#include < stdio.h>
char * TestString=" Строка 1\nСтрока 2\nСтрока 3\n"; extern unsigned int LineCount( char * StringToCount, unsigned int * CharacterCountPtr );
void main() { unsigned int LCount; unsigned int CCount;
LCount = LineCount(TestString, & CCount); printf(" Строк: %d\nСиволов: %d\n", LCount, CCount); }
Файл: COUNT.ASM
; Файл: ; COUNT.ASM ; Действие: ; подсчет количества символов и количества строк (в смысле - ; последовательность символов, завершающаяся \n) ; в строке (массиве символов), завершающейся нулевым байтом ; Интерфейс: ; Borland C++ v.3.1, модель - small ; extern unsigned int LineCount( ; char * StringToCount, ; unsigned int * CharacterCountPtr); ; Параметры и возвращаемые значения: ; StringToCount - указатель на строку, в которой выполняется подсчет ; CharacterCountPtr - указатель на переменную - количество символов ; возвращает - количество строк ; NEWLINE equ 0Ah; LF - символ новой строки dosseg model SMALL codeseg public _LineCount _LineCount proc push BP; +пролог mov BP, SP push SI; -пролог mov SI, [BP+4]; DS: SI - указатель на входную строку sub CX, CX; счетчик символов mov DX, CX; счетчик строк LineCountLoop: lodsb; очередной символ входной строки в AL and AL, AL; а не нулевой ли это символ? jz EndLineCount; да, конец входной строки inc CX; нет, увеличиваем счетчик символов cmp AL, NEWLINE; а не символ ли это новой строки? jnz LineCountLoop; нет, продолжаем просмотр строки inc DX; да, увеличиваем счетчик строк jmp LineCountLoop EndLineCount: cmp byte ptr [SI-2], NEWLINE; есть ли в хвосте символ LF je NoLastLine; есть, не будем увеличивать счетчик строк inc DX; нет, будем увеличивать счетчик строк NoLastLine: mov BX, [BP+6]; BX - указатель на счетчик символов mov [BX], CX; mov AX, DX; возвращаемое значение - счетчик строк pop SI; +эпилог pop BP ret; -эпилог _LineCount ENDP END
ВАРИАНТЫ ЗАДАНИЙ Во всех заданиях следует разработать некоторую подпрограмму на ассемблере с интерфейсом Pascal или C и вызывающую программу, на соответствующем языке. Вызывающая программа должна демонстрировать работоспособность ассемблерной подпрограммы. Если в задании язык не указан, то можно выбрать любой. 1. Разработать подпрограмму на ассемблере, которая выполняет пересылку указанного числа байт. Адреса источника и приемника – параметры. Подпрограмма должна возвращать количество пересланных байт. 2. Разработать подпрограмму на ассемблере, которая выполняет обмен указанного числа байтов. Адреса областей памяти – операндов должны быть переданы как параметры. Подпрограмма должна возвращать количество перемещенных байтов. 3. Разработать подпрограмму на ассемблере, которая определяет и возвращает номер первого установленного бита в массиве байтов. Адреса массива и его размер должны быть переданы как параметры. 4. Разработать подпрограмму на ассемблере для определения длины строки. Адрес строки – параметр. Подпрограмма должна возвращать длину строки. 5. Разработать подпрограмму на ассемблере для сравнения строк (аналог функции strcmp языка C). Адрес строки – параметр. Подпрограмма должна возвращать длину строки. Язык – C. 6. Разработать подпрограмму на ассемблере для сравнения строк (аналог функции strcnmp языка C). Адрес строки – параметр. Подпрограмма должна возвращать длину строки. Язык – C. 7. Разработать подпрограмму, которая определяет, содержится ли одна заданная строка в другой заданной строке, и если да, то, начиная с какой позиции. Разработать программу, которая вводит с клавиатуры две строки и сообщает, содержится ли одна из них в другой и сколько раз. Язык – C. 8. Разработать подпрограмму, которая подсчитывает, сколько раз заданный символ встречается в строке. Разработать программу, которая вводит с клавиатуры строку, вводит число N и выдает список символов, которые встречаются в строке не менее чем N раз. Язык – C. 9. Разработать две подпрограммы, одна из которых соединяет две строки в одну, а другая обрезает строку до заданной длины (или дополняет пробелами, если длина строки меньше заданной). Разработать программу, которая вводит с клавиатуры число N, затем вводит несколько строк (конец ввода – пустая строка) и формирует новую строку, состоящую из первых N символов каждой введенной строки. 10. Разработать подпрограмму, которая разбивает заданную строку на две части: первое слово строки (до первого пробела) и остаток строки (пробелы после первого слова отбрасываются). 11. Разработать подпрограмму, которая определяет, содержится ли одна заданная строка в другой заданной строке, и если да, то, начиная с какой позиции. Язык – Pascal. КОНТРОЛЬНЫЕ ВОПРОСЫ 1. Что означает понятие «соглашение о связях»? 2. Каким образом осуществляется передача параметров по ссылке и по значению? 3. Что такое «выравнивание полей структур на границу...»? 4. Каким образом осуществляется возврат значений в функциях? БИБЛИОГРАФИя 1. Сван Т. Освоение Turbo Assembler. К: Диалектика, 1996. 544 с. 2. Скэнлон Л. Персональные ЭВМ IBM PC и AT. М.: Радио и связь, 1989. 336с. 3. Брэдли Д. Программирование на языке ассемблера для персональной ЭВМ фирмы IBM. М.: Радио и связь, 1988. 448с. 4. Шнайдер А. Язык ассемблера для персонального компьютера фирмы IBM. М.: Мир, 1988. 406с. 5. Лю Ю-Чжен, Гибсон Г. Микропроцессоры семейства 8086/8088. Архитектура, программирование и проектирование микрокомпьютерных систем. М.: Радио и связь, 1987. 512с. 6. Нортон П. Персональный компьютер фирмы IBM и операционная система MS-DOS. М.: Радио и связь, 1991. 416с. 7. Mixed-Language Programming Guide. Document No. 410840031-500-R01-1287. Microsoft Corp., 1987.
Содержание Введение......................................................................................................................... 3 Лабораторная работа № 1. Разработка и отладка программ на языке ассемблера 4 Лабораторная работа № 2. Программирование линейных конструкций. 13 Лабораторная работа № 3. Циклические и разветвляющиеся программы 16 Лабораторная работа № 4. Логические команды............................................ 19 Лабораторная работа № 5. Символьная обработка....................................... 22 Лабораторная работа № 6. Десятичная арифметика..................................... 28 Лабораторная работа № 7. Подпрограммы...................................................... 34 Лабораторная работа № 8. Использование подпрограмм на языке ассемблера в программах на языках C и PASCAL 47 Библиографя............................................................................................................... Заметки
_________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________ _________________________________________________________
Методическая разработка к лабораторным работам «Программирование на языке ассемблера ПЭВМ IBM PC»
Ответственный за выпуск Калачев Д.П. Редактор Кочергина Т.Ф. Корректор Проценко И.А.
ЛР № 020565 Подписано к печати 5.12.97 Формат 60x84 1/16 Бумага офсетная. Печать офсетная. Усл. п. л. – 3, 6. Уч.-изд. л. – 3, 0 Заказ № Тираж 300 «С» Издательство Таганрогского радиотехнического университета ГСП 17А, Таганрог, 28, Некрасовский, 44 Типография Таганрогского радиотехнического университета ГСП 17А, Таганрог, 28, Энгельса, 1 Популярное:
|
Последнее изменение этой страницы: 2016-03-25; Просмотров: 1098; Нарушение авторского права страницы