Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Расширенные директивы описания процедур



Возможен следующий синтаксис описания процедуры:


ИМЯ proc [[МОДИФИКАТОР_ЯЗЫКА] ЯЗЫК] [РАССТОЯНИЕ]
[arg СПИСОК_АРГУМЕНТОВ]
[local СПИСОК_АРГУМЕНТОВ]
...
[ИМЯ] endp

Приведем синтаксис определения передаваемых процедуре ар­гументов:

arg АРГУМЕНТ [, АРГУМЕНТ ]... [ =ИМЯ ]

При определении локальных переменных процедуры использу­ется следующий синтаксис:

local АРГУМЕНТ [, АРГУМЕНТ ]... [ =ИМЯ ]

Отдельные аргументы имеют следующий синтаксис:

ИМЯ_АРГУМЕНТА [[ СЧЕТЧИК_1 ]] [: ТИП [: СЧЕТЧИК_2 ]]

Здесь ТИП – это тип данных аргумента – byte, word, dword и т.п.

СЧЕТЧИК_2 задает, сколько элементов данного типа определяет аргумент.

Например, в определении аргумента:

arg TMP: dword: 4

определяется аргумент с именем TMP, состоящий из 4 двойных слов. По умолчанию СЧЕТЧИК_2 имеет значение 1 (кроме аргумен­тов типа byte. Так как вы не можете занести в стек байтовое зна­чение, для аргументов типа byte значение счетчика по умолчанию равно 2, что обеспечивает для них в стеке размер в слово.

Например:

arg REALBYTE: byte: 1

СЧЕТЧИК_1 представляет собой число элементов массива. Если поле СЧЕТЧИК_1 не задано, то по умолчанию оно равно 1.

Если список аргументов завершается символом равенства (=) и идентификатором, то ассемблер будет приравнивать этот иденти­фикатор к общему размеру блока аргументов (в байтах). Если вы не используете автоматическое использование соглашений языков высокого уровня в ассемблере, то можете использовать данное значение в конце процедуры в качестве аргумента инст­рукции ret.

Аргументы и переменные определяются в процедуре как опе­ранды в памяти относительно BP. Передаваемые аргументы, опре­деленные с помощью директивы arg, имеют положительное сме­щение относительно BP. Локальные переменные, определенные с помощью директивы local, имеют отрицательное смещение от BP.

Например:

FUNC1 proc NEAR
arg A: word, B: word: 4, C: byte =ArgSize
local X: dword, Y: word: 2 =LocSize
...

Здесь A определяется, как [BP+4], B – [BP+6], C – [BP+14], а ArgSize – 20. X – [BP-2], Y – [BP-6], а LocSize – 8.

Область действия имен

Если для аргументов и локальных переменных, а также меток операторов в подпрограмме, не заданы имена с предшествующим префиксом локального идентификатора, все аргументы, заданные в заголовке процедуры, определены ли они с помощью директивы arg или local и метки имеют глобальную область действия.

Идентификаторы с локальной областью действия разрешает ди­ректива locals (не путать с директивой local).

Например:

locals __
TST1 proc
arg __A: word, __B: word, __C: byte
local __X: word, __Y: dword
...

В этом примере директива locals __ определяет двойной символ подчеркивания как префикс локальных имен. Это означает, что все имена, начинающиеся с данной пары символов, будут счи­таться локальными в пределах подпрограммы.

Итоги

Соединив все, что было сказано в предыдущих параграфах, можно предложить следующий шаблон подпрограммы:


locals __

...
Func proc near
arg __p1: word, __p2: word, ... = __ArgSize
local __v1: byte, __v2: word, ... = __LocSize
; Действие: ...
; Входные параметры: ...
; Выходные параметры: ...
; Возвращает: ...
; Обращение: ...
; Замечания:
; регистры не модифицирует
; стек чистит от параметров

push BP; + BP - указатель
mov BP, SP; - кадра стека
sub SP, __LocSize; выделение памяти для лок. переменных
push SI, DI; сохранение регистров
...
mov SI, __p1; доступ к параметру
...
mov __v2, SI; доступ к локальной переменной
...
pop DI, SI; восстановление регистров
mov SP, BP; чистка стека от лок. переменных
pop BP; восстановление BP
ret __ArgSize; возврат и чистка стека от параметров
Func endp

ПРИМЕР ВЫПОЛНЕНИЯ РАБОТЫ

Разработать подпрограмму, которая удаляет, начиная с задан­ной позиции строки, указанное число символов. Разработать про­грамму, которая вводит с клавиатуры строку, вводит позицию и длину удаляемой части строки и удаляет эту часть.

Текст программы:


locals __

model small

stack 100h

dataseg

MESS1 db 0dh, 0ah, 0dh, 0ah, " Введите строку: ", 0dh, 0ah, " $"

MESS2 db 0dh, 0ah, " Введите позицию: $"

MESS3 db 0dh, 0ah, " Введите число удаляемых символов: $"

MESS4 db 0dh, 0ah, 0dh, 0ah, " Строка после удаления: ", 0dh, 0ah, " $"

S_BUFLEN db 80; Макс. длина строки

S_FACTLEN db? ; Длина фактически введенной строки

S_INPBUF db 80 dup (? ); Введенная строка

N_BUFLEN db 3; Макс. длина числа при вводе

N_FACTLEN db? ; Фактическая длина

N_INPBUF db 3 dup (? ); Строка представления числа

POSDEL dw? ; Позиция, начиная с которой удаляем

LENDEL dw? ; Сколько символов удалить

 

codeseg

startupcode

; Ввод строки

MLOOP: lea DX, MESS1

mov AH, 09h

int 21h; Приглашение к вводу строки

lea DX, S_BUFLEN

mov AH, 0Ah

int 21h; Ввод строки

mov BL, S_FACTLEN

cmp BL, 0; Строка пустая?

jne LLL0; Нет - продолжать

jmp QUIT; Закончить работу

LLL0: mov BH, 0; Дополнить длину до слова

add BX, 2; и получить адрес позиции

add BX, DX; сразу после конца строки

mov byte ptr[BX], 0; Записать признак конца строки

; Ввод позиции удаления

LLL1: lea DX, MESS2; Приглашение

mov AH, 09h; к вводу

 

int 21h; позиции удаления

lea DX, N_BUFLEN

mov AH, 0Ah

int 21h; Ввод строки числа

lea BX, N_INPBUF; Адрес строки представления числа

mov CL, N_FACTLEN; Длина этой строки

call VAL; Перевод в целое число

jc LLL1; Ошибка? - повторить ввод

cmp AL, 0; Ноль?

je LLL1; Повторить ввод

cmp AL, S_FACTLEN; Превышает длину строки?

jg LLL1; Повторить ввод

mov POSDEL, AX; Запомнить позицию удаления

; Ввод длины удаляемой части

LLL2: lea DX, MESS3; Приглашение

mov AH, 09h; к вводу

int 21h; числа удаляемых

lea DX, N_BUFLEN

mov AH, 0Ah

int 21h; Ввод строки числа удаляемых

lea BX, N_INPBUF; Адрес строки представления числа

mov CL, N_FACTLEN; Длина этой строки

call VAL; Перевод в целое число

jc LLL2; Ошибка? - повторить ввод

mov LENDEL, AX; Запомнить число удаляемых

add AX, POSDEL; Подсчитать, не выходит ли

dec AX; удаляемая часть

cmp AL, S_FACTLEN; за конец строки?

jg LLL2; Если да - повторить ввод

; Занесение параметров в стек и вызов п/п удаления

lea AX, S_INPBUF

push AX; 1-й параметр - адрес строки

push POSDEL; 2-й параметр - позиция удаления

push LENDEL; 3-й параметр - число удаляемых

call DELSUBS; Вызов подпрограммы

; Вывод результата

lea DX, MESS4

mov AH, 09h

int 21h; Заголовок вывода

lea BX, S_INPBUF

mov CX, 80

LLL3: cmp byte ptr [BX], 0; Цикл поиска конца строки и выход

je LLL4; - когда конец строки найден

inc BX; Сдвиг по строке

loop LLL3

LLL4: mov byte ptr [BX], '$'; Заменить признак конца строки

lea DX, S_INPBUF

mov AH, 09h

int 21h; Вывод результата

 

jmp MLOOP; На повторение работы

 

QUIT: exitcode 0

 

; Действие:

; функция вычисляет целое число по его строковому представлению.

; Результат не может быть больше 255.

; Для неверно введенных чисел устанавливает флаг переноса

; Параметры:

; BX - адрес строки - предстваления числа

; CX - длина этой строки

; Возвращает:

; CF - установлен, если в строке не цифры, AX - не определен

; сброшен, строка нормальная, AX - число

; AX - преобразованное число, если сброшен

VAL proc near

push DX; Сохранить все изменяемые регистры,

; кроме AX, в котором результат

mov CH, 0; Расширяем длину до слова

mov AX, 0; Начальное значение результата

mov DL, 10; Основание системы счисления

__1: imul DL; Умножить на основание

jc __2; Переполнение байта?

mov DH, [BX]; Очередная цифра

sub DH, '0'; Получить значение цифры

jl __2; Это была не цифра!

cmp DH, 9

jg __2; Это опять же была не цифра!

add AL, DH; + значение цифры к результату

jc __2; Переполнение байта?

inc BX; Сдвиг по строке

loop __1; Цикл по строке

jmp __3; Нормальное число

__2: stc; Было переполн. - устанавливаем CF

__3: pop DX; Восстановить все, что сохраняли

ret

VAL endp

 

; Подпрограмма удаления подстроки

DELSUBS proc near

arg __Ldel: word, __Pdel: word, __StrAdr: word = __ArgSize

; Params struc; Структура стека после сохранения BP

; SaveBP dw? ; Сохраненное значение BP

; SaveIP dw? ; Адрес возврата

; LDel dw? ; 3-й параметр - число удаляемых

; PDel dw? ; 2-й параметр - позиция удаления

; StrAdr dw? ; 1-й параметр - адрес строки

; Params ends

push BP; Сохранить BP

mov BP, SP; Теперь BP адресует стек ПОСЛЕ сохр.BP,

; но ДО сохранения остальных регистров

push ES AX SI DI CX; Сохранить все изменяемые регистры

 

mov AX, DS; ES будет указывать на

mov ES, AX; сегмент данных

mov DI, __StrAdr; Вычислить в DI адрес,

add DI, __PDel; куда надо

dec DI; пересылать символы

mov SI, DI; А в SI - адрес,

add SI, __LDel; откуда их пересылать

cld; Продвигаться от начала строки к концу

__REPEAT:

movsb

cmp byte ptr [SI-1], 0

jne __REPEAT

pop CX DI SI AX ES; Восстановить все, что сохраняли

pop BP

ret __ArgSize; Убрать из стека 3 параметра-слова

DELSUBS endp

 

end

ВАРИАНТЫ ЗАДАНИЙ

В приведенных ниже вариантах заданий используется стан­дартное представление строк ASCII с кодом 0 в качестве ограни­чителя конца строки. Способ передачи параметров выбирается программистом произвольно. Рекомендуется зациклить программу по вводу, а признаком окончания работы считать ввод пустой строки.

1. Разработать подпрограмму, которая определяет, содержится ли одна заданная строка в другой заданной строке, и если да, то, начиная с какой позиции. Разработать программу, которая вводит с клавиатуры две строки и сообщает, содержится ли одна из них в другой и сколько раз.

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

3. Разработать две подпрограммы, одна из которых соединяет две строки в одну, а другая обрезает строку до заданной длины (или дополняет пробелами, если длина строки меньше задан­ной). Разработать программу, которая вводит с клавиатуры число N, затем вводит несколько строк (конец ввода – пустая строка) и формирует новую строку, состоящую из первых N символов каждой введенной строки.

4. Разработать две подпрограммы, одна из которых сравнивает две строки по лексикографическому порядку, а другая обмени­вает значения двух строк. Разработать программу, которая вводит с клавиатуры несколько строк (конец ввода – пустая строка) и сортирует их в лексикографическом порядке.

5. Разработать подпрограмму, которая разбивает заданную строку на две части: первое слово строки (до первого пробела) и оста­ток строки (пробелы после первого слова отбрасываются). Раз­работать программу, которая вводит с клавиатуры строку и выводит каждое слово с новой строки.

6. Разработать подпрограмму, которая переставляет символы за­данной строки в обратном порядке. Разработать программу, ко­торая вводит с клавиатуры строку и переставляет в обратном порядке символы в каждом слове (слова разделяются пробе­лами).

7. Разработать подпрограмму, которая вставляет подстроку в строку, начиная с заданной позиции. Разработать программу, которая вводит с клавиатуры исходную строку, вводит под­строку и позицию вставки, вставляет подстроку в строку.

8. Разработать две подпрограммы, одна из которых преобразует любую заданную букву в заглавную (в том числе для русских букв), а другая - преобразует букву в строчную. Разработать программу, которая вводит с клавиатуры строку и заменяет первые буквы всех слов на заглавные, а остальные буквы - на строчные.

КОНТРОЛЬНЫЕ ВОПРОСЫ

1. Что такое «ближние» и «дальние» подпрограммы?

2. Как определяется, «ближний» или «дальний» вариант команды call использован в программе?

3. Какие еще способы передачи параметров можно предложить, кроме двух, описанных в данной работе?

4. Может ли массив быть параметром процедуры?

5. Нельзя ли адресовать параметры в стеке через регистр SP, не используя BP?

6. Что и как нужно изменить в программе из примера, если ис­пользуется версия ассемблера, не поддерживающая понятие структуры?

7. Изменить описание подпрограммы из примера с использова­нием упрощенных директив описания подпрограмм.

8. Что означает операнд команды ret?

9. Какой последовательностью команд можно было бы заменить команду ret 6?


Лабораторная работа

È Ñ Ï Î Ë Ü Ç Î Â À Í È Å Ï Î Ä Ï Ð Î Ã Ð À Ì Ì Í À ß Ç Û Ê Å À Ñ Ñ Å Ì Á Ë Å Ð À Â Ï Ð Î Ã Ð À Ì Ì À Õ Í À ß Ç Û Ê À Õ C È PASCAL

ЦЕЛЬ РАБОТЫ

Цель настоящей работы – выработка навыков подготовки раз­ноязыковых программ в операционной системе MS-DOS.

ОСНОВНЫЕ СВЕДЕНИЯ

Введение

Каждый язык программирования обладает своими достоинст­вами и недостатками. Поэтому при разработке больших проектов может возникнуть необходимость написания отдельных частей программы на различных языках программирования, например:

· вся программа на каком-либо языке высокого уровня (ЯВУ), а для доступа к нестандартной аппаратуре или нестандартного доступа к стандартной требуется написание подпрограмм на языке ассемблера;

· в программе на ЯВУ необходимо повысить эффективность вы­полнения какого-либо фрагмента и для этого переписать его на языке ассемблера;

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

Вся конкретная информация и примеры рассмотрены для сис­темы программирования (СП) Borland C++ Version 3.1 и Borland Pascal Version 6.0 фирмы Borland International, Inc. и ориентиро­ваны на программирования в DOS.

ТерминЫ и сокращения

Подпрограмма – фрагмент программы, оформленный таким образом, что к нему можно обращаться (вызывать) из других фрагментов программы и возвращаться в точку вызова. При вы­зове подпрограммы ей можно передавать параметры и она может возвращать значение.

Процедура – подпрограмма, не возвращающая значения (см. процедуры Паскаля).

Функция – подпрограмма, возвращающая значение (см. функ­ции Паскаля или Си).

Параметр – фрагмент данных, передаваемый подпрограмме, и возможно, изменяемый ею. Внешние (глобальные) данные пара­метрами не являются.

Формальный параметр – обозначение (идентификатор) пара­метра в подпрограмме.

Фактический параметр – выражение или идентификатор пе­ременной, подставляемый при обращении (вызове) подпрограммы.

Прототип подпрограммы – описание заголовка подпрограммы с описанием формальных параметров.

Основной язык – язык, на котором написана вызывающая про­грамма, язык подпрограммы – язык, на котором написана подпро­грамма.

Сокращения:

СП – система программирования

ЯП – язык программирования

ЯВУ – язык программирования высокого уровня

ИМ – исходный модуль

ОМ – объектный модуль

Соглашения о связях

Вообще говоря, для каждого транслятора с языка высокого уровня существует свое собственное соглашение о связях между подпрограммами. То есть соглашение о том, в какие машинные команды и конструкции языка ассемблера транслируются опера­торы языка высокого уровня, служащие для описания и вызова подпрограмм.

Понятие «соглашение о связях» включает следующие аспекты: преобразование имен подпрограмм и переменных, передача и воз­врат управления, передача и возврат данных, преобразование дан­ных при передаче и возврате, трансляция и компоновка подпро­грамм в единую программу.

Преобразование имен

Под термином «преобразование имен» понимаются правила формирования имен транслятором при создании объектного мо­дуля. Необходимо учитывать, по меньшей мере, следующие мо­менты:

· допустимое количество символов в имени в программе на ЯП и в ОМ;

· различаются ли прописные и строчные буквы в программе на ЯП и в ОМ;

· не добавляет ли что-нибудь транслятор от себя к именам в ОМ.

Длина внешнего имени (т.е. имени «видимого» компоновщи­ком) зависит от конкретной СП, как правило, это 32 символа.

В языке C в именах различаются прописные и строчные буквы, в языке Pascal, напротив, не различаются. Как правило, трансля­торы с этих языков поступают соответствующим образом при формировании имен в ОМ. В частности, Pascal-трансляторы преобразуют строчные буквы в прописные.

С-трансляторы, как правило, включают символ подчеркивания в начало каждого имени в ОМ.


Поделиться:



Популярное:

  1. Административно – процедурное производство. Сущность и виды.
  2. Административные процедуры как правовой институт в структуре административного процесса
  3. Аналитические процедуры и их применение в проведении аудиторских проверок. ФП(С)АД №20 «Аналитические процедуры»
  4. Б. Процедуры заключения договоров
  5. Билет 29. Принципы описания слова в исторических и этимологических словарях. Отражение динамики языка в «Словаре русского языка 18 века»
  6. ВИДЫ БИБЛИОГРАФИЧЕСКОГО ОПИСАНИЯ ДОКУМЕНТОВ
  7. Виды и порядок осуществления реорганизационных процедур и ликвидация предприятия
  8. Возбуждение процедуры банкротства. Досудебная санация.
  9. Глава 15 Судебно-бухгалтерская экспертиза материалов дела по несостоятельности в части отражения на счетах бухгалтерского учета процедур банкротства
  10. Глава 15. ПРИМИРИТЕЛЬНЫЕ ПРОЦЕДУРЫ. МИРОВОЕ СОГЛАШЕНИЕ
  11. Глава I Теоретические аспекты формирования навыка правописания словарных слов на уроках русского языка
  12. Документированная процедура № 1


Последнее изменение этой страницы: 2016-03-25; Просмотров: 1020; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.079 с.)
Главная | Случайная страница | Обратная связь