CALL CPYAR
; Пример для x86
; Объявление области данных
PUBLIC CNT, P1, P2, CPYAR
.DATA
CNT DW 0
P1 DW 0
P2 DW 0
; Процедура
.CODE
CPYAR PROC NEAR
; Сохранение регистров
PUSH CX
PUSH SI
PUSH DI
; Подготовка к rep movsb
PUSH DS
POP ES
CLD
MOV CX, CNT
MOV SI, P1
MOV DI, P2
; Копирование
REP MOVSB
; Восстановление регистров
POP DI
POP SI
POP CX
RET
CPYAR ENDP
Фаза вызова
EXTRN CNT:WORD, P1:WORD, P2:WORD
MOV AX, SIZE1
MOV CNT, AX
LEA AX, M1
MOV P1, AX
LEA AX, M2
MOV P2, AX
CALL CPYAR
Передача параметров через область памяти, приписываемую фазе вызова
Плюсы:
· более простая реализация рекурсивных процедур
· естественность в случае, когда передаваемые данные - константы
· простота реализации ПП в ПЗУ
Минус - необходимость создавать области в различных фазах.
Пример для PDP-11
; В фазе вызова используется передача
; указателя на область параметров
; через регистр адреса возврата
JSR R5, CPYFC
.WORD SIZE1
.WORD M1
.WORD M2
. . .
; CPYFC копирует W1 байт из области
; памяти с адресом W2 в область с
; адресом W3. W1, W2,W3 - слова за
; оператором вызова CPYFG
CPYFC:
; Сохранение регистров в стеке
MOV R0, -(SP)
MOV R1, -(SP)
MOV R2, -(SP)
;Извлечение параметров из W1-W3
MOV (R5)+, R0
MOV (R5)+, R1
MOV (R5)+, R2
; Цикл копирования
L: MOVB (R1)+, (R2)+
SOB R0, L
; Восстановл. регистров из стека
MOV (SP)+, R2
MOV (SP)+, R1
MOV (SP)+, R0 ;
; Возврат по адресу в R5,
; указывающему за слово W3
RTS R5
Пример для I8086
; Фаза вызова
CALL CPYFC
DW SIZE1
DW M1
DW M2
; Точка, куда должен быть
; обеспечен возврат
; В подпрограмме CPYFC параметры
; извлекаются через адрес возврата,
; находящийся в стеке
CPYFC PROC NEAR
; стек адресуем через BP
PUSH BP
MOV BP, SP
; сохраняем регистры
PUSH SI
PUSH DI
PUSH CX
MOV DI, [BP+2]
MOV CX, CS:[DI]
MOV SI, CS:[DI+2]
MOV DI, CS:[DI+4]
L1: MOV AL, [SI]
INC SI
MOV [DI], AL
INC DI
LOOP L1
; восстановление регистров
POP CX
POP DI
POP SI
POP BP
; возврат
POP AX ; извлечение &W1
ADD AX, 6 ; АВ = &W1 + 6
JMP AX ; возврат
CPYFC ENDP
Передача параметров через стек
func(x1,x2,x3)
Прямой порядок передачи | Обратный порядок передачи |
push x1 push x2 push x3 call func | push x3 push x2 push x1 call func |
Состояние стека при входе в ПП | |
mem[SP] – АВ mem[SP+2] – x3 mem[SP+4] – x2 mem[SP+6] – x1 | mem[SP] – АВ mem[SP+2] – x1 mem[SP+4] – x2 mem[SP+6] – x3 |
Пример PDP-11
; cpystk(int len, char * from, char *to)
; Копирует len>0 байт из области
; памяти from в область памяти to
; смещения к параметрам
LEN = 2
FROM = 4
TO = 6
CPYSTK: MOVB @FROM(SP),@TO(SP)
INC FROM(SP)
INC TO(SP)
DEC LEN(SP)
BNE CPYSTK
RTS PC
Фаза вызова
MOV #M2, -(SP)
MOV #M1, -(SP)
MOV #SIZE1, -(SP)
JSR PC, CPYSTK ; CALL CPYSTK
Модификация с целью повышения быстродействия
CPYSTK: MOV R0, -(SP)
MOV R1, -(SP)
MOV R2, -(SP)
; теперь смещения другие
LEN = 8.
FROM = 10.
TO = 12.
MOV LEN(SP), R0
MOV FROM(SP), R1
MOV TO(SP), R2
; Цикл копирования
L: MOVB (R1)+, (R2)+
SOB R0, L
; Восстановление регистров
MOV (SP)+, R2
MOV (SP)+, R1
MOV (SP)+, R0
RTS PC
С целью уменьшения ошибок, связанных с изменением смещений к параметрам, используется базирование
CPYSTK: MOV R5, -(SP)
MOV SP, R5
; смещения относительно R5 постоянны
; *R5 – сохраненное R5
; *(R5+2) – адрес возврата АВ
; *(R5+4) – len, *(R5+6) – from, *(R5+8) – to
LEN = 4
FROM = 6
TO = 8.
MOV R0, -(SP)
MOV R1, -(SP)
MOV R2, -(SP)
MOV LEN(R5), R0
MOV FROM(R5), R1
MOV TO(R5), R2
L: MOVB (R1)+, (R2)+
SOB R0, L
MOV (SP)+, R2
MOV (SP)+, R1
MOV (SP)+, R0
MOV (SP)+, R5
RTS PC
I8086:
CPYSTK PROC NEAR
PUSH BP ; Организация
MOV BP, SP ; базирования на BP
PUSH CX
PUSH SI
PUSH DI
BP-6 => | Старое DI |
BP-4 => | Старое SI |
BP-2 => | Старое CX |
BP => | Старое BP |
BP+2 => | Адрес возврата |
BP+4 => | len |
BP+6 => | from |
BP+8 => | to |
LEN = 4
FROM = 6
TO = 8
MOV CX, [BP+LEN]
MOV SI, [BP+FROM]
MOV DI, [BP+TO]
PUSH DS
POP ES
CLD
REP MOVSB
POP DI
POP SI
POP CX
POP BP
RET
CPYSTK ENDP
Освобождение области стека, занятой параметрами
1. В фазе вызова
; PDP-11
JSR PC, CPYSTK
ADD #6, SP
; I8086
CALL CPYSTK
ADD SP, #6
2. В операторе выхода из подпрограммы
;I8086
RET 6
Возврат значений из подпрограмм-функций
1. Регистры
2. Область памяти, адресуемая переданным в качестве указателя параметром
3. Стек
Иногда учитывается цепочка операций и
стек параметров одного вызова используется в другом:
; char * cpystk(int len, char *from, char *to)
M1: .BLKB 20
M2: .BLKB 20
M3: .BLKB 40
; получение m3 = m1+m2
; p = cpystk(20,m2,cpystk(20,m1,m3)+20)
MOV #M3, -(SP)
MOV #M1, -(SP)
MOV #20., -(SP)
CALL CPYSTK
; SP => #20.
; SP+2 => #M1
; SP+4 => #M3
ADD #20, 4(SP) ; M3+20?
MOV #M2, 2(SP) ; M2
CALL CPYSTK
ADD #6, SP
MOV R0, P
Локальные параметры
; Обмен местами двух массивов
void mxchg(int len, char *p1, char *p2)
{ char buf[size];
cpystk(len, p1,buf);
cpystk(len, p2,p1);
cpystk(len, buf, p2);
}
MXCHG PROC NEAR
PUSH BP
MOV BP, SP
SUB SP, SIZE; char buf[size]
; cpystk(len, p1,buf);
LEA AX, [BP-SIZE]
PUSH AX
PUSH [BP+P1]
PUSH [BP+LEN]
CALL CPYSTK
ADD SP, 6
; cpystk(len, p2,p1);
PUSH [BP+P1]
PUSH [BP+P2]
PUSH [BP+LEN]
CALL CPYSTK
ADD SP, 6
; cpystk(len, buf, p2);
PUSH [BP+P2]
LEA AX, [BP-SIZE]
PUSH AX
PUSH [BP+LEN]
CALL CPYSTK
ADD SP, 6+SIZE
RET
MXCHG ENDP
Реализация управляющих структур средствами машинных команд
IF-THEN IF-THEN-ELSE IF-THEN-ELSEIF-…-ELSE | Из лекции по ОЭВМ + дома |
switch(var)
|
Из за большого объема этот материал размещен на нескольких страницах:
1 2 3 4 5 6 |


