nicolap ha scritto:
migliorabile ha scritto:
Stai PASTICCIANDO con CONCETTI FONDAMENTALI!
Una cosa e' LO STACK delle chiamate alle funzioni, gestito da BP e SP, E QUESTO NON LO PUOI TOCCARE,
Un'altra cosa e' lo stack come struttura dati, che DEVI IMPLEMENTARE TU.
Tutti e due funzionano come uno stack, MA quello delle chiamate e' gestito DIRETTAMENTE dalla CPU.
@nonc'èsperanzachemigliori: che fregnaccia colossale! Questo dimostra che di Assembly 8086 non sai niente!
TUTTE le funzioni usano lo Stack per l'allocazione delle variabili temporanee e per il passaggio dei parametri!
Nell'immagine un esempio.
stack1.PNG
Il sorgente della funzione:
Function TFBase64.Prova(Const Numero:integer):integer;
Var
a, b : double;
begin
a := Numero;
b := a * 3.14;
Result := Trunc(b + 0.5);
end; //Prova
Osserva come
- all'inizio della funzione EBP viene salvato
- EBP prende il valore di ESP cioè dell'ultima locazione usata (c'è il vecchio valore di EBP)
- ESP viene DIMINUITO di un tot di byte: lo Stack cresce verso il basso!
A quel punto EBP viene usato come puntatore alle variabili locali e al risultato della funzione.
Alla fine della funzione ESP viene ripristinato ricopiandolo da EBP e liberando quindi lo spazio allocato, infine viene ripristinato EBP: gli altri registri spesso non sono conservati oppure sono usati per il passaggio di parametri ma EBP è fondamentale per l'uso che se ne fa.
Da notare anche che:
- il codice è scritto in Delphi
- le ottimizzazioni sono spente
- il controllo "Range checking" è acceso
Gli altri linguaggi compilati fanno un uso quasi identico dello Stack, le differenza, di solito, sono stilistiche.
Allora, ho notato che hai capito la mia richiesta, però ti chiederei una cortesia se possibile. Io sono in 3° superiore e le cose che so di assembly sono legate all'assembly stesso. Non abbiamo visto l'assembly in funzione di altri linguaggi, abbiamo solo programmato in 8086. Se vuoi ti faccio anche vedere un mio programma per renderti conto del livello a cui sono. Detto ciò, grosso modo credo di aver capito il concetto, ma se è possibile fare un'altro esempio non scritto il delphi ma con un qualcosa di simile a quello allegato qui di sotto capirei meglio. Comunque ne so più di prima quindi grazie lo stesso.
.MODEL SMALL ; definisce il modello di memoria da utilizzare
.STACK 100h ; dimensione massima del codice sorgente
.DATA ; definizione delle stringhe
inserimento DB 'Inserisci un numero ','$'
Decimale DB 'Il risultato in decimale equivale a ','$'
Binario DB 'Il risultato in binario equivale a ','$'
Esadecimale DB 'Il risultato in esadecimale equivale a ','$'
Ottale DB 'Il risultato in ottale equivale a ','$'
accapo DB 13,10,'$'
ricalcola DB 'Per rieseguire il programma da capo digita 1: ','$'
.CODE ; inizio codice sorgente
mov ax,@data
mov ds,ax ; imposta DS per puntare al segmento di dati
sub ax,ax ; azzerare il registro ax
; ||***********||
; ||INSERIMENTO||
; ||***********||
JMP INIZIO2
INIZIO:
mov dx,OFFSET accapo ; fa andare accapo il testo
mov ah,09h
int 21h
INIZIO2:
mov dx,OFFSET inserimento ; stampa d'inserimento del primo numero
mov ah,09h
int 21h
mov ah,01h ; acquisisce delle decine del primo numero
int 21h
sub ah,ah ; controlla se il valore acquisito in input è un numero
cmp ax,30h
JL INIZIO
cmp ax,39h
JG INIZIO
sub al,30h ; porta il valore preso da tastiera al valore effettivo
mov bh,0Ah ; moltpiplica il valore contenuto in ax per quello di bh
mul bh
mov bl,al ; il risultato della moltiplicazione viene salvato in bl
mov ah,01h ; acquisisce delle unità primo numero
int 21h
sub ah,ah ; controlla se il valore acquisito in input è un numero
cmp ax,30h
JL INIZIO
cmp ax,39h
JG INIZIO
sub al,30h ; porta il valore preso da tastiera al valore effettivo
add bl,al ; somma il valore appena acquisito al risultato della moltiplicazione precedente per formare il valore complessivo
mov dx,OFFSET accapo ; Fa andare accapo il testo
mov ah,09h
int 21h
mov dx,OFFSET inserimento ; stampa d'inserimento del secondo numero
mov ah,09h
int 21h
mov ah,01h ; acquisisce delle decine del secondo numero
int 21h
sub ah,ah ; controlla se il valore acquisito in input è un numero
cmp ax,30h
JL INIZIO
cmp ax,39h
JG INIZIO
sub al,30h ; porta il valore preso da tastiera al valore effettivo
mul bh ; moltpiplica il valore contenuto in ax per quello di bh
add bl,al
mov ah,01h ; acquisisce delle decine del secondo numero
int 21h
sub ah,ah ; stampa d'inserimento del secondo numero
cmp ax,30h
JL INIZIO
cmp ax,39h
JG INIZIO
sub al,30h ; porta il valore preso da tastiera al valore effettivo
add bl,al
mov dx,OFFSET accapo ; fa andare accapo il testo
mov ah,09h
int 21h
sub bh,bh
push bx ; salvataggio del risultato della somma
mov ax,bx
; ||*******************||
; ||CALCOLO IN DECIMALE||
; ||*******************||
cmp ax,0Ah ; controlla se maggiore
JGE ALLORA1
add al,30h ; codifica ASCII della somma
JMP RISULTATO
ALLORA1:
mov ch, 0h ;inizializzazione a 0
FOR1:
sub al, 0Ah ; spartizione delle cifre nei vari registi
inc ch ; ch=decine al=untià
cmp ax,0Ah
JGE FOR1
cmp ch,0Ah ; controlla se le decine sono maggiori di 0A
JL RISULTATO2
sub ch,0Ah ; ulteriore spartizione
mov cl,01h ; cl centinaia
JMP RISULTATO3
; ||******************||
; ||STAMPA IN DECIMALE||
; ||******************||
RISULTATO:
mov bl,al
mov dx,OFFSET Decimale ; stampa della stringa risultato
mov ah,09h
int 21h
mov dl,bl ; stampa della cifra
mov ah,02h
int 21h
JMP OTTALE1
RISULTATO2:
mov bl,al
mov dx,OFFSET Decimale ; stampa della stringa risultato
mov ah,09h
int 21h
mov dl,ch ; stampa delle decine
add dl,30h
mov ah,02h
int 21h
mov dl,bl ; stampa delle unità
add dl,30h
mov ah,02h
int 21h
JMP OTTALE1
RISULTATO3:
mov bl,al
mov dx,OFFSET Decimale ; stampa della stringa risultato
mov ah,09h
int 21h
mov dl,cl ; stampa delle centinaia
add dl,30h
mov ah,02h
int 21h
mov dl,ch ; stampa delle decine
add dl,30h
mov ah,02h
int 21h
mov dl,bl ; stampa delle unità
add dl,30h
mov ah,02h
int 21h
; ||*****************||
; ||CALCOLO IN OTTALE||
; ||*****************||
OTTALE1:
mov dx,OFFSET accapo ; fa andare accapo il testo
mov ah,09h
int 21h
pop ax ; assegnazione ad bl della somma dei due numeri
push ax ; salvataggio del risultato della somma
cmp ax,08h ; controllo se il risultato è maggiore di 08
JGE ALLORA2
add al,30h ; conversone in codifica ASCII
JMP RISOTTALE1
ALLORA2:
mov ch, 0h ; spartizione delle cifre su vari registi
FOR2: ; ch=decine al=unità
sub al, 08h
inc ch
cmp ax,08h
JGE FOR2
cmp ch,08h ; controllo sulle centinaia
JL RISOTTALE2 ; cl=centinaia
sub cl,cl
FOR21:
sub ch, 08h
inc cl
cmp ch,08h
JGE FOR21
JMP RISOTTALE3
; ||****************||
; ||STAMPA IN OTTALE||
; ||****************||
RISOTTALE1:
mov dx,OFFSET accapo ; fa andare accapo il testo
mov ah,09h
int 21h
mov bl,al
mov dx,OFFSET Ottale ; stampa della stringa risultato
mov ah,09h
int 21h
mov dl,bl ; stampa delle unità
mov ah,02h
int 21h
JMP ESADECIMALE1
RISOTTALE2:
mov dx,OFFSET accapo ; fa andare accapo il testo
mov ah,09h
int 21h
mov bl,al
mov dx,OFFSET Ottale ; stampa della stringa risultato
mov ah,09h
int 21h
mov dl,ch ; stampa delle decine
add dl,30h
mov ah,02h
int 21h
mov dl,bl ; stampa delle unità
add dl,30h
mov ah,02h
int 21h
JMP ESADECIMALE1
RISOTTALE3:
mov bl,al
mov dx,OFFSET Ottale ; stampa della stringa risultato
mov ah,09h
int 21h
mov dl,cl ; stampa delle centinaia
add dl,30h
mov ah,02h
int 21h
mov dl,ch ; stampa delle decine
add dl,30h
mov ah,02h
int 21h
mov dl,bl ; stampa delle unità
add dl,30h
mov ah,02h
int 21h
; ||**********************||
; ||CALCOLO IN ESADECIMALE||
; ||**********************||
ESADECIMALE1:
pop ax ; assegnazione ad bl della somma dei due numeri
push ax ; salvataggio del risultato della somma
cmp ax,10h ; controllo se la somma è maggiore di 10
JGE ALLORA3
add al,30h ; conversione codifica ASCII
JMP RISESADECIMALE1
ALLORA3: ; spartizione delle cifre su vari registi
mov ch, 0h ; ch=decine al=unità
FOR3:
sub al, 10h
inc ch
cmp ax,10h
JGE FOR3
JMP RISESADECIMALE2
; ||*********************||
; ||STAMPA IN ESADECIMALE||
; ||*********************||
RISESADECIMALE1:
mov dx,OFFSET accapo ; fa andare accapo il testo
mov ah,09h
int 21h
mov bl,al ; controllo se il valore sia maggiore di 09 per la stampa dei caratteri
cmp bl, 3Ah
JL RIS1
add bl,07h
RIS1:
mov dx,OFFSET Esadecimale ; stampa della stringa risultato
mov ah,09h
int 21h
mov dl,bl ; stampa delle unità
mov ah,02h
int 21h
JMP BINARIO1
RISESADECIMALE2:
mov dx,OFFSET accapo ;fa andare accapo il testo
mov ah,09h
int 21h
mov bl,al
mov dx,OFFSET Esadecimale ; stampa della stringa risultato
mov ah,09h
int 21h
mov dl,ch ; stampa delle decine
cmp dl, 0Ah
JL RIS2
add dl,07h
RIS2:
add dl,30h
mov ah,02h
int 21h
mov dl,bl ; stampa delle unità
cmp dl, 0Ah
JL RIS3
add dl,07h
RIS3:
add dl,30h
mov ah,02h
int 21h
JMP BINARIO1
; ||******************||
; ||CALCOLO IN BINARIO||
; ||******************||
BINARIO1:
pop ax ; assegnazione ad bl della somma dei due numeri
sub cx,cx
mov bl,01h ; salvataggio del valore 1 in bl
sub dx,dx ; azzeramento del registro dx per assegnarli il valore 0
CICLO1: ; tramite le divisioni avviene la conversione in binario
inc bl ; se il resto della divisione è diverso da 0 esegue la push di 1, se è uguale a 0 fa la push del di 0
div bl
dec bl
cmp ah,00h
JNE ELSE1
push dx
JMP FIN1
ELSE1:
push bx
FIN1:
mov cl,al
inc ch
mov ax,cx
sub ah,ah
cmp ax,00h
JG CICLO1
; ||*****************||
; ||STAMPA IN BINARIO||
; ||*****************||
RISBINARIO1:
mov cl,ch ; assegnazione di cl e azzeramento di ch
sub ch,ch ; cx usato in seguito per il ciclo for
mov dx,OFFSET accapo ; fa andare accapo il testo
mov ah,09h
int 21h
mov dx,OFFSET Binario ; stampa della stringa risultato
mov ah,09h
int 21h
FOR4:
pop dx ; stapa del risultato tramite ciclo for
add dl,30h
mov ah,02h
int 21h
LOOP FOR4
mov dx,OFFSET accapo ; fa andare accapo il testo
mov ah,09h
int 21h
mov dx,OFFSET accapo ; fa andare accapo il testo
mov ah,09h
int 21h
mov dx,OFFSET ricalcola ; stampa la stringa ricalcola
mov ah,09h
int 21h
mov ah,01h ; acquisisce la risposta del ricalcola
int 21h
sub ah,ah ; condizione di salto
cmp ax,31h
JNE FINE
JMP INIZIO
FINE:
mov ah,4ch ;funzione dos per terminare il programma
int 21h ;termina il programma
END ;END va sempre messo alla fine del programma