Государственное Образовательное Учреждение высшего профессионального образования Московский Авиационный Институт Государственный Технический Университет "маи" кафедра 304. конспект
Вид материала | Конспект |
- Инновационной образовательной программы, 1090.47kb.
- Самостоятельная работа 2 часа в неделю всего часов, 28.69kb.
- Самостоятельная работа 2 часа в неделю всего часов, 45.89kb.
- Самостоятельная работа 2 часа в неделю всего часов, 73.46kb.
- Самостоятельная работа 2 часа в неделю всего часов, 46.6kb.
- Самостоятельная работа 2 часа в неделю всего часов, 41.37kb.
- Самостоятельная работа 2 часа в неделю всего часов, 41.08kb.
- Самостоятельная работа 2 часа в неделю всего часов, 64.33kb.
- Самостоятельная работа 2 часа в неделю всего часов, 29.72kb.
- Самостоятельная работа 2 часа в неделю всего часов, 33.42kb.
Расположение процедур в сегменте
- Внутренние процедуры находятся в одном сегменте с вызывающей программой.
При этом возможны 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
Передача параметров между процедурами (организуется по желанию программиста)
- Передача параметров через регистры МП
Передавать значения фактических параметров можно через регистры МП по желанию программиста. Например,
; процедура вычисления 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 ; сохранение результата
…
- Передача параметров по ссылке означает передачу адреса (имени) ячейки памяти, соответствующей фактическому параметру (передача именованного значения из ассемблера в Pascal). Для этого можно использовать имя ячейки памяти или загрузить адрес перед вызовом процедуры в регистр (BX, BP, SI или DI, т.к. в процедуре можно использовать эти регистры для адресации ).
Например, командой
LEA BX, B
CALL……
- Передача параметров через стек.
Передача параметров через регистры ограничена их небольшим количеством. Если параметров много (больше 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}
При таком возврате из процедуры в вызывающей программе дополнительные действия не требуются.
- Проблема сохранения регистров при обращении к процедуре
Чтобы процедура не портила значения регистров, которые использовались в вызывающей программе, требуется в тексте процедуры перед использованием какого-либо регистра сохранить его «старое» значение в стеке, а в конце процедуры все сохраненные значения восстановить.
Например, если в процедуре будет использоваться регистр CH, то его следует сохранить в стеке, но стек запоминает только со слова, поэтому в процедуре будет фрагмент:
PUSH CX ; сохранение «старого» CX
MOV CX, 0 ; использование CX в процедуре
…
; перед выходом из процедуры
POP CX ; восстановление «старого» CX
Таким образом, получится обобщенная схема близкой (NEAR) процедуры с параметрами, передаваемыми через регистры и через стек
{имя проц} proc
PUSH BP для обслуживания
mov BP, SP стека
PUSH сохранение регистров,
используемых в процедуре
тело проц.
РОР ... восстановление регистров
РОР ВР восстановление BP
RET {cnt}
{имя проц} ENDP