- Lektsia - бесплатные рефераты, доклады, курсовые работы, контрольные и дипломы для студентов - https://lektsia.info -

Передача и возврат управления и данных



При рассмотрении передачи и возврата управления и данных необходимо учитывать следующие моменты:

· тип команд вызова и возврата;

· способы передачи параметров – по ссылке, по значению, для передачи по ссылке – тип адресации, передача сложных типов данных – массивов и структур;

· доступ к данным в подпрограмме;

· при передаче параметров через стек, в каком порядке помещать параметры в стек и какая из программ ответственна за очистку стека;

· как располагаются многомерные массивы в памяти;

· выполняется ли выравнивание полей структур на границу слова, двойного слова и т.п.;

· СП могут осуществлять обязательное преобразование данных некоторых типов при использовании их в качестве фактиче­ских параметров;

· как представляются сложные типы данных: структуры, за­писи и объекты (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

Тип функции Регистр(ы)
Boolean, Char, ShortInt, Byte AL
Integer, Word AX
LongInt DX – старшее слово, AX – младшее
Pointer DX – сегмент, AX – смещение
String · в вызывающей подпрограмме резервируется память под воз­вращаемую строку; · в стек на самый низ (т.е. первым параметром) помещается адрес этой памяти; · вызываемая подпрограмма помещает по указанному адресу результат; · при возврате стек чистится от всех параметров, кроме этого адреса, удалением этого адреса должна заниматься вызы­вающая подпрограмма.

Многомерные массивы располагаются в памяти таким образом, что быстрее изменяется последний индекс.

При передаче по значению массива, записи или строки компи­лятор формирует код, который обеспечивает передачу через стек far-адреса, выделение необходимой памяти в подпрограмме и ко­пирование туда параметра.

Трансляция и компоновка

Для подключения внешней ассемблерной подпрограммы к про­грамме на Pascal следует:

оттранслировать ассемблерную программу и получить ОМ;

в программе на Pascal описать внешнюю подпрограмму
procedure имя( параметры ); external;

в программу на 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

Тип функции Регистр(ы)
char AL
short, int AX
long DX – старшее слово, AX – младшее
near * AX – смещение
far * DX – сегмент, AX – смещение

Многомерные массивы располагаются в памяти таким образом, что быстрее изменяется последний индекс.

При определении размеров структур и доступа к ним необхо­димо учитывать возможность выравнивания полей структур на границу слова (команда 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