mov/add vs lea



  • [edx+eax*1] wieso *1 ?

    Nennt sich Skalierung bzw. Skalierungsfaktor. Davon gibt es *1, *2, *4, *8. (Ein Displacement passt auch noch rein.)

    Damit wird das jeweilige Indexregister multipliziert. Sinnvoll bei Feldzugriffen. Finde gerade keinen Link dazu. 😞

    "[edx + eax*4 - 8]" vs. "-8(%edx, %eax, 4)"
    

    Soweit zur Syntax. 🙂



  • merker schrieb:

    ... Soweit zur Syntax.

    Das ist richtig, aber wie würde man in der Intel kompatiblen Syntax folgende Befehle eingeben:

    movl $42, (%eax)
        movl $42, (, %eax)
    

    eax-Register einmal als Basisregister und einmal als Indexregister 😕



  • mov [eax], 42       ; C6 00 2A
    mov [eax*1], 42     ; C6 00 2A
    

    Aber korrekterweise müsste Skalierung *1 bei einem Index- ohne Basisregister via SIB zusammengebaut werden:

    mov [eax*1], 42               ; C6 04 05 00 00 00 00 2A
    mov [eax*1+000000000h], 42    ; C6 04 05 00 00 00 00 2A
    

    👍



  • Hast du dazu einen Assembler benutzt oder manuell assembliert 😕
    Nach den Kommentaren in diesem Code zu urteilen

    merker schrieb:

    mov [eax], 42       ; C6 00 2A
    mov [eax*1], 42     ; C6 00 2A
    

    stimmt was nicht... beide Befehle erzeugen gleichen Code C6 00 2A...
    Der zweite Codeausschnitt scheint richtig zu sein. Ich hab es mit dem GNU as überprüft 😉
    Aus

    .section .text
    myfunc:
        movl $42, (%eax)
        movl $42, (, %eax)
        ret
    

    wird

    00000000 <myfunc>:
       0:	c7 00 2a 00 00 00    	movl   $0x2a,(%eax)
       6:	c7 04 05 00 00 00 00 	movl   $0x2a,0x0(,%eax,1)
       d:	2a 00 00 00 
      11:	c3                   	ret
    

    Übrigens wollte ich die Konstante 42 als 32-bit Konstante. Als 8-Bit Konstante (wie in deinem Beispiel):

    .section .text
    myfunc:
        movb $42, (%eax)
        movb $42, (, %eax)
        ret
    

    disassembliert:

    00000000 <myfunc>:
       0:	c6 00 2a             	movb   $0x2a,(%eax)
       3:	c6 04 05 00 00 00 00 	movb   $0x2a,0x0(,%eax,1)
       a:	2a 
       b:	c3                   	ret
    


  • Mein (Intel-Syntax-)Assembler hält ein Indexregister mit Skalierung *1 ohne Basisregister für sinnfrei. Darum der gleiche Code im ersten Beispiel.

    Es aber via Syntax trotzdem zu erzwingen, könnte auch sinnfrei sein. 🙂



  • Deswegen sage ich, die AT&T Syntax ist am besten durchdacht, siehe hier: http://www.c-plusplus.net/forum/viewtopic-var-t-is-275053-and-start-is-40.html



  • movb   $0x2a,(%eax)        ; c6 00 2a
    movb   $0x2a,0x0(,%eax,1)  ; c6 04 05 00 00 00 00 2a
    

    Wußte hier der Assembler nicht, daß beide Befehle die gleiche Wirkung haben?

    Oder wurde das durch die Syntax erzwungen? 🙂



  • Das wurde durch die Syntax erzwungen. Ich bin der Meinung, auch wenn beide Befehle gleiche Wirkung haben, darf der verwendete Assembler diesbezüglich keine Entscheidungen treffen. Der Programmierer entscheidet sich für die eine oder andere Variante und der Assembler muss diese "gehorsam" akzeptieren und entsprechend übersetzen. Wenn der Assembler trotzdem solche Entscheidungen trifft, dann ist das eine nicht zu vernachlässigende Limitierung. Das würde ja bedeuten, der Programmierer denkt, er habe mit dem Assembler volle Kontrolle usw., nutzt aber nur eine Teilmenge von dem, was die CPU wirklich kann...



  • Ein klares Statement von Dir. Woraus aber folgt, daß sich ein ATT-Syntax-Assembler niemals weiterentwickeln kann (oder soll). Neue Befehle aufnehmen, das wars dann schon.



  • Ja, der GNU Assembler hat nur eine rudimentäre Unterstützung für Makros, hat ein Paar bekannte Bugs hinsichtlich FPU Operationen, die wahrscheinlich niemals "gefixt" werden wegen der Abhängigkeit zu älteren Compilern und wenn ich es als Laie beurteilen kann, die Weiterentwicklung kann nur mit der Aufnahme von neuen Befehlen stattfinden.
    Aber was wären die "Features" von anderen Assemblern, bei denen man sagen würde, sie wären "weiterentwickelter"...?


Anmelden zum Antworten