Inserire nella libreria condivisa esterna .so anche codice Assembly

Da Gambas-it.org - Wikipedia.
Versione del 25 lug 2015 alle 16:38 di Vuott (Discussione | contributi) (Creata pagina con 'E' possibile inserire in una libreria esterna condivisa .so, da noi realizzata, anche codice ''Assembly'', al fine di ottenere prestazioni ancor più veloci. In particolare s...')

(diff) ← Versione meno recente | Versione attuale (diff) | Versione più recente → (diff)

E' possibile inserire in una libreria esterna condivisa .so, da noi realizzata, anche codice Assembly, al fine di ottenere prestazioni ancor più veloci.

In particolare sono possibili due modalità.


Uso della funzione asm()

Nel semplice esempio, che segue, è possibile vedere come - in via generale - si integra il codice Assembly all'interno del linguaggio C in un sistema a 32-bit:

static unsigned int car asm("raxregistro");
static unsigned int cbr asm("rbxregistro");
 cbr = 15;
 asm("mov rbxregistro,%ax");
 asm("mov %ax,raxregistro");
printf("%d",car);

alla fine, alla riga con printf, la variabile car avrà valore 15.


Problemi di compilazione nei sistemi a 64-bit durante la creazione di una Libreria .so

Si è riscontrato nei sistemi a 64-bit che durante la compilazione, qualora nel codice vi siano una o più variabili, viene restituito il seguente avviso di errore:

relocation R_X86_64_32S against `.bss' can not be used when making a shared object; recompile with -fPIC

Ciò avviene, ad esempio, nel tentativo di compilazione di un codice di questo tipo:

//libprova.c file:

static unsigned int car asm("raxregistro"); 	
static unsigned int cbr asm("rbxregistro"); 	

int prova(int numero) {
 cbr=numero;
 asm("mov rbxregistro,%eax");
 asm("ciclo:");
 asm("dec %eax");
 asm("jne ciclo");
 asm("mov %eax,raxregistro");
 return car;
}

Il problema è nel trasferimento del valore contenuto nelle variabili "raxregistro" e "rbxregistro" alle righe appunto in Assembly:

asm ("mov rbxregistro, eax%");
asm("mov %eax,raxregistro");

e sembra essere legato alle differenze nel codice pic tra i386 e amd64.
Per risolvere il problema è necessario utilizzare uno spostamento relativo di indirizzo; altrimenti si finisce con il codice dipendente di posizione che non funziona per le librerie condivise.
Cosicché, data ad esempio le variabili "raxregistro" e "rbxregistro" in queste righe:

static unsigned int car asm("raxregistro");
static unsigned int cbr asm("rbxregistro");

per richiamarle bisogna usare l'address-relative, così:

asm("mov %eax,raxregistro(%rip)");
asm("mov rbxregistro(%rip),%eax");

Pertanto, l'esempio di codice, sopra mostrato, dovrà - per i sistemi a 64-bit - essere scritto come segue:

static unsigned int car asm("raxregistro"); 	
static unsigned int cbr asm("rbxregistro"); 	

int prova(int numero) {
 cbr=numero;
 asm("mov rbxregistro(%rip),%eax");
 asm("ciclo:");
 asm("dec %eax");
 asm("jne ciclo");
 asm("mov %eax,raxregistro(%rip)");
 return car;
}