INTERFACCIAMENTO ASSEMBLY - C++ Prof. Marco Solarino
IN COSA CONSISTE Interfacciare l'Assembly con un linguaggio ad alto livello significa utilizzare del codice scritto in linguaggio Assembly all'interno di un'applicazione realizzata con l'altro linguaggio (nel nostro caso il C++).
Funzioni particolari Velocità di esecuzione Compattezza del codice A COSA SERVE Interfacciare l'Assembly con un linguaggio ad alto livello può essere utile per ottenere: Funzioni particolari Velocità di esecuzione Compattezza del codice
Esistono due modalità per realizzare l'interfacciamento Assembly-C++: COME SI REALIZZA Esistono due modalità per realizzare l'interfacciamento Assembly-C++: Interfacciamento interno Interfacciamento esterno
INTERFACCIAMENTO INTERNO Il TurboC++ contiene un assemblatore interno (il BASM, Borland Assembler) che offre un sottoinsieme delle potenzialità del TASM (Turbo Assembler) e ci consente di inserire istruzioni in Assembly nel sorgente scritto in C++ (Assembly inline).
INTERFACCIAMENTO INTERNO Come si fa nel TurboC++ Per invocare il BASM e tradurre l'Assembly si antepone la direttiva asm alle istruzioni interessate: asm MOV AX,1000 Se le istruzioni Assembly sono più di una: asm { Istruzioni Assembly }
INTERFACCIAMENTO INTERNO Attenzione! Dopo la direttiva asm vale come terminazione dell'istruzione anche l'a capo oltre al punto e virgola, quindi l'eventuale parentesi graffa va aperta sulla stessa riga di asm.
INTERFACCIAMENTO INTERNO Limiti Alcuni compilatori non consentono di usare le etichette nell'Assembly inline Non si possono usare macro e procedure In pratica l'interfacciamento interno va usato in casi molto semplici, nei quali si debbano usare poche istruzioni Assembly.
INTERFACCIAMENTO ESTERNO I sorgenti sono almeno due Sorgente *.CPP Eseguibile *.EXE ? Sorgente *.ASM
INTERFACCIAMENTO ESTERNO Generico Compilatore (TurboC++) Sorgente *.ASM *.CPP Oggetto *.OBJ Eseguibile *.EXE LINKER (TLINK) Assemblatore (TASM) Oggetto *.OBJ
INTERFACCIAMENTO ESTERNO Nel TurboC++ File di progetto *.prj Eseguibile *.EXE Sorgente *.ASM *.CPP
INTERFACCIAMENTO ESTERNO Problemi Far capire al compilatore C++ che la funzione Assembly non è nel sorgente *.cpp Rendere visibile al linker la funzione Assembly
INTERFACCIAMENTO ESTERNO Cosa c’è nel cpp Prima di utilizzarla, facciamo capire al C++ che la funzione Assembly è esterna : extern “C” {tipo far nome(parametri);... tipo far nome(parametri);} Per esempio: extern “C” {int far doppio(int x);}
INTERFACCIAMENTO ESTERNO Cosa c’è nell’asm (1) Al nome della funzione va anteposto ‘_’: …o lo facciamo noi _ doppio proc far …o lo facciamo fare al TASM .model small,C
INTERFACCIAMENTO ESTERNO Cosa c’è nell’asm (2) Rendiamo visibile (pubblica) la funzione al linker PUBLIC doppio se abbiamo usato , altrimenti .model small,C PUBLIC _doppio
INTERFACCIAMENTO ESTERNO Cosa non c’è nell’asm Siccome i segmenti dati e stack vengono definiti dal C++, il sorgente *.asm non dovrà contenere le direttive .data e .stack. Dato che il main della nostra applicazione è nel sorgente *.cpp, il sorgente *.asm non dovrà contenere le macro .startup e .exit 0.