JavascriptProva

sabato 21 settembre 2013

Passaggio di parametri tramite stack con indicazione dei parametri nella direttiva PROC.

Ripassati CMP, alcuni salti condizionati, diverse flags, e riscoperta la tecnica di Giobe per ottenere la stampa a video dei codici ASCII dei numeri, mediante la quale egli realizza la procedura Byt2Asc, ho pensato di creare una Byt2Asc nella quale il parametro sia passato mediante lo stack, aggiungendo alla direttiva PROC il parametro.
Ecco la procedura:
public Byt2Asc
text segment byte public
Byt2Asc proc near C,num:WORD
 mov ax,num
 push ax
 shr al,1
 shr al,1
 shr al,1
 shr al,1
 
 cmp al,0AH
 jb X1
 add al,7
X1: add al,30h

 mov ah,0eh
 int 10h
 
 pop ax
 and al,0Fh
 
 cmp al,0AH
 jb X2
 add al,7
X2: add al,30h

 mov ah,0eh
 int 10h

 ret 2
Byt2Asc endp
text ends
end
Per specificare i parametri nella direttiva PROC, bisogna dichiarare anche la "convenzione di chiamata", che può essere C o di altro tipo (la ripasserò in seguito) in quanto la procedura deve conoscere l'ordine nel quale ritirare i parametri dallo stack.
Ho dichiarato C, ma mi sono cominciato a scontrare con una persistente segnalazione di errore, che non riuscivo a capire, di "unresolved external". Poi, ricordando l'associazione di idee di convenzione di chiamata C con l'underscore iniziale, ho capito che il problema era che nel programma chiamante avrei dovuto far precedere il nome Byt2Asc da un underscore, così ho fatto e ho risolto il problema:
extrn Cancella:near
extrn _Byt2Asc:near
extrn KeyWait:near

text segment public

.....
Ho assemblato e linkato il tutto, e funziona.
Dal momento che l'aggiunta di parametri automatizza parte del codice, vediamo qual è il vero codice in DEBUG:
AX=00F4  BX=0000  CX=0450  DX=0000  SP=03FC  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1786  CS=1781  IP=001E   NV UP EI PL NZ NA PO NC
1781:001E 55            PUSH    BP
-p

AX=00F4  BX=0000  CX=0450  DX=0000  SP=03FA  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1786  CS=1781  IP=001F   NV UP EI PL NZ NA PO NC
1781:001F 8BEC          MOV     BP,SP
-p

AX=00F4  BX=0000  CX=0450  DX=0000  SP=03FA  BP=03FA  SI=0000  DI=0000
DS=1771  ES=1771  SS=1786  CS=1781  IP=0021   NV UP EI PL NZ NA PO NC
1781:0021 8B4604        MOV     AX,[BP+04]                         SS:03FE=00F4
-p

........


AX=0E34  BX=0000  CX=0450  DX=0000  SP=03FA  BP=03FA  SI=0000  DI=0000
DS=1771  ES=1771  SS=1786  CS=1781  IP=0048   NV UP EI PL NZ NA PO NC
1781:0048 5D            POP     BP
-p

AX=0E34  BX=0000  CX=0450  DX=0000  SP=03FC  BP=0000  SI=0000  DI=0000
DS=1771  ES=1771  SS=1786  CS=1781  IP=0049   NV UP EI PL NZ NA PO NC
1781:0049 C20200        RET     0002
-p
Ecco: Le istruzioni "automatiche" sono:
PUSH BP
MOV BP,SP

.....

POP BP
Ossia il salvataggio nello stack del Base Pointer, l'attribuzione al Base Pointer del valore di SP, e poi, alla fine, presupponendo che SP sia tornato al valore corrispondente a BP mediante il corretto equilibrio dei pushaggi e dei poppaggi, l'istruzione che riprende il valore precedente di BP.

Nessun commento:

Posta un commento