2016-06-14 18 views
-2

Ich muss Registervariablen eax, ebx tauschen, ohne ein neues Register zu erstellen. Es ist nicht erlaubt, XCHG, CMPXCHG und ihre Varianten zu verwenden. Ich habe das versucht, aber es hat nicht funktioniert. Was ist das Problem in meinem Code? Ist der XOR die richtige Methode?XOR Swap Assembly NASM

%include "asm_io.inc" 

SECTION .data 

x: dd 10 
y: dd 50 

fmt2: db "Value of myInteger X is %d",10,0 
fmt1: db "Value of myInteger Y is %d",10,0 


SECTION .text 

extern printf 
global asm_main 

asm_main: 

    push ebp 
    mov ebp, esp 



    mov eax, DWORD x 
    mov ebx, DWORD y 

    xor eax, ebx 
    xor ebx, eax 
    xor eax, ebx 

    push DWORD [x] 
    push fmt2 
    call printf 

    push DWORD [y] 
    push fmt1 
    call printf 


    mov esp, ebp 
    pop ebp 
    ret 
+1

Es funktioniert, aber Sie haben nur die Register nicht 'x' und' y', die Sie drucken, vertauscht ... Sie könnten stattdessen 'push eax' und' push ebx' stattdessen tun. PS: beim nächsten Mal Code richtig formatieren. PS # 2: 'ebx' ist Anrufer gespeichert Register. – Jester

+0

danke Spaßvogel. Ich verstehe nicht, wie man x und y eintauscht. kannst du mir bitte helfen? – Sedem

+1

Wenn Sie x und y im Speicher austauschen möchten, ist es am einfachsten, sie auszuwechseln: 'mov eax, [x]; mov edx, [y]; mov [x], edx; mov [y], eax'. Beachten Sie, dass 'xor' nicht mit 2 Speicheroperanden funktioniert. – Jester

Antwort

2

Ihr XOR-Tausch ist gültig und funktioniert gut. Es ist der Druck des Ergebnisses, das (die Darstellung der ursprünglichen [x] und [y] Werte versagt, ohne auf Ergebnisse in eax ebx getauscht und wirft es weg

Entweder fügen.

mov [x],eax 
    mov [y],ebx 

direkt nach dem 3x xor Block (Speicher das Ergebnis von swap)

oder neu schreibt die Anzeige von Ergebnissen eAX/ebx zu verwenden, wie zum Beispiel:.

... 

    xor eax, ebx 
    xor ebx, eax 
    xor eax, ebx 

    ; prepare stack for printf ebx (new y) 
    push ebx 
    push offset fmt1 
    ; prepare stack for printf eax (new x) 
    push eax 
    push offset fmt2 
    ; do printf eax (new x) 
    call printf 
    ; do printf ebx (new y) 
    pop eax 
    pop eax  ; parameters of "printf eax" removed from stack 
    ; here stack points to the previously prepared ebx+fmt1 
    call printf 

BTW, würde ich vermeiden, mov eax, DWORD x Syntax zu verwenden, da verschiedene Assemblers es anders behandeln können. Zuerst können Sie DWORD weglassen, da dies für den Assembler aus der Registerverwendung eax offensichtlich ist, und dann beginnen, [x] für den Referenzwert unter x Adresse oder offset x für Adresse selbst zu verwenden. Also in Ihrem Code würde ich mov eax,[x] schreiben, wie Sie eax mit dem Wert an Adresse x laden möchten. Auf diese Weise ist Ihr Stil konsistent mit Dingen wie mov eax,[esi] vs mov eax,esi.

Und statt fmt1 und fmt2 sollten Sie aussagekräftigeren Namen verwenden, wie fmtx und fmty (zu halten, super kurz, obwohl über die Zeit, die ich nicht zu kurz Symbole gelernt zu verwenden, da dann kann ich kaum daran erinnern, was das war nach ein paar Tagen).