Passaggio parametri Assembly 8086

di il
13 risposte

Passaggio parametri Assembly 8086

Salve ragazzi innanzitutto grazie per la disponibilità e per avermi aiutato ..se qualcuno può aiutarmi ho dei dubbi riguardo al passaggio di parametri attraverso lo stack... ecco la traccia:
Data una stringa e un carattere di controllo passare tramite stack l' indirizzo della stringa e il carattere ad una procedura che verifica la presenza del carattere all' interno della stringa ed in caso affermativo restituisca al programma chiamante la stringa invertita dalla posizione in cui è stato trovato il carattere fino all'inizio.
Ho fatto il pogramma senza utilizzare le procedure e funziona ma con il passaggio di parametri con lo stack non ho proprio capito come funziona.. in particolare non ho capito come fare a passare il carattere di controllo e come restituire poi la stringa invertita..se potete darmi una mano..ma in ogni caso grazie mille ragazzi !
car equ 'o'
data segment
string db "cstgnosrf","$" 
ends

stack segment
    dw   128  dup(0)
ends
code segment
start:
mov ax,@data
mov ds,ax 
xor si,si  
mov ax,car ;[bp+6]
push ax 
lea bx,string ;[bp+4]
push bx
sub sp,6
call inverti
add sp,6    
xor si,si
mov cx,6 
mov ax, 4c00h
int 21h  
ends     
inverti proc
push bp
mov bp,sp
push bx
push cx                   
push si
push dx
push ax 
xor ax,ax
mov si,[bp+4] 
mov di,[bp+6]
ciclo:
cmp [si],di
je trovato
inc bx; per trovare la posizione
inc si
cmp si,0
jne ciclo

trovato:
mov ax,bx ; divido per 2 per lo scambio 
shl ax,1
mov cx,ax
xor ax,ax
xor si,si
xor di,di
mov si,[bp+4]
mov di,[bp+4] 
add di,bx

ciclo1:
mov al,[si]
mov bl,[di]
mov [si],bl
mov [di],al 
inc si
dec di
loop ciclo1

pop ax
pop dx
pop si
pop cx
pop bx
pop bp
ret

inverti endp
end

