Le due WORD pushate prima di chiamare la procedura, contenenti i parametri, non vengono poi ripoppate o smaltite in qualche modo, cosicchè SP non torna ai valori iniziali fino alla fine del programma.
Seguo in DEBUG i valori prima e dopo la chiamata della procedura Stampa:
AX=0003 BX=0000 CX=0440 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0003 NV UP EI PL NZ NA PO NC 1781:0003 B041 MOV AL,41 -p AX=0041 BX=0000 CX=0440 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0005 NV UP EI PL NZ NA PO NC 1781:0005 B30C MOV BL,0C -p AX=0041 BX=000C CX=0440 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0007 NV UP EI PL NZ NA PO NC 1781:0007 50 PUSH AX -p AX=0041 BX=000C CX=0440 DX=0000 SP=03FE BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0008 NV UP EI PL NZ NA PO NC 1781:0008 53 PUSH BX -p AX=0041 BX=000C CX=0440 DX=0000 SP=03FC BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0009 NV UP EI PL NZ NA PO NC 1781:0009 E80700 CALL 0013 -Il valore di base di SP è 0400.
Con il pushaggio dei parametri diventa poi 03FE e 03FC.
-t AX=0041 BX=000C CX=0440 DX=0000 SP=03FA BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0013 NV UP EI PL NZ NA PO NC 1781:0013 55 PUSH BP -Con la CALL diventa 03FA perchè viene pushato l'indirizzo di ritorno.
-t AX=0041 BX=000C CX=0440 DX=0000 SP=03F8 BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0014 NV UP EI PL NZ NA PO NC 1781:0014 8BEC MOV BP,SP -t>Con il PUSH BP all'interno della procedura diventa 03F8.
AX=0041 BX=000C CX=0440 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0016 NV UP EI PL NZ NA PO NC 1781:0016 8B5E04 MOV BX,[BP+04] SS:03FC=000C -t AX=0041 BX=000C CX=0440 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0019 NV UP EI PL NZ NA PO NC 1781:0019 8B4606 MOV AX,[BP+06] SS:03FE=0041 -t AX=0041 BX=000C CX=0440 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0019 NV UP EI PL NZ NA PO NC 1781:0019 8B4606 MOV AX,[BP+06] SS:03FE=0041 -t AX=0041 BX=000C CX=0440 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=001C NV UP EI PL NZ NA PO NC 1781:001C B409 MOV AH,09 -t AX=0941 BX=000C CX=0440 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=001E NV UP EI PL NZ NA PO NC 1781:001E B700 MOV BH,00 -t AX=0941 BX=000C CX=0440 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0020 NV UP EI PL NZ NA PO NC 1781:0020 B90100 MOV CX,0001 -t AX=0941 BX=000C CX=0001 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0023 NV UP EI PL NZ NA PO NC 1781:0023 CD10 INT 10 -p A AX=0941 BX=000C CX=0001 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0025 NV UP EI PL NZ NA PO NC 1781:0025 5D POP BP -pE resta tale fino ad ora. Quindi il POP BP lo riporta a 03FA.
AX=0941 BX=000C CX=0001 DX=0000 SP=03FA BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0026 NV UP EI PL NZ NA PO NC 1781:0026 C3 RET -
E con il RET, col recupero dell'indirizzo di ritorno, va a 03FC.
-t AX=0941 BX=000C CX=0001 DX=0000 SP=03FC BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=000C NV UP EI PL NZ NA PO NC 1781:000C E81800 CALL 0027 -
...per poi restare uguale fino alla fine del programma.
-p AX=1C0D BX=000C CX=0001 DX=0000 SP=03FC BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=000F NV UP EI PL NZ NA PO NC 1781:000F B44C MOV AH,4C -p AX=4C0D BX=000C CX=0001 DX=0000 SP=03FC BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0011 NV UP EI PL NZ NA PO NC 1781:0011 CD21 INT 21 -p Program terminated normally -C'è quindi un conto in sospeso con lo stack, che rimane 4 bytes, ossia 2 words, più in basso rispetto a quello che dovrebbe essere.
Come "aggiustarlo" alla fine della procedura?
Come "riassorbire", cioè, i due parametri che erano stati pushati prima della chiamata della procedura?
Mi pare di ricordare che posporre un numero a RET determina un riassestamento di SP.
Controlliamo...
extrn Cancella:near extrn KeyWait:near ;definiamo il segmento text segment public ;inizio del programma start: call Cancella mov al,'A' mov bl,0Ch push ax push bx call Stampa call KeyWait mov ah,4ch int 21H stampa proc near push bp mov bp,sp mov bx,[bp+4] mov ax,[bp+6] mov ah,09h mov bh,00h mov cx,1 int 10h pop bp ret 4 stampa endp text ends stack segment para stack db 1024 dup(00H) stack ends end start
AX=0941 BX=000C CX=0440 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0020 NV UP EI PL NZ NA PO NC 1781:0020 B90100 MOV CX,0001 -p AX=0941 BX=000C CX=0001 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0023 NV UP EI PL NZ NA PO NC 1781:0023 CD10 INT 10 -p A AX=0941 BX=000C CX=0001 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0025 NV UP EI PL NZ NA PO NC 1781:0025 5D POP BP -t AX=0941 BX=000C CX=0001 DX=0000 SP=03FA BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=0026 NV UP EI PL NZ NA PO NC 1781:0026 C20400 RET 0004 -p AX=0941 BX=000C CX=0001 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000 DS=1771 ES=1771 SS=1785 CS=1781 IP=000C NV UP EI PL NZ NA PO NC 1781:000C E81A00 CALL 0029 -Ecco. Aggiungendo a RET il numero di bytes che sono stati occupati dai parametri passati, oltre a "rimangiarsi" l'indirizzo di ritorno, si resetta SP 4 bytes più in su, al punto di partenza!
Mi pare che ci fosse anche la possibilità di riportare lo stack al valore di base mediante un'istruzione specifica, ma ciò andrebbe fatto dopo il "rientro" nel programma di base.
extrn Cancella:near extrn KeyWait:near ;definiamo il segmento text segment public ;inizio del programma start: call Cancella mov al,'A' mov bl,0Ch push ax push bx call Stampa add sp,4 call KeyWait mov ah,4ch int 21H stampa proc near push bp mov bp,sp mov bx,[bp+4] mov ax,[bp+6] mov ah,09h mov bh,00h mov cx,1 int 10h pop bp ret stampa endp text ends stack segment para stack db 1024 dup(00H) stack ends end start
AX=0941 BX=000C CX=0001 DX=0000 SP=03F8 BP=03F8 SI=0000 DI=0000
DS=1771 ES=1771 SS=1785 CS=1781 IP=0028 NV UP EI PL NZ AC PE NC
1781:0028 5D POP BP
-t
AX=0941 BX=000C CX=0001 DX=0000 SP=03FA BP=0000 SI=0000 DI=0000
DS=1771 ES=1771 SS=1785 CS=1781 IP=0029 NV UP EI PL NZ AC PE NC
1781:0029 C3 RET
-t
AX=0941 BX=000C CX=0001 DX=0000 SP=03FC BP=0000 SI=0000 DI=0000
DS=1771 ES=1771 SS=1785 CS=1781 IP=000C NV UP EI PL NZ AC PE NC
1781:000C 83C404 ADD SP,+04
-t
AX=0941 BX=000C CX=0001 DX=0000 SP=0400 BP=0000 SI=0000 DI=0000
DS=1771 ES=1771 SS=1785 CS=1781 IP=000F NV UP EI PL NZ AC PE NC
1781:000F E81800 CALL 002A
-
Ottimo!
Nessun commento:
Posta un commento