JavascriptProva

venerdì 20 settembre 2013

Parametri tramite stack: due erroracci che si compensano!

Ecco trattata la procedura Stampa mediante passaggio di parametri per mezzo dello stack.
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 bx
 push ax
 call Stampa
 
 
 call KeyWait
 
 mov ah,4ch
 int 21H
 
stampa proc near
 pop ax
 mov bx,ax
 pop ax
 mov ah,09h
 mov bh,00h
 mov cx,1
 int 10h
 ret
stampa endp
text ends

stack segment para stack
 db 1024 dup(00H)

stack ends

end start
 
Funziona.
Vediamo nel dettaglio cosa accade:
AX=0003  BX=0000  CX=0430  DX=0000  SP=0400  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0003   NV UP EI PL NZ NA PO NC
1781:0003 B041          MOV     AL,41
-p

AX=0041  BX=0000  CX=0430  DX=0000  SP=0400  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0005   NV UP EI PL NZ NA PO NC
1781:0005 B30C          MOV     BL,0C
-
qui in AL e BL vengono posti rispettivamente il carattere e il colore.
AX=0041  BX=0000  CX=0430  DX=0000  SP=0400  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0005   NV UP EI PL NZ NA PO NC
1781:0005 B30C          MOV     BL,0C
-p

AX=0041  BX=000C  CX=0430  DX=0000  SP=0400  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0007   NV UP EI PL NZ NA PO NC
1781:0007 53            PUSH    BX
-d 1784:03f0
1784:03F0  00 00 00 00 03 00 41 00-00 00 07 00 81 17 C4 11   ......A.........
1784:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
-
Prima che i parametri vengano passati tramite stack, ottengo un dump della "cima" dello stack.
Adesso vediamo come cambia dopo il primo push:
-p

AX=0041  BX=000C  CX=0430  DX=0000  SP=03FE  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0008   NV UP EI PL NZ NA PO NC
1781:0008 50            PUSH    AX
-d 1784:03f0
1784:03F0  00 00 00 00 41 00 00 00-08 00 81 17 C4 11 0C 00   ....A...........
1784:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
-
Ecco: in cima allo stack è stato depositato il colore presente in BH. SP è stato decrementato di 2 (è stata inserita una WORD)
Secondo push:
AX=0041  BX=000C  CX=0430  DX=0000  SP=03FC  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0009   NV UP EI PL NZ NA PO NC
1781:0009 E80700        CALL    0013
-d 1784:03f0
1784:03F0  00 00 41 00 00 00 09 00-81 17 C4 11 41 00 0C 00   ..A.........A...
1784:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
-
E adesso in cima allo stack è stato depositato anche il carattere (41H, codice ASCII della A), e SP è stato decrementato ancora di 2.

Successivamente, con il CALL (NEAR), viene depositato nello stack l'indirizzo "di ritorno" calcolato:
-p

AX=0041  BX=000C  CX=0430  DX=0000  SP=03FC  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0009   NV UP EI PL NZ NA PO NC
1781:0009 E80700        CALL    0013
-t

AX=0041  BX=000C  CX=0430  DX=0000  SP=03FA  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0013   NV UP EI PL NZ NA PO NC
1781:0013 58            POP     AX
-d1784:03f0
1784:03F0  41 00 00 00 13 00 81 17-C4 11 0C 00 41 00 0C 00   A...........A...
1784:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
-
E guardacaso, una fortunata (o sfortunata) coincidenza fa sì che casualmente il programma "funzioni"! adesso faccio POP AX:
-p

AX=000C  BX=000C  CX=0430  DX=0000  SP=03FC  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0014   NV UP EI PL NZ NA PO NC
1781:0014 8BD8          MOV     BX,AX
-d 1784:03f0
1784:03F0  41 00 0C 00 00 00 14 00-81 17 C4 11 41 00 0C 00   A...........A...
1784:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
-
Infatti l'indirizzo di ritorno è 000C, che è uguale alla word pushata che contiene il codice di colore rosso (0CH), e che viene posta in AX per poi essere passata in BX, passando in BL il codice di colore per la procedura Stampa.