13 Risposte

  • Re: Passaggio parametri Assembly 8086

    Tra chi devi passare i parametri ?
    tra assembler e assembler o tra assembler e c++.
    se il passaggio dei parametri riguarda 2 programmi assembler
    puoi fare in diversi modi:
    metodo 1:
    Codice: Seleziona tutto
    mov dx,offset array
    xor ax,ax
    mov ax,numero elementi
    push ax
    push dx
    
    ricorda questo metodo va usato se hai un solo segmento dati !
    metodo 2
    Codice: Seleziona tutto
    mov ds,seg array
    mov dx,offset array
    xor ax,ax
    mov ax,numero elementi
    push ax
    push dx
    push ds
    questo sistema va usato se usi più segmenti dati
    ricordati che quando estrai dallo stack i parametri devono essere letti a partire dall'ultimo dato inserito.
    quando estrai i parametri il registro bp serve per "scavalcare" i vari dati che stanno nello stack
    esempio
    bp+0 sta ad indicare la posizione iniziale dello stack che nel assembler 8086 16 bit viene indirizzato dalla coppia di registri sp:bp dove sp e il segmento e bp l'offset.
    bp+2 "scarta" il primo byte contenuto nello stack e quando eseguirai la pop andra' a prendersi i successivi byte
    esempio di ripristino parametri per il metodo 1:
    
    mov ax,@stack 
    mov sp,ax ; io la includo anche se normalmente queste 2 istruzioni vanno ad inizio del sorgente.
    pop dx ;prelevo l'offset dell'array o della stringa che avevo salvato
    pop ax ;prelevo dallo stack il numero di elementi dell'array o il carattere di controllo che avevo salvato
    metodo 1 con scarto di un parametro
    
    mov ax,@stack 
    mov sp,ax ; io la includo anche se normalmente queste 2 istruzioni vanno ad inizio del sorgente.
    mov bp,sp
    add bp,4 ;questo fa si che il primo parametro presente nello stack sia scartato ho usato bp+4 perche un offset e una word se inveve fosse stato un byte avrei dovuto usare bp+2
    pop ax ;prelevo dallo stack il numero di elementi dell'array o il carattere di controllo che avevo
    
    per il repristino dal metodo 2 valgono grosso modo le stesse regole del repristino del metodo 1 so che se vorrai scartare la stringa dovrai fare un bp+8 perche sia segmento che offset sono di tipo word.
    -----------------------------------------------------------------------------------------------------------------
    se invece vuoi scambiare i parametri tra un programma assembler e un programma c++ la procedura più semplice e la seguente:
    nel sorgente c++
    definisci la funzione nel seguente modo:
    extern "C" _int stdcall mia_funzione(int*a,int *b); questa va nel prototipo di funzione
    int c;
    c=mia_funzione(4,5);
    
    nel sorgente assembler
    quando definisci la funzione fai:
    mia_funzione proc Arg1:dword,Arg2:dword
    mov esi,Arg2 ; serve per prendere i parametri
    mov edi,Arg1
    ................
    ................
    push edi
    push esi
    ; adesso se i parametri sono stati modificati dovrai fare usare una ret 8 altrimenti se non sono stati modificati usa una ret 
    spero di esserti stato d'aiuto
    ricordati che in eax sara' contenuto il valore di ritorno della funzione quindi prima della ret impostalo ad un valore a te gradito di solito 0 se la funzione va a bun fine 1 se c'è stato un errore.
  • Re: Passaggio parametri Assembly 8086

    Se ti serve un buon sito sul assembler consulta www.giobe2000.i tratta l'assembler per 8086 in maniera veramente eccelsa.
  • Re: Passaggio parametri Assembly 8086

    Grazieeee mille per la spiegazione e per il sito , gentilissimo ...nel mio caso devo passare da assembler ad assembler l' indirizzo di una stringa e poi un carattere.... per l'indirizzo della stringa posso utilizzare il primo metodo che mi hai spiegato ... per passare invece il carattere si può fare questa cosa:
     
    car equ 'a' ; lo definisco come costante
    mov ax,car ; lo passo in ax e faccio push sullo stack
    push ax
    
  • Re: Passaggio parametri Assembly 8086

    Il codice che passerà i dati sarà
    
        mov ax,@data
        mov ds,ax 
    
        mov ax,car    
        push ax
        lea ax,string 
        push ax
        call inverti
        add sp,4
        
        mov ax, 4c00h
        int 21h  
    
    Considera che dopo il setup del registro ds devi solamente prelevare il carattere e inserirlo nello stack e subito dopo lo stesso per l'indirizzo della stringa. Subito dopo chiami la inverti.
    All'uscita aggiusti lo stack aggiungendo al puntatore il numero di byte utilizzati prima della chiamata (nel tuo caso 2+2 = 4).

    Lo scheletro della funzione sarà
    
        push bp
        mov bp,sp
        
    ... eventuale salvataggio di registri
        
        mov si,[bp+4] 
        mov ax,[bp+6]
    
    ... eventuale recupero di registri
    
        mov sp,bp  
        pop bp  
        ret
    
    Occhio che la routine che hai scritto non mi pare corretta ... il carattere da confrontare è comunque un solo byte e sarà in AL con la mov che ti ho indicato. Devi utilizzare AL per il confronto e non DI (che è a 16 bit).

    In uscita dalla funzione, dato che questa opera "tramite l'indirizzo della stringa", avrai la stringa modificata.

    L'esercizio qui non è molto chiaro. Se la stringa modificata da restituire deve essere DIVERSA da quella originale allora la faccenda cambia.
  • Re: Passaggio parametri Assembly 8086

    Ragazzi siete grandi..non so davvero come ringraziarvi...tornando al programma sto aggiustando quello che avevo fatto fino ad ora....per quanto riguarda la stringa che ne deve uscire fuori per spiegarmi meglio faccio un esempio...se la stringa originale è "assembly" e il carattere di controllo è 'm' dovrebbe uscire fuori "messa" (o almeno è questo quello che ho interpretato io dalla traccia) quindi ho pensato che dovrei definire un' altra stringa e passare anche il suo indirizzo alla procedura..ora visto che devo invertire questi caratteri a mano a mano li posso andare ad inserire nella nuova stringa (magari con un contatore prendere la sua lunghezza)e poi all' uscita della procedura inverti..potrei fare una procedura di stampa ..questa è l'idea che mi è venuta non so se è fattibile...che ne dici? :S
  • Re: Passaggio parametri Assembly 8086

    Quindi i parametri devono essere 3, in pratica la funzione inverti sarò chiamata così

    inverti (indirizzo_stringa_in_ingresso, indirizzo_stringa_in_uscita, carattere)

    e dunque con 6 byte da aggiustare all'uscita
    
        mov ax,@data
        mov ds,ax 
    
        mov ax,car    
        push ax
        lea ax,string_out
        push ax
        lea ax,string_in
        push ax
    
        call inverti
        add sp,6
        
        mov ax, 4c00h
        int 21h  
    
    e nella funzione avrai
    
        mov si,[bp+4]     ; puntatore alla stringa in input
        mov di,[bp+6]    ; puntatore alla stringa in output
        mov ax,[bp+8]   ; carattere da cercare (in AL)
    
  • Re: Passaggio parametri Assembly 8086

    @smalldragon ... "nel assembler 8086 16 bit viene indirizzato dalla coppia di registri sp:bp dove sp e il segmento e bp l'offset."

    Non è corretto ... il segmento dello stack è SS e quindi la coppia di registri per lo stack è

    SS:SP

    l'offset è in SP.

    Il registro BP è un indice (come SI, DI ...) che però, a differenza degli altri, fa riferimento al segmento SS ... l'indirizzo completo sarà sempre

    SS:BP
  • Re: Passaggio parametri Assembly 8086

    Grazie a tutte le spiegazioni la procedura fa il suo dovere...ora mi è tutto molto ma molto più chiaro grazie mille
    car equ 'o' 
    lung equ 9
    data segment
    string db "cstgnosrf","$" 
    string2 db ?
    ends
    
    stack segment
        dw   128  dup(0)
    ends
    
    code segment
    start:
    mov ax,@data
    mov ds,ax 
    mov ax,car ;[bp+10] 
    push ax  
    mov bx,lung ;[bp+8]
    push bx 
    lea dx,string;[bp+6]
    push dx
    lea ax,string2;[bp+4]
    push ax
    call inverti
    call stampa      
    add sp,8
    
    mov ax,4c00h
    int 21h
         
    inverti proc
    push bp
    mov bp,sp
    push bx
    push cx                   
    push si
    push dx
    push ax 
    
    mov di,[bp+4];stringa di output
    mov si,[bp+6] ;stringa di input
    mov cx,[bp+8];lunghezza 
    mov ax,[bp+10];carattere
    xor bx,bx
    ciclo:
    cmp [si],al;confronta stringa con carattere
    je trovato
    inc bx; per trovare la posizione
    inc si
    loop ciclo
    
    trovato:
    inc bx
    mov cx,bx
    mov di,[bp+4];stringa output
    mov si,[bp+6] 
    dec bx
    add si,bx ;punto al caratt trovato
      
    ciclo1:
    mov al,[si]
    mov [di],al 
    dec si
    inc di
    xor al,al 
    loop ciclo1
    
    pop ax
    pop dx
    pop si
    pop cx
    pop bx
    pop bp
    ret
    inverti endp
    ends
    
    stampa proc
        push bp
        mov bp,sp
        push bx
        push cx
        push ax
        push dx   
        mov di,[bp+4]
        
         ciclo2:
        mov ah,02h
        mov dx,[di]
        int 21h
        inc di 
        cmp [di],0
        jne ciclo2  
        
        pop dx
        pop ax
        pop cx
        pop bx
        pop bp
        ret
    stampa endp
    ends
    

    L' unico dubbio che mi rimane sta nel passaggio della lunghezza alla procedura di stampa come potrei...io ho utilizzato cmp [di],0 volendo sarebbe corretto passare la lunghezza in cx con un mov cx,bx? dove in bx dalla procedura inverti ho la lunghezza...cioè volendo posso passare un valore da una procedura all'altra oppure le procedure devono essere indipendenti tra loro? e tutto deve essere passato dal programma chiamante...non so se mi sono spiegata :p
    grazieeee infiniteee
  • Re: Passaggio parametri Assembly 8086

    Le procedure devono ricevere gli argomenti dal chiamante (anche una procedura può essere considerata chiamante se richiama un'altra procedura).

    Occhio a diversi punti ...

    1) la stringa di destinazione deve avere una grandezza, non puoi prevedere un solo carattere perché gli altri saranno scritti in memoria chissà dove e con quali effetti ...

    2) quando passi i parametri tramite push non devi per forza utilizzare registri diversi (ax, bx, ...) ... ne basta uno solo perché quando i dati sono inseriti con la push il registro puoi riutilizzarlo

    3) all'uscita delle proc prima di pop bp *devi* inserire una mov sp,bp come ti avevo detto prima ...
  • Re: Passaggio parametri Assembly 8086

    Grazie grazie per il punto uno dato che prima di chiamare la procedura non conosco la sua lunghezza..posso fare :
    
    car equ 'o' 
    lung equ 9
    data segment
    string db "cstgnosrf","$" 
    string2 db lung dup (?)
    ends
    
    la dichiaro una stringa di 9 elementi per eccesso...perchè al massimo ne potrebbe contenere 9 ...va bene cosi? grazie mille
  • Re: Passaggio parametri Assembly 8086

    @oregon scusa hai perfettamente ragione mi sono confuso
  • Re: Passaggio parametri Assembly 8086

    azzurra_13 ha scritto:


    perchè al massimo ne potrebbe contenere 9 ...va bene cosi?
    Sì, va bene ... importante riservare la memoria in modo che non possa essere "sporcata" una zona utilizzata da altro codice/dato


    @smalldragon .... no problem
  • Re: Passaggio parametri Assembly 8086

    Grazie grazie grazie grazie grazieeeeeeeeeeeeeeeeeeeeee
Devi accedere o registrarti per scrivere nel forum
13 risposte