2016-05-05 16 views
2

Ich versuche, einen Scheduler zu schreiben, was wir "Fasern" nennen. Leider bin ich es nicht gewohnt, Inline-Assembly zu schreiben.Inline-Assembly - nutzlose Zwischenkopie Anweisungen

typedef struct { 
    //fiber's stack 
    long rsp; 
    long rbp; 

    //next fiber in ready list 
    struct fiber *next; 

} fiber; 

//currently executing fiber 
fiber *fib; 

So ist die allererste Aufgabe ist - natürlich - eine Faser für die main Funktion zu schaffen, damit es aufgehängt werden kann.

int main(int argc, char* argv[]){ 

    //create fiber for main function 
    fib = malloc(sizeof(*fib)); 
    __asm__(
     "movq %%rsp, %0;" 
     "movq %%rbp, %1;" 
     : "=r"(fib->rsp),"=r"(fib->rbp) 
     ); 

    //jump to actual main and execute 
    __asm__(...); 

} 

Dies wird

movl $24, %edi #, 
    call malloc # 
#APP 
# 27 "scheduler.c" 1 
    movq %rsp, %rcx;movq %rbp, %rdx; # tmp92, tmp93 
# 0 "" 2 
#NO_APP 
    movq %rax, fib(%rip) # tmp91, fib 
    movq %rcx, (%rax) # tmp92, MEM[(struct fiber *)_3].rsp 
    movq %rdx, 8(%rax) # tmp93, MEM[(struct fiber *)_3].rbp 

zu

zusammengestellt Warum diese mov s in temporäre Register nicht kompiliert? Kann ich sie irgendwie loswerden?

Die erste Version dieser Frage hatte asm Ausgabe von gcc -O0, mit noch mehr Anweisungen und Provisorien.

Optimierungen werden nicht ausgeschaltet.

+0

Haben Sie Optimierungen aktivieren? – Jester

+0

@Jester Ich hatte es zunächst nicht, aber wenn ich sie einschalte, werden die Provisorien nicht gelöscht (siehe oben). – User1291

+0

C unterstützt nicht _methods_ – Olaf

Antwort

3

drehen sie auf wird nicht der Provisorien befreien

Es hat einige zusätzliche Lasten und speichert loszuwerden. Die fib ist natürlich noch in Erinnerung, da Sie dies als globale Variable deklariert haben. Der rax ist der Rückgabewert von malloc, der dem fib im Speicher zugewiesen werden muss. Die anderen zwei Zeilen schreiben in Ihre fib Mitglieder, die auch benötigt werden.

Da Sie Registerausgänge angegeben haben, kann der asm-Block nicht direkt in den Speicher schreiben. Das ist einfach, mit einem Speicher-Einschränkung zu beheben, obwohl:

__asm__(
    "movq %%rsp, %0;" 
    "movq %%rbp, %1;" 
    : "=m"(fib->rsp),"=m"(fib->rbp) 
    ); 

Dies wird erzeugen:

call malloc 
    movq %rax, fib(%rip) 
    movq %rsp, (%rax) 
    movq %rbp, 8(%rax) 
+0

Sie sollten wahrscheinlich verwenden '" = rm ", um dem Compiler die Option zu geben. In diesem Fall spielt es keine Rolle, aber wenn Sie Code schreiben, der diese Werte betrachtet, kann der Compiler sie in regs inst behalten eine Laden-> laden. (Obwohl idealerweise wäre es eine Möglichkeit, eine C-Variable auf den Wert von 'rbp' zu setzen, ohne irgendwelche Anweisungen zu verwenden.) Clang trifft manchmal schlechte Entscheidungen, wenn er Einschränkungen mit mehreren Optionen erhält. Überprüfen Sie daher den Code für diesen Fall. (Eigentlich erinnere ich mich nicht an die Details, als ich gesehen habe, wie Klänge schlecht mit GNU C 'asm' Statements umgehen, aber es kann passieren.) –