Infatti non avevo tenuto conto, nel manipolare lo stack dalla procedura, che bisognava considerare l'indirizzo di ritorno messo in cima allo stack!
Mi meraviglio del fatto che il programma funzioni normalmente, ma forse ho capito perchè. Vado avanti:
-p

AX=000C  BX=000C  CX=0430  DX=0000  SP=03FC  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0014   NV UP EI PL NZ NA PO NC
1781:0014 8BD8          MOV     BX,AX
-d 1784:03f0
1784:03F0  41 00 0C 00 00 00 14 00-81 17 C4 11 41 00 0C 00   A...........A...
1784:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
-p

AX=000C  BX=000C  CX=0430  DX=0000  SP=03FC  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0016   NV UP EI PL NZ NA PO NC
1781:0016 58            POP     AX
-d 1784:03f0
1784:03F0  41 00 0C 00 00 00 16 00-81 17 C4 11 41 00 0C 00   A...........A...
1784:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
-p

AX=0041  BX=000C  CX=0430  DX=0000  SP=03FE  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0017   NV UP EI PL NZ NA PO NC
1781:0017 B409          MOV     AH,09
-d 1784:03f0
1784:03F0  41 00 0C 00 41 00 00 00-17 00 81 17 C4 11 0C 00   A...A...........
1784:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
-
Il secondo POP AX mette in AX il valore della lettera 41H.
-p

AX=0941  BX=000C  CX=0430  DX=0000  SP=03FE  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0019   NV UP EI PL NZ NA PO NC
1781:0019 B700          MOV     BH,00
-p

AX=0941  BX=000C  CX=0430  DX=0000  SP=03FE  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=001B   NV UP EI PL NZ NA PO NC
1781:001B B90100        MOV     CX,0001
-p

AX=0941  BX=000C  CX=0001  DX=0000  SP=03FE  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=001E   NV UP EI PL NZ NA PO NC
1781:001E CD10          INT     10
-p
A
AX=0941  BX=000C  CX=0001  DX=0000  SP=03FE  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0020   NV UP EI PL NZ NA PO NC
1781:0020 C3            RET
-p
E già: ho erroneamente invertito l'ordine dei parametri immessi nello stack! Secondo errore, che ha compensato il primo! Infatti ho pushato prima il colore e dopo la lettera, mentre nella procedura ho poppato prima il colore e dopo la lettera, cosa che se non avessi avuto casualmente l'indirizzo di ritorno contenente esattamente il codice del colore nella parte bassa della WORD avrebbe generato una "stranezza".

Adesso RET riprende quello che nelle mie erronee intenzioni doveva essere il colore, e che coincide con l'indirizzo di ritorno per puro caso, e reindirizza IP nel modo giusto.
-p
A
AX=0941  BX=000C  CX=0001  DX=0000  SP=03FE  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=0020   NV UP EI PL NZ NA PO NC
1781:0020 C3            RET
-t

AX=0941  BX=000C  CX=0001  DX=0000  SP=0400  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1784  CS=1781  IP=000C   NV UP EI PL NZ NA PO NC
1781:000C E81200        CALL    0021
-d 1784:03f0
1784:03F0  41 00 0C 00 41 09 41 09-00 00 0C 00 81 17 C4 11   A...A.A.........
1784:0400  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0410  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0420  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0430  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0440  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0450  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
1784:0460  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00   ................
-
...pronto a chiamare la procedura KeyWait.

Simpatico, questo errore compensato da un altro errore!!!

Così, anziche poppare i parametri dallo stack, ho capito che devo usare istruzioni diverse per poterli richiamare dallo stack nel corpo della procedura, perchè per poppare i parametri non posso fare a meno di poppare anche l'indirizzo di ritorno, creando casini!

Nessun commento:

Posta un commento