2016-06-14 53 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(为了保持超总之,虽然在时间我学会了不能用太短的符号,正如当时我很难记得那是什么几天后)。