Zugriff auf lokale Variablen mit dem GCC in Intel-Syntax



  • Weis irgendjemand, wie man bei Inline-Assembler-Code unter GCC auf lokale Variablen zugreifen kann, wenn man auf Intel-Syntax umgestellt hat?
    Also irgendwie sowas

    int main()
    {
      int a=10;
      ...
      asm(
          ".intel_syntax noprefix"
          "mov   eax,a"            // geht nicht
          "mov   eax,[a]"          // geht auch nicht
          "mov   eax,???a???"      // wie dann???
          ".att_syntax noprefix"
      );
      ...
    }
    

    Oh man, der GCC-Assembler frisst echt meine Zeit. Versteh echt nicht warum diese spastische Syntax immernoch verwendet wird. Der Microsoft- und der Borland-Compiler ist da echt weit voraus.



  • Soweit ich weiß, kannste nicht auf lokale Variablen Zugreifen, sondern nur auf globale.

    int a, b;
    
    int main(void)
    {
      asm("mov [_a], 3\n");
      asm("mov eax, [_a]\n");
      asm("mov [_b], eax\n");
      return(0);
    }
    


  • dmesg schrieb:

    Soweit ich weiß, kannste nicht auf lokale Variablen Zugreifen, sondern nur auf globale.

    int a, b;
    
    int main(void)
    {
      asm("mov [_a], 3\n");
      asm("mov eax, [_a]\n");
      asm("mov [_b], eax\n");
      return(0);
    }
    

    Das hab ich auch schon probiert, geht nicht.
    Ok, wenns im Intelsyntax nicht gehen sollte, wie mach ich es dann in der normalen AT&T-Syntax? Z.B. was mach ich hier:

    ...
      int n=10;
      __asm__ ("mov  ???n???, %eax" : bla : bla : bla );
    ...
    

    ???????????????

    Diese Syntax verstehen bestimmt nur die, die GCC programmiert haben!!?!?!??



  • Eine gute Einführung in Inline-Assember mit dem GCC findest du hier: http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html.
    Dein Beispiel, in dem du den Wert aus einer Variable in das Register eax kopierst, sieht dann so aus:

    int main()
    {
     int a = 10;
    
     __asm__ ("movl %0,%%eax" : : "m"(a));
     // ...
    }
    

    Die %0 repräsentiert den ersten von unseren Operanden also a (der zweite wäre %1 usw.). Da die Syntax asm(code : output : input : register); ist, bleibt das Feld für output leer. Unser Input ist die Variable a, die wir mit dem "m" als Memory-Adresse markieren. Ansonsten lohnt es sich bestimmt, auch mal in das verlinkte HOWTO zu schauen.



  • Overflow schrieb:

    Eine gute Einführung in Inline-Assember mit dem GCC findest du hier: http://www.ibiblio.org/gferg/ldp/GCC-Inline-Assembly-HOWTO.html.
    Dein Beispiel, in dem du den Wert aus einer Variable in das Register eax kopierst, sieht dann so aus:

    int main()
    {
     int a = 10;
     
     __asm__ ("movl %0,%%eax" : : "m"(a));
     // ...
    }
    

    Die %0 repräsentiert den ersten von unseren Operanden also a (der zweite wäre %1 usw.). Da die Syntax asm(code : output : input : register); ist, bleibt das Feld für output leer. Unser Input ist die Variable a, die wir mit dem "m" als Memory-Adresse markieren. Ansonsten lohnt es sich bestimmt, auch mal in das verlinkte HOWTO zu schauen.

    Vielen Dank! Das Tutorial hatte ich auch schon mal gefunden, habe es aber nicht geschafft, das obige Beispiel mit dessen Hilfe zum Laufen zu bringen.

    Wenn ich nun aus eax nach a schreiben will, so sollte das doch so aussehen, oder:

    {
      ...
      int a;
      ...
     __asm__ ("movl %%eax", %0  :"m"(a) : );
     ...
    }
    

    Funktioniert aber so nicht. Nur wenn ich das "m"(a) als Input schreibe, funktioniert's (weis bloß nicht, ob es dann auch das richtige macht), es soll doch aber output sein, von eax nach a, oder bezieht sich dieses input und output auf etwas anderes?



  • Von eax nach a müsste so aussehen:

    __asm__ ("movl %%eax,%0" : "=m"(a));
    

    Das = ist notwendig, um den Operanden wirklich als Output zu definieren. Die übrigen Doppelpunkte kann man weglassen, wenn nichts mehr folgt.



  • katana. schrieb:

    Oh man, der GCC-Assembler frisst echt meine Zeit. Versteh echt nicht warum diese spastische Syntax immernoch verwendet wird. Der Microsoft- und der Borland-Compiler ist da echt weit voraus.

    Ohja da muss ich dir aber recht geben! also ich verwende den inline asm eins ms compilers (gott sei dank!) und da gehts so:

    int a=10;
    __asm
    {
       mov a, 0; // <---
    }
    

    vielleicht fehlt ja ein semikolon am ende? sonst fällt mir grad auch nix ein



  • Besser ist

    int main()
    {
    	int foo = 10;
    
    	asm(" ... " : : "a"(foo));
    }
    

    hier wird es dem Compiler überlassen dafür zu sorgen dass foo in eax steht. Entweder er lädt den Wert rein oder er sorgt dafür, dass foo immer in eax steht. Was besser ist entscheidet der Optimizer (der ist aber nur klug bei -O2).

    Wenn das Ziel nur ist, foo in eax zu haben dann geht auch:

    int main()
    {
    	int foo = 10;
    
    	asm("" : : "a"(foo));
    }
    

Anmelden zum Antworten