ASM [8088] Problema con esercizio

Stato
Discussione chiusa ad ulteriori risposte.

Ryel

Utente Bronze
17 Giugno 2015
3
1
0
35
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...

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.
 
Ho reimplementato la funzione usa1 che era sbagliata e ho scritto una roba del genere:

Codice:
usa1:
    PUSH BP
    MOV BP, SP
    ! devo implementare lo scorrimento dell'array facendo +2 all'offset
    PUSH AX
    !
    MOV AX, 1
    PUSH BX
    ! accumulatore di somme parziali
    MOV BX, 0
    PUSH DI
    MOV DI, 2
    PUSH SI
    ! qui gli mettiamo l'inizio dell'offset del vettore
    MOV SI, 8(BP)

    CMP AX, 4(BP)
    ! salta a fine ciclo se l'indice in AX supera il n. di elementi del parametro passato alla funzione
    JGE fineciclo
    ! moltiplichiamo AX per 2 e il risultato viene lasciato in AX (il passo di scorrimento dell'array)
    MUL DI
    ! aggiungiamo all'inizio dell'array l'indice potenza di 2
    ADD SI, AX
    ADD BX, SI
    SHL AX, 1
    fineciclo:
        MOV AX, BX
        POP BP
        RET

Il problema è che l'emulatore mi da il seguente errore: Return on suspicious stack pointer prdepth 2

C'è qualcuno che riesce ad aiutarmi? È una roba piuttosto importante :\
 
Stato
Discussione chiusa ad ulteriori risposte.