Frage zu Register



  • merker schrieb:

    ... Welcher wäre denn der richtige?

    An dieser Stelle gar keiner? Die eckigen Klammern [] teilen ja genug Information mit, dass es sich um eine Adressierungsart handelt. Oder übersehe ich irgendwas 😕
    ptr steht für mich für Zeiger und unter Zeigern verstehe ich Variablen. Diese Variablen enthalten Adressen auf irgendwas, z.B. auf andere Zeiger. Register und Adressbildung in der CPU mit Hilfe von Registern haben doch nichts mit Zeigern zu tun.
    Wenn man auf der Assembler-Ebene einen Zeiger nutzen möchte, muss man erstens wissen, wo sich der Zeiger im Speicher befindet, also seine effektive Adresse, zweitens muss man seinen Inhalt in eines der CPU Register laden, mit dem man Adressen bilden kann. Danach kann man auf die Adresse zugreifen, auf die der Zeiger zeigt.

    merker schrieb:

    Nobuo T schrieb:

    Falls du mal wieder die AT&T vs. Intel diskutieren willst => bitte neuen Thread aufmachen.

    Das hat nichts mit der durchdachten AT&T Syntax zu tun 🙂



  • Kann bitte jemand die Essenz dieses eher verwirrenden Threads zusammen fassen?



  • nachtfeuer schrieb:

    merker schrieb:

    Die Indireke Adressierung kennt weder Basis- noch Indexregister, sondern nur Register. EBX hier als Basis- oder Indexregister zu bezeichnen, hätte nur Bedeutung für den Programmierer. Die CPU kennt beides nicht.

    Das stimmt irgendwie nicht. Würde ich nochmal in den Unterlagen vertiefen. 😉

    In den Unterlagen steht "wirkt wie" und nicht "ist" ein Basisregister. Soll jetzt keine Haarspalterei sein. 🙂

    nachtfeuer schrieb:

    standardmäßig ginge auch noch

    mov qword ptr [bx], 2
    mov tbyte ptr [bx], 2
    

    Es gibt bei MOV keine Variante, die das ermöglichen könnte. Falls das vom Assembler keine Fehlermeldung gibt, dann hat er wahrscheinlich mehrere Befehle hintereinander generiert, um es umzusetzen.

    nachtfeuer schrieb:

    sowas wie *ebx = 2 - meine ich - stiftet in diesem Zusammenhang hier nur Verwirrung, vor allem für jene, die es in selbst in C noch gar nicht so richtig begriffen haben.

    Ja gut, meine "C-like-Syntax" sollte auch nur Pseudocode sein und eher wie eine Gleichung gelesen werden. 🙂

    abc.w schrieb:

    An dieser Stelle gar keiner? Die eckigen Klammern [] teilen ja genug Information mit, dass es sich um eine Adressierungsart handelt. Oder übersehe ich irgendwas 😕

    Streng genommen teilen die eckigen Klammern nur mit, daß es sich bei dem Ausdruck um eine Speicherreferenz handelt. Zwischen den eckigen Klammern steht dann die Art und Weise, wie die EA ausgerechnet werden soll. Davon gibt es ja diverse Varianten.

    Aber es fehlt noch eine eindeutige Größenangabe, was heißt, wieviel Bytes (oder Bits) da hin geschoben werden sollen. ATT macht das klar via Suffix movb, movw, movl, popl 🙂 ,pushl 🙂 . Intel eben via Operator PTR.

    abc.w schrieb:

    ... durchdachten AT&T Syntax ...

    Bei Dir heißt ja "durchdachte Syntax" lediglich, daß der Assembler von sich aus keine Optimierungen vornehmen soll/kann/darf.



  • abc.w schrieb:

    ptr steht für mich für Zeiger und unter Zeigern verstehe ich Variablen.

    Das mag wohl das größte Problem mit PTR sein. Praktisch selbst verursacht. In keiner Unterlage steht, daß PTR die Abkürzung für POINTER sein soll. Beispiel:

    Turbo Assembler Quick Reference Guide schrieb:

    BYTE
    (syntax:) BYTE expression
    Forces address expression to be byte size.

    BYTE PTR
    (syntax:) BYTE PTR expression
    Forces address expression to be byte size

    PTR
    (syntax:) type PTR expression
    Forces address expression to have type size

    Kein Wort von Zeiger. 🙂



  • merker schrieb:

    abc.w schrieb:

    ... durchdachten AT&T Syntax ...

    Bei Dir heißt ja "durchdachte Syntax" lediglich, daß der Assembler von sich aus keine Optimierungen vornehmen soll/kann/darf.

    Nein, durchdacht heißt für mich einfach durchdacht und ich bestreite auch, dass die sogenannten "Optimierungen", die vom Assembler durchgeführt werden, wirklich als Optimierungen zu bezeichnen sind. Das, was man unter "Optimierung" versteht, ist einfach auf die Limitierung der Syntax des verwendeten Assemblers zurückzuführen. Die Entwickler haben gesehen, die Syntax erlaubt keine eineindeutige Unterscheidung, also wird der Befehl irgendwie übersetzt, damit es passt.
    Die Limitierung der Syntax ergibt sich, weil entweder die Syntax zu kompliziert wird, weil alles zu unterstützen wäre zu komplex, oder weil man sich von vornherein auf das eine oder andere Feature verzichtet.
    Soweit ich weiss, unterstützt der MASM Assembler (vielleicht TASM auch nicht 😕 ) keine direkte Adressierungsart mit bekannten Displacements (bitte korrigiert mich, wenn meine Aussage falsch ist, aber es gab hier im Forum mal einen Thread, wo es nicht ging), d.h. so was geht nicht:

    movl $42, 1000
    

    Weil man sich darauf bewusst oder unbewusst verzichtet hatte, gibt es keinen Bedarf, in der Syntax zwischen Konstanten und Displacements zu unterscheiden. Also kein Bedarf, ein $-Zeichen einzuführen (oder ein anderes Zeichen). Nun hat sich in der Syntax eine Lücke ergeben, die man mit einem "mov , OFFSET" gestopft hatte. Damit hat man noch eine Verzerrung der Begriffe Offset und Displacement eingebaut: Offset ist nun ein Begriff für Displacement. Das ist für mich nicht durchdacht. Wenn durchdacht, dann:

    movl variable, %eax    # Lade den Inhalt der Variable in eax
        movl $variable, %eax    # Lade das Displacement der Variable als Konstante in eax
        movl 1000, %eax    # Lade den Inhalt der Speicherzelle mit der Adresse 1000 in eax
        movl $1000, %eax    # Lade die Konstante 1000 in eax
    

    Also alles durchdacht einheitlich...

    merker schrieb:

    abc.w schrieb:

    ptr steht für mich für Zeiger und unter Zeigern verstehe ich Variablen.

    Das mag wohl das größte Problem mit PTR sein. Praktisch selbst verursacht. In keiner Unterlage steht, daß PTR die Abkürzung für POINTER sein soll.

    Toll, wofür steht es denn 😕
    Eine weitere Verzerrung der Begriffe 😕



  • abc.w schrieb:

    Wenn durchdacht, dann:

    movl variable, %eax     # Lade den Inhalt der Variable in eax
     movl $variable, %eax    # Lade das Displacement der Variable als Konstante in eax
     movl 1000, %eax         # Lade den Inhalt der Speicherzelle mit der Adresse 1000 in eax
     movl $1000, %eax        # Lade die Konstante 1000 in eax
    

    Also alles durchdacht einheitlich...

    Kannst Du mal für diese vier Befehle die generierten Opcodebytes posten?

    abc.w schrieb:

    Nein, durchdacht heißt für mich einfach durchdacht und ich bestreite auch, dass die sogenannten "Optimierungen", die vom Assembler durchgeführt werden, wirklich als Optimierungen zu bezeichnen sind.

    Konsequenterweise dürfte dann der Assembler nicht selbstständig festlegen, ob bei einem Sprungziel auch ein "kurzer" (also +/- 126 Bytes) reichen würde. 🙂

    abc.w schrieb:

    Toll, wofür steht es denn 😕

    PTR steht für PTR. Das soll jetzt wirklich kein Witz sein.



  • merker schrieb:

    Kannst Du mal für diese vier Befehle die generierten Opcodebytes posten?

    Ja, gerne. Die Datei tmp.s:

    .global _start
    
    .section .data
    
    variable: .long 0x12345678
    
    .section .text
    _start:
        movl variable, %eax
        movl $variable, %eax
        movl 1000, %eax
        movl $1000, %eax
        ret
    

    Gebaut mit:

    as tmp.s -o tmp.o
    ld tmp.o -o tmp_exe
    

    Ausgabe von objdump:

    tmp_exe:     file format elf32-i386
    
    Disassembly of section .text:
    
    08048094 <_start>:
     8048094:	a1 ac 90 04 08       	mov    0x80490ac,%eax
     8048099:	b8 ac 90 04 08       	mov    $0x80490ac,%eax
     804809e:	a1 e8 03 00 00       	mov    0x3e8,%eax
     80480a3:	b8 e8 03 00 00       	mov    $0x3e8,%eax
     80480a8:	c3                   	ret
    


  • merker schrieb:

    abc.w schrieb:

    Toll, wofür steht es denn 😕

    PTR steht für PTR. Das soll jetzt wirklich kein Witz sein.

    Na gut... dann ist es wohl so 😞



  • Dein Assembler hat optimiert. 🙂 Bei "movl variable, %eax" hat er die "A1-Variante" von MOV genommen, die nur mit EAX funktioniert, aber nicht mit den anderen Registern.

    Könntest Du mal "Displacement" im Zusammenhang mit (globalen) Variablen näher erläutern?



  • merker schrieb:

    Dein Assembler hat optimiert. 🙂 Bei "movl variable, %eax" hat er die "A1-Variante" von MOV genommen, die nur mit EAX funktioniert, aber nicht mit den anderen Registern.

    Stimmt... aber das fällt in die Kategorie "die Syntax wird zu kompliziert, weil alles zu unterstützen wäre zu komplex" und nicht, weil "man auf ein Feature verzichtet".

    merker schrieb:

    Könntest Du mal "Displacement" im Zusammenhang mit (globalen) Variablen näher erläutern?

    Was meinst Du genau? Die Variablen werden ähnlich wie Sprungmarken deklariert und bekommen nach dem Linken eine eindeutige Adresse. Greift man auf diese Adresse zu, wird diese übersetzt in das, was man bei den Adressierungsarten (laut Intel-Konvention 😕 ) als Displacement bezeichnet... so verstehe ich das...



  • Erhard Henkes schrieb:

    Kann bitte jemand die Essenz dieses eher verwirrenden Threads zusammen fassen?

    Es geht um eckige Klammern Erhard...
    Falls du wirklich verwirrt bist, dann kannst du dich freuen, denn der kleine interaktive Asm-Einführungskurs, den ich plane, ist bald fertig. 😉


Anmelden zum Antworten