2016-06-14 54 views
-2

我必須交換Registervariables eax,ebx而不創建新的寄存器。不允許使用XCHG,CMPXCHG及其變體。 我試過了,但沒有奏效。我的代碼有什麼問題。異或換換正確的方法?XOR交換組裝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

它確實有效,但您只交換了不是'x'和'y'的寄存器,您可能需要執行'push eax'和'push ebx'。 PS:下次正確使用代碼格式。 PS#2:'ebx'主叫保存寄存器。 – Jester

+0

謝謝你小丑。我不明白如何交換x和y。你能幫我嗎? – Sedem

+1

如果你想在內存中交換x和y,最簡單的事情就是把它們寫出來交換:'mov eax,[x]; mov edx,[y]; mov [x],edx; mov [y],eax'。請注意,'xor'不支持2個內存操作數。 – Jester

回答

2

您的xor swap是有效的,並且運行良好。 它的結果,這是失敗的(顯示原始[x][y]值的打印,忽略換入eax ebx結果,並把它扔了

要麼添加:

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

你的3倍xor塊之後(存儲交換的結果)

或重寫顯示結果的使用EAX/EBX,例如像:

... 

    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 

順便說一句,我會避免使用mov eax, DWORD x語法,因爲不同的裝配可以特別對待。首先,您可以省略DWORD,因爲這對於彙編程序來說很明顯,因爲從eax寄存器的使用情況來看,然後開始使用[x]來引用地址x地址的值,或者對於地址本身引用offset x。所以在你的代碼中,我會寫mov eax,[x],因爲你想加載eax的地址爲x。這樣你的風格將與mov eax,[esi] vs mov eax,esi一致。

,轉而fmt1fmt2你應該使用更有意義的名稱,如fmtxfmty(爲了保持超總之,雖然在時間我學會了不能用太短的符號,正如當時我很難記得那是什麼幾天後)。