Государственное Образовательное Учреждение высшего профессионального образования Московский Авиационный Институт Государственный Технический Университет "маи" кафедра 304. конспект

Вид материалаКонспект

Содержание


Расположение процедур в сегменте
Внешние процедуры
Передача параметров через регистры МП
Передача параметров по ссылке
Передача параметров через стек.
Проблема сохранения регистров при обращении к процедуре
Подобный материал:
1   ...   7   8   9   10   11   12   13   14   15

Расположение процедур в сегменте




  1. Внутренние процедуры находятся в одном сегменте с вызывающей программой.

При этом возможны 3 варианта расположения:

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

Например:

Text SEGMENT ‘code’

ASSUME CS: text, DS: data, SS: stack

A1 PROC



RET

A1 ENDP

Main PROC

MOV AX, data

MOV DS, AX



CALL A1



MOV AX, C400h

INT 21h

Main ENDP

Text ENDS

Data SEGMENT



Data ENDS

Stack SEGMENT ‘stack’



Stack ENDS

END Main


б) все процедуры – ниже точки вызова.

в) процедуры – внутри основной процедуры, возможно даже, что процедура внутри другой процедуры (хотя никакой выгоды это не даёт)


Например,



Main PROC



CALL A1



MOV AX, C400h

INT 21h

A1 PROC



RET

A1 ENDP

Main ENDP

Text ENDS


2) Внешние процедурырасполагаются в других сегментах или в других файлах.

Например, текст основной программы находится в файле P.asm

Text SEGMENT public ‘code’

; объединение модулей последовательно

; в общий сегмент

ASSUME CS: text, DS: data, SS: stack

EXTRN stop: proc; объявление внешнего имени

Main PROC



CALL Stop



Main ENDP

Text ENDS

Data SEGMENT



Data ENDS

Stack SEGMENT ‘stack’



Stack ENDS

END Main

Исходный текст процедуры находится в файле P1.asm

Text SEGMENT public ‘code’

ASSUME CS: text

PUBLIC stop; объявление имени доступным извне

Stop proc



ret

stop ENDP

text ENDS

END ; конец файла без точки входа


Объединение этих файлов происходит на шаге компоновки, т.е. требуется раздельная трансляция. Например, для MASM

MASM/ZI PR

MASM/ZI P1

где ZI – опция, позволяющая поместить в объектный файл полную информацию о номерах строк и символах исходного модуля (ИМ).

После образования PR.obj и P1.obj их нужно скомпоновать в единый загрузочный файл

LINK/C0 PR P1, COMPOZ

где С0 – опция, передающая в загрузочный файл символьную информацию, позволяющую отладчику CV выводить на экран полный текст ИМ, включая метки и комментарии.

Модуль COMPOZ.exe готов к исполнению.

Можно подключить процедуру из библиотеки. Для этого перед сегментами ИМ помещается директива

INCLUDE {имя файла библиотеки}

Например, для подключения файла IO.asm следует записать

INCLUDE IO.asm

S SEGMENT ‘stack’



S ENDS

D SEGMENT ‘data’



D ENDS

C SEGMENT ‘code’

ASSUME CS:C, SS:S, DS:D

Begin: …



C ENDS

END Begin

Передача параметров между процедурами (организуется по желанию программиста)




  1. Передача параметров через регистры МП

Передавать значения фактических параметров можно через регистры МП по желанию программиста. Например,

; процедура вычисления AX := max {AX, BX}

max proc far

CMP AX, BX

JGE Max1

MOV AX, BX

Max1: RET

max endp



; в основной процедуре



MOV AX, A ; подготовка параметров

MOV BX, B ; к вызову процедуры

CALL max

MOV C, AX ; сохранение результата


  1. Передача параметров по ссылке означает передачу адреса (имени) ячейки памяти, соответствующей фактическому параметру (передача именованного значения из ассемблера в Pascal). Для этого можно использовать имя ячейки памяти или загрузить адрес перед вызовом процедуры в регистр (BX, BP, SI или DI, т.к. в процедуре можно использовать эти регистры для адресации ).

Например, командой

LEA BX, B

CALL……
  1. Передача параметров через стек.

Передача параметров через регистры ограничена их небольшим количеством. Если параметров много (больше 5-ти), их передают через стек следующим образом:

- Основная программа записывает в стек фактические параметры (значения или адреса);

- В процедуре используются параметры, записанные в стек.

Например:

; вызов p(a1,…, ak)

PUSH a1



PUSH ak

CALL p



В процедуре можно использовать дополнительный указатель стека BP, но в начале процедуры следует сохранить значение BP, которое использовалось в вызывающей программе, т.е.

; начало процедуры Р

P proc

PUSH BP ; сохранение BP

MOV BP, SP ; настройка BP на вершину стека



Затем можно использовать базовую адресацию. Например, для близкого вызова

[BP + 2] – адрес возврата, занесенный в стек автоматически,

[BP + 4] – адрес последнего параметра ak.

До возврата из процедуры следует восстановить BP командой

POP BP

затем очистить стек от передаваемых параметров, чтобы он не перегружался при многократном вызове процедур, т.е. установить в SP значение, на 2*k больше, чем было после вызова процедуры.

Есть 2 возможности корректного возврата из процедуры.

а) корректировать SP в вызывающей программе

; конец процедуры

; в вызывающей программе

POP BP

CALL p

RET

ADD SP, 2*k ; коррекция SP

P ENDP



б) использовать команду возврата с восстановлением стека, имеющую вид для близкого вызова

RET {cnt}

где {cnt} – счетчик (константное выражение ), размером слово.

Команда выполняет следующие действия:

IP := Stack SP := SP + {cnt}

Тогда конец процедуры имеет вид:

POP BP

RET 2*k

p ENDP

Для дальнего вызова процедуры команда возврата имеет вид

RET {cnt}

и выполняет следующие действия:

IP := Stack CS := Stack SP := SP + {cnt}

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

Чтобы процедура не портила значения регистров, которые использовались в вызывающей программе, требуется в тексте процедуры перед использованием какого-либо регистра сохранить его «старое» значение в стеке, а в конце процедуры все сохраненные значения восстановить.

Например, если в процедуре будет использоваться регистр CH, то его следует сохранить в стеке, но стек запоминает только со слова, поэтому в процедуре будет фрагмент:

PUSH CX ; сохранение «старого» CX

MOV CX, 0 ; использование CX в процедуре



; перед выходом из процедуры

POP CX ; восстановление «старого» CX

Таким образом, получится обобщенная схема близкой (NEAR) процедуры с параметрами, передаваемыми через регистры и через стек


{имя проц} proc







PUSH BP для обслуживания

mov BP, SP стека







PUSH сохранение регистров,

используемых в процедуре







тело проц.







РОР ... восстановление регистров







РОР ВР восстановление BP






RET {cnt}







{имя проц} ENDP