Einige grundlegende Verständnissprobleme



  • Hallo zusammen
    Ich habe nach wie vor nicht aufgegeben mit dem lernen der Programmiersprache Assembler! 🙂

    Allerdings tauchen halt mit der Zeit immer wieder gewisse Verständnissprobleme auf:

    Arr db 34,45,56
    mov ax,[Arr+1]

    Ok der Assembler kennt ja natürlich die Adresse von Arr, da diese statisch ist

    Aber wieso geht denn dies:
    mov ax,[bp+4]
    Ich meine die Adresse von bp kann der Assembler AFAIK nicht kennen! Müsste man dies nicht so machen:

    mov si,bp
    add si,4
    mov ax [si]

    Versteht mich bitte nicht falsch, ich meine, ich weiss, dass ersteres auch funktioniert, aber ich frage mich halt eben einfach ein wenig warum! 🙂

    Was ist eigentlich genau der Unterschied zwischen mov und lea? Ich meine unter der Befehlsbeschreibung steht immer nur Load Effective Address, doch was bedeutet das?

    Was ist der Unterschied zwischen
    mov ax,bp und lea ax,bp ??

    Meine letzte Frage ist nun, wie ich denn nun eigentlich ein Array durchlaufen kann:

    Arr1 db 32,45,56,67
    Arr2 db 12,78,45,34

    mov ax,[Arr1+cx]
    mov bx,[Arr2+cx]

    hat leider nicht funktioniert, wie kann das denn sonst noch machen?

    So, das waren wieder einmal viele Fragen! Ich hoffe, jemand von euch findet ein wenig Zeit, mir das ein wenig verständlicher zu machen! 🙂

    Lg Ishildur

    P.S.
    Ich verwende NASM, der hat hier und da ein wenig eine andere Syntax...



  • Ishildur schrieb:

    Aber wieso geht denn dies:
    mov ax,[bp+4]
    [...]

    Nein, den Wert von bp kennt der Assembler beim Erzeugen natuerlich nicht - muss er aber auch gar nicht.
    Das ganze laesst sich genau so, wie es da steht, in einen OpCode umsetzen. Dh. die CPU bildet bei der Ausfuehrung dieses Befehls die Adresse, indem sie bp hernimmt und 4 dazu addiert (bp wird dabei letztendlich natuerlich nicht veraendert).
    Stichworte zur Adressierung beim x86 sind in diesem Zusammenhang modr/m-byte fuer 16Bit-Adressierung und zusaetzlich noch das SIB-byte fuer 32Bit Adressierung.
    Praktisch kannst du dir AFAIK aber folgendes merken:
    Direkte Adressierung mit Konstanten klappt immer.
    Indirekte 16Bit-Adressierungen klappen nur mit den Registern bx, si, di und bp.
    Dabei koennen jeweils zu bx oder bp noch si oder di addiert werden, jedoch nicht bx und bp oder si und di. Wahlweise dann zu dem Ganzen noch +/- eine Konstante.
    Also zB. muesste "mov ax, [bx + si + 4]" klappen.

    Indirekte 32Bit-Adressierung klappt mit allen 32Bit-Registern.
    Dabei koennen max. 2 Register (egal welche) addiert werden, einer davon wahlweise mit 2, 4 oder 8 multipliziert. Dazu natuerlich ggF. wieder +/- Konstante.
    zB. "mov ax, [ecx + 2*ecx + MyLabel]"

    Ishildur schrieb:

    Was ist eigentlich genau der Unterschied zwischen mov und lea? Ich meine unter der Befehlsbeschreibung steht immer nur Load Effective Address, doch was bedeutet das?

    Es bedeutet genau das. Also zu gut Deutsch: Lade die effektive Adresse, die das zweite Argument bildet, in das erste.

    Ishildur schrieb:

    Was ist der Unterschied zwischen
    mov ax,bp und lea ax,bp ??

    Praktisch in der Wirkung gibt es bei diesem Beispiel keinen Unterschied. Einige Assembler werden daher das lea letztendlich auch einfach als mov kodieren.
    Die wirkliche Maechtigkeit des lea-Befehls wird erst bei komplizierteren Adressen deutlich.
    zB.
    lea eax, [ebp + 4ecx + 1234]
    Heisst praktisch eax = ebp + 4
    ecx + 1234
    Kann man also entweder zum Vereinfachen von Adressen hernehmen, oder auch um mehrere Rechenbefehle sauber und schnell in einen zu stecken. Das Beispiel da oben vereint zB. auf elegante Weise 4 Befehle in einem (mov, shift und 2 Additionen).

    Ishildur schrieb:

    Meine letzte Frage ist nun, wie ich denn nun eigentlich ein Array durchlaufen kann:

    Arr1 db 32,45,56,67
    Arr2 db 12,78,45,34

    mov ax,[Arr1+cx]
    mov bx,[Arr2+cx]

    hat leider nicht funktioniert, wie kann das denn sonst noch machen?

    16Bit-Adressen kannst du nicht mit cx bilden - siehe oben.



  • OK, alle kapiert 🙂 , bis auf diese Sache mit dem lea:

    Ich habe noch folgenden Link gefunden:

    http://www.i8086.de/asm/8086-88-asm-lea.html

    Also ich kann mit Nasm sowohl:

    mov ax,[MyVar+di]

    sowie auch

    lea ax,[MyVar+di]

    benutzen!

    Kannst du mir ein konkretes Beispiel geben, wo ich lea einsetzen MUSS?!

    Lg Ishildur



  • Ishildur schrieb:

    Also ich kann mit Nasm sowohl:

    mov ax,[MyVar+di]

    sowie auch

    lea ax,[MyVar+di]

    benutzen!

    Ja, ist aber, wie in deinem verlinkten Text schon sehr schoen bemerkt, nicht das gleiche.

    Ishildur schrieb:

    Kannst du mir ein konkretes Beispiel geben, wo ich lea einsetzen MUSS?!

    Nein, gibt es nicht (ausser vielleicht in einigen C++ Inline-Assemblern zum Bestimmen des Offsets lokale Variablen, aber das ist eine andere Geschichte).
    Normalerweise kann man lea immer durch einen oder mehrere andere Befehle ausdruecken.



  • Ach so, OK
    Ich hatte eben nicht gewusst, dass bspw. [bp+5] das + 5 ebenfalls ein Teil des Opcodes ist! 🙂


Anmelden zum Antworten