Ciao ragazzi sono un neofita della programmazione in Assembly per 8086/8088 e mi sto sbattendo per cercare di venire a capo di un semplice esercizio ma credo di essermi bloccato. Il testo dell'esercizio dice:
Il file crea_2vettori_stack.s colloca sullo stack due vettori contenenti ciascuno lo stesso numero di elementi interi a 16bit e chiama una funzione di nome esegui, passando a questa funzione, 3 parametri sullo stack, qui sotto elencati in ordine crescente di posizione (indirizzo) sullo stack:
- lo scostamento, rispetto all’inizio dello stack, dell’inizio del primo vettore;
- lo scostamento, rispetto all’inizio dello stack, dell’inizio del secondo vettore;
- il numero di elementi interi a 16bit di cui è composto ciascun vettore
La funzione esegui restituisce un risultato intero mettendolo nel registro AX. Al termine della funzione esegui, il programma principale stampa a video il risultato della funzione, prendendolo dal registro AX.
La funzione esegui deve prima chiamare la funzione usa1 e successivamente chiamare la funzione usa2.
Ciascuna di queste funzioni prende 2 parametri, che sono:
- l’offset, rispetto all’inizio del segmento di stack, dell’inizio di un vettore di interi a 16bit;
- il numero di elementi interi di quel vettore.
Ciascuna di queste funzioni restituisce come risultato un intero a 16bit, mettendolo in uno spazio dello stack creato dal chiamante nel record di attivazione costruito per la funzione stessa.
La funzione esegui chiama prima la funzione usa1 passandole l’offset del primo vettore ed il numero di elementi del primo vettore. Poi la funzione esegui chiama la funzione usa2 passandole l’offset del secondo vettore ed il numero di elementi del secondo vettore.
La funzione esegui deve sommare i risultati restituiti dalle due funzioni.
Il risultato che la funzione esegui deve restituire al programma principale, mediante il registro AX, è proprio questa somma.
La funzione usa1 deve restituire la somma degli elementi di indice uguali ad una potenza intera di 2 (1, 2, 4,...).
Ad esempio, se il vettore è così composto (3,2,1,5,4,9,8,10,7,6) il risultato deve essere 2+1+4+8=15
La funzione usa2 deve scandire il vettore e restituire il numero degli elementi del vettore che soddisfano ENTRAMBE le due seguenti condizioni: i) il valore dell’elemento è uguale a 0; ii) il valore dell’elemento successivo è uguale a 0.
Ad esempio, se il vettore è così composto (3,0,0,5,4,0,0,0,7,6) il risultato deve essere 3.
----
Questo è il mio codice. La funzione usa2 non riesco a capire proprio come implementarla, la funziona usa1 concettualmente credo sia giusta ma penso ci sia qualche errore...
Se qualcuno è in grado di aiutarmi gliene sarei veramente grato.
Il file crea_2vettori_stack.s colloca sullo stack due vettori contenenti ciascuno lo stesso numero di elementi interi a 16bit e chiama una funzione di nome esegui, passando a questa funzione, 3 parametri sullo stack, qui sotto elencati in ordine crescente di posizione (indirizzo) sullo stack:
- lo scostamento, rispetto all’inizio dello stack, dell’inizio del primo vettore;
- lo scostamento, rispetto all’inizio dello stack, dell’inizio del secondo vettore;
- il numero di elementi interi a 16bit di cui è composto ciascun vettore
La funzione esegui restituisce un risultato intero mettendolo nel registro AX. Al termine della funzione esegui, il programma principale stampa a video il risultato della funzione, prendendolo dal registro AX.
La funzione esegui deve prima chiamare la funzione usa1 e successivamente chiamare la funzione usa2.
Ciascuna di queste funzioni prende 2 parametri, che sono:
- l’offset, rispetto all’inizio del segmento di stack, dell’inizio di un vettore di interi a 16bit;
- il numero di elementi interi di quel vettore.
Ciascuna di queste funzioni restituisce come risultato un intero a 16bit, mettendolo in uno spazio dello stack creato dal chiamante nel record di attivazione costruito per la funzione stessa.
La funzione esegui chiama prima la funzione usa1 passandole l’offset del primo vettore ed il numero di elementi del primo vettore. Poi la funzione esegui chiama la funzione usa2 passandole l’offset del secondo vettore ed il numero di elementi del secondo vettore.
La funzione esegui deve sommare i risultati restituiti dalle due funzioni.
Il risultato che la funzione esegui deve restituire al programma principale, mediante il registro AX, è proprio questa somma.
La funzione usa1 deve restituire la somma degli elementi di indice uguali ad una potenza intera di 2 (1, 2, 4,...).
Ad esempio, se il vettore è così composto (3,2,1,5,4,9,8,10,7,6) il risultato deve essere 2+1+4+8=15
La funzione usa2 deve scandire il vettore e restituire il numero degli elementi del vettore che soddisfano ENTRAMBE le due seguenti condizioni: i) il valore dell’elemento è uguale a 0; ii) il valore dell’elemento successivo è uguale a 0.
Ad esempio, se il vettore è così composto (3,0,0,5,4,0,0,0,7,6) il risultato deve essere 3.
----
Questo è il mio codice. La funzione usa2 non riesco a capire proprio come implementarla, la funziona usa1 concettualmente credo sia giusta ma penso ci sia qualche errore...
Codice:
_PRINTF = 127
_GETCHAR = 117
_EXIT = 1
asciinl = 10
EOF = -1
.SECT .TEXT
start:
PUSH BP
! imposto il BP affinche' punti al dynamic link
MOV BP,SP
creavettore2:
PUSH 1
PUSH 3
PUSH 2
PUSH 4
PUSH 0
PUSH 8
PUSH 7
PUSH 9
PUSH 11
PUSH 3
creavettore1:
PUSH 2
PUSH 6
PUSH 4
PUSH 6
PUSH 8
PUSH 5
PUSH 7
PUSH 4
PUSH 3
PUSH 1
mettinumelem:
PUSH 10
mettiaddrvet2:
MOV AX,BP
SUB AX,20
PUSH AX
mettiaddrvet1:
SUB AX,20
PUSH AX
! inserire qui la chiamata alla funzione
call esegui
! finita la funzione, ripristino lo stack
! elimino i due indirizzi e numeroelementi dallo stack
ADD SP,6
! elimino vettori dallo stack
ADD SP,40
! stampo il risultato messo in AX
PUSH AX
PUSH pfmt
PUSH _PRINTF
SYS
! elimino i parametri passati alla syscall
ADD SP,6
! ripristino il BP caricandolo dal dynamic link
POP BP
! termino processo
PUSH 0
PUSH _EXIT
SYS
! IMPLEMENTARE TUTTO QUELLO CHE SERVE
! ANCHE IN ALTRE FUNZIONI
!
esegui:
PUSH BP
MOV BP,SP
!
! IMPLEMENTARE TUTTO QUELLO CHE SERVE
! ANCHE IN ALTRE FUNZIONI
! mio intervento
PUSH AX, SS - [BP+4]
PUSH AX, SS - [BP+6]
PUSH AX, BP+8
call usa1
call usa2
POP BP
RET
usa1:
PUSH BP
MOV BP, SP
; devo implementare lo scorrimento dell'array facendo +2 all'offset
PUSH AX, 1 ; accumulatore
PUSH BX, 0 ; somme parziali
PUSH DI;
MOV DI, 2
; offset di v1 è raggiungibile a BP+8 -> SS + [BP+8]
CMP AX, BP+4 ; compara l'indice con il numero elementi
JAE fineciclo ; salta a fine ciclo se l'indice supera il n. el
MUL DI, AX ; moltiplica il 2 contenuto in DI per l'indice dell'array
ADD BX, SS + [BP+8+DI] ; somma parziale
SHL AX, AX
fineciclo:
POP BP
RET
usa2:
; non so proprio concettualmente come impostarla
PUSH BP
MOV BP, SP
.SECT .DATA
pfmt: .ASCIZ "The result is %d \n"
.SECT .BSS
STR: .SPACE 80
Se qualcuno è in grado di aiutarmi gliene sarei veramente grato.