2016-03-23 4 views
1

Ich versuche, Nasm zu verwenden, um mein Programm zu kompilieren, und ich traf ein Problem über Nasm-Syntax. Eigentlich schreibe ich diesen Code:Nasm, Kann ich Speicherdaten direkt in einer Zeile austauschen?

mov byte [edi],[esi] 

nasm gibt mir nur einen Fehler, sagt

invalid combination of opcode and operands.

Deshalb möchte ich fragen, ob ich direkt Speicherdaten in einer Zeile ohne andere Register austauschen kann als Medien.

+4

In der Regel keine. Aber in diesem speziellen Fall können Sie die 'movsb'-Anweisung verwenden. Siehe Band 2 der Intel-Handbücher. – Michael

+0

@Michael Ich versuche es, aber es schlägt wieder fehl. Verwendet das NASM, um es zu kompilieren? – Liberty

+2

_ "es scheitert" _ ist keine ausreichende Problembeschreibung. Was ist die _exact_ Fehlermeldung, die Sie erhalten, und was ist die _exact_ Codezeile, der der Fehler entspricht? – Michael

Antwort

1

Das von Ihnen verwendete Befehlsformat ist "illegal". Der Prozessor versteht den Wechsel zwischen zwei Speicherorten nicht. Deshalb erhalten Sie einen Fehler. Durch Verwendung des direkten Adressierungsmodus des Registers (unter Verwendung der eckigen Klammern) geben Sie ihm Speicheradressen, die in jedem der aufgelisteten Register (edi, esi) gespeichert sind.

Der Prozessor kann das einfach nicht. Es tut mir Leid. Sie müssen einen anderen Weg finden, um das zu tun, was Sie tun wollen.

Jetzt bewegt sich die Anweisung movsb um ein Byte von der Adresse, auf die esi zeigt, in die Adresse, auf die edi zeigt. Das mag sein, was Sie versuchen zu finden, aber in diesem Fall ist der Code einfach

ohne Parameter. Es wird auch esi und edi inkrementieren oder dekrementieren, abhängig von dem Wert des Richtungsflags (das normalerweise klar ist, so dass es inkrementieren würde).

Sie können den Wiederholungsmodifizierer verwenden, um die Anweisung so oft zu wiederholen, wie durch den in ecx gespeicherten Wert angezeigt wird.

Denken Sie daran, dass die Werte IN edi und esi durch die Anweisung movsb geändert werden. Wenn Sie movsB verwenden, werden sie um eins erhöht oder verringert.

Wenn Sie zwei Werte im Speicher austauschen müssen, können Sie es mit einem zusätzlichen Register tun, wie von einem anderen Benutzer als Antwort auf meine etwas weniger effiziente Methode mit zwei Registern wiesen darauf hin:

mov edx, [edi] 
xchg edx, [esi] 
mov [edi], edx 

Dies tauscht die Inhalte der Speicheradressen, auf die der Inhalt von edi und esi zeigt. Es gibt keinen kürzeren Weg, es zu tun.

+1

Technisch gibt es eine kürzere Methode: 'mov edx, [edi]/xchg edx, [esi]/mov [edi], edx'. Es spart 4 Bytes, kann aber langsamer laufen. – owacoder

+0

@owacoder, das macht Sinn - ich habe meine ursprüngliche Antwort bearbeitet, nachdem ich mich an die movsb-Anweisung erinnert habe, aber deine Antwort ist kürzer als meine ursprüngliche Antwort. – querist

+0

Wenn das Richtungsflag gelöscht wird ([_CLD_] (http://www.felixcloutier.com/x86/CLD.html)), wird es vorwärts/inkrementiert und falls gesetzt ([_STD_] (http: //www.felixcloutier .com/x86/STD.html)) es ist rückwärts/dekrementiert –

Verwandte Themen