come si fa un subroutine in assembler?

salve a tutti

non ho capito come si fa una subroutine in assembler..

protreste spiegarmelo con un sepmplicissimo esempio con spiegazione

ve ne sarei moooolto grato

perchè oggi il prof ci ha dato le basi ma non ho capito un càzzo

ma proprio un càzzo

ci ha detto che si inizia con proc near e si termina con ret,oppure era endp,non mi ricordo qual'era dei due

solo che non so come si fanno e a cosa servono

se dovete copiare un testo da wikipedia allora non rispondete neanche perchè neanche su wiki non ci ho capito un càzzo!! xD

3 risposte

Classificazione
  • 6 anni fa
    Migliore risposta

    l'assembly è un "non linguaggio", nel senso che è la traduzione letterale di codice macchina, + qualche cosa al contorno che permette di costruire un eseguibile per un certo ambiente.

    ogni processore ha il suo assembly, e poi ogni "ambiente" ha le sue convenzioni necessarie.

    dal punto di vista dell'assembly per sé, qualunque esso sia, una subroutine non è altro che un salto da un punto del codice a un altro, il quale poi è in grado di tornare all'istruzione successiva al salto fatto:

    istruzione 1

    istruzione 2

    salta a subX

    istruzione 3

    ..

    ..

    subX:

    istruzione sub 1

    istruzione sub 2

    .

    .

    ritorna all'istruzione successiva al salto (cioè a istruzione 3).

    questa è una subroutine nuda e cruda, nella sua essenza. come viene realizzata realmente dipende dal processore, e oltre che dal processore può dipendere dal "modello" di memoria usato per cui delle apposite pseudoistruzioni sono date in pasto all'assembler per rendere possibile la generazione del codice corretto.

    oltre a tutto ciò, esistono robe chiamate "calling convention", ma ti interessano solo se vuoi fare subroutine che siano chiamabili dall'esterno, magari da codice C, e ti interessa conoscere qelle del sistema operativo, se vuoi chiamare subroutine si sistema.

    se uno salta queste robacce da anni '80 e va direttamente su codice "serio" moderno, e assembly x86 duro e puro, possiamo tranquillamente ridurre il tutto a questo:

    section .text

    start:

    mov eax, 5

    call subroutine

    xor eax, eax

    ret

    subroutine:

    mov ebx, eax

    ret

    la subroutine è effettivamente una subroutine. tuttavia questo è codice "moderno" che va bene su un modello di memoria "flat" a 32bit (si assembla con nasm, il tuo assembler potrebbe non essere molto d'accordo -- da cui l'importanza di specificare il software usato)

    quando invece non si è tanto fortunati da poter scrivere quel tipo di codice, ... le cose si complicano, e possiamo avere chiamate di due tipi: near e far. il "modo" near (vicino in inglese) fa riferimento al fatto che la subroutine da chiamare è "vicina", cioè nello stesso segmento, per cui può essere chiamata usando un indirizzo a 16 bit (un offset per lo stesso segmento). "far" vuol dire lontano e in tal caso la chiamata deve specificare il segmento e l'offset all'interno di quel segmento.

    tutto ciò potrebbe essere a carico del programmatore, ma nella realtà pratica gli assembler forniscono pseudoistruzioni (cioè istruzioni che non corrispndono a nessuna istruzione singola del processore) che consentono di facilitare le cose, fanno in modo che sia l'assembler a preoccuparsi di certi dettagli, e per esempio sollevano il programmatore x86 16bit l'ingrato compito di dover per esempio sapere usare retn o retf.

    In alcuni assembler

    proc near

    serve proprio a questo: a dire all'assembler di genereare istruzioni adeguate per una chiama "near".

    poi però citi "endp" e mi fai venire in mente un'altra cosa. Prima ho parlato di pseudoistruzioni. Non ci sono solo quelle che permettono di scegliere tra chiamate near e far, ma ci sono anche quelle che permettono di generare del codice "introduttivo" che fa sì che una certa "subroutine" si uniformi a una certa calling convention. Se questo è il tuo caso, la tua subroutine terminerà con una "chiusa" e poi il ret.

    oppure, e forse è qeusto il caso, l'endp serve solo a delimitare la fine della tua subroutine e in tal caso va dopo il ret. Probabilmente la risposta al tuo dubbio è che si termina sia con un ret, che con endp. Ma ricorda che ret è un'istruzione macchina che dice che, una volta eseguita, fa tornare l'esecuzione al punto del salto (all'istruzione successiva), mentre endp è una pseudoistruzione dell'assembly che serve per delimitare la serie di istruzioni che costituiscono il codice della subroutine, una roba del tipo:

    subroutine: proc near

    istr1

    istr2

    istr3

    ret

    endp

    • Accedi per rispondere alle risposte
  • 6 anni fa

    L'Assembly E' un linguaggio poiche' ha le sue istruzioni ( 118 ai miei tempi ), la sua codifica, viene compilato con l'Assembler e genera un file exe che poi con il programma exe2bin viene trasformato in com.

    Le routine in Assembler ( chiamiamolo cosi', e' piu' comodo ) vengono anche utilizzate dai linguaggi ad alto livello per eseguire delle procedure a volte non contemplate nel linguaggio in uso oppure per velocizzare delle operazioni facenti parte del programma.

    Quando il programma ( alto livello ) chiama la routine in assembler questa deve per prima cosa salvare i registri nello Stack con una istruzione Push ed alla fine richiamarli con l'istruzione Pop ma attenzione, bisogna rispettare le posizioni nello stack per ripristinare i registri a fine procedura.

    La chiamata alla routine avviene tramite l'istruzione Call.

    Nei programmi in Assembler l'istruzione proc near significa che la procedura e' contenuta nello stesso segmento di codice al quale appartiene il programma che la ha invocata.

    Lo so che e' complicato ma non si puo' esaurire in 2 parole e cosi' ti faccio un esempio di una routine che scrive errore sullo schermo.

    Essa fa parte di un vecchissimo programma per formattare i floppy disk scritto nel 1990

    Tralascio tutto la parte relativa alla formattazione.

    driverr proc near ;stampa il messaggio di errore

    cls

    locate 1,1

    print errdrive

    ret

    driverr endp

    In pratica se ce' un errore il programma salta alla routine driverr

    call driverr ;esce se la scelta <> a/b

    Ossia se la scelta del drive e' diversa da A o B ( i drive dei floppy ) viene invocata driverr

    ATTENZIONE. Qualcuno obiettera' che print, locate ecc non sono in linguaggio Assembler.

    Certo, fanno parte della libreria display.inc che viene caricata dal programma in fase di esecuzione.e visto che sono buono ti scrivo la print

    print macro stringa ;scrive una stringa sul video

    mov ah,9

    mov dx,offset stringa

    int 21h

    Spero di essere stato abbastanza chiaro.

    Ciao

    Alvin

    Fonte/i: Programmatore a riposo
    • Accedi per rispondere alle risposte
  • Anonimo
    6 anni fa
    • Accedi per rispondere alle risposte
Altre domande? Fai una domanda e ottieni le risposte che cerchi.