2013-04-14 15 views
7

Sto provando a scrivere una libreria di sostituzione libc molto leggera in modo che possa capire meglio l'interfaccia del kernel. Il primo compito è chiaramente ottenere alcuni wrapper di chiamata di sistema sul posto. Sono riuscito a far funzionare da 1 a 3 wrapper di argomenti, ma sto lottando con una varietà di 4 argomenti. Ecco il mio punto di partenza:Vincolare registro r10 in assembly gcc inline x86_64

long _syscall4(long type, long a1, long a2, long a3, long a4) 
{ 
    long ret; 
    asm 
    (
     "syscall" 
     : "=a"(ret) 
     : "a"(type), "D"(a1), "S"(a2), "d"(a3), "r10"(a4) 
     : "c", "r11" 
    ); 
    return ret; 
} 

Il compilatore mi dà il seguente errore:

error: matching constraint references invalid operand number 

La mia funzione _syscall3 funziona bene, ma pretende molto uso R10 o avere una lista clobber.

Qualche idea?

risposta

0

Presumibilmente poiché nessuna istruzione ha requisiti specifici per il registro r10, la gente di gcc non ha creato un vincolo per questo (dato che i vincoli sono principalmente per le descrizioni della macchina). Se insisti in linea asm, non penso che tu possa fare di meglio che usare un vincolo generico "r" (o "m") e spostarti in r10 (e aggiungerlo all'elenco dei clobber).

5

Non ci sono vincoli per i registri: %r8 .. %15. Tuttavia, più recente (come in gcc-4.x) dovrebbero accettare:

register long r10 asm("r10") = a4; 

quindi utilizzare il vincolo di ingresso: "r" (r10)

questo può richiedere il __asm__ essere qualificato con __volatile__ - Io corro fuori memoria qui, quindi non posso dirti quando questa sintassi è stata resa ufficiale, ecc. Si tratta di un ragionevole riciclaggio della altrimenti inutile parola chiave register.

+2

Ottimo suggerimento. Questa è una caratteristica fantastica che aiuta davvero a mettere a pezzi l'assemblatore in linea di GCC. Ecco la documentazione pertinente: https://gcc.gnu.org/onlinedocs/gcc/Local-Reg-Vars.html – linguamachina