您的C代码试图交换指针指向的值,但您的汇编代码似乎将值视为指向segmentation faults
. 处理这个问题的一种方法是使用额外的寄存器来保存指针和它们指向的值。
32 位CDECL允许我们使用EAX 、 ECX和EDX而不用担心保存它们的值。我们需要第四个寄存器,我们必须自己保存它。
我还将假设您希望存在帧指针(可以在没有它的情况下编写例程):
push %ebp
mov %esp,%ebp
push %ebx # Preserve non-volatile EBX register
mov 8(%ebp),%eax # EAX = Pointer to a (arg1)
mov 12(%ebp),%edx # EDX = Pointer to b (arg2)
mov (%eax),%ecx # Temporarily save value at memory address a (*a) to ECX
mov (%edx),%ebx # Temporarily save value at memory address b (*b) to EBX
mov %ebx,(%eax) # Move value of b (EBX) to memory address of a (*a)
mov %ecx,(%edx) # Move value of a (ECX) to memory address of b (*b)
pop %ebx # Restore non-volatile EBX register
pop %ebp
ret
从理论上讲,您可以完全删除堆栈帧(可能会使调试器中的堆栈跟踪更难跟踪)。该代码可以使用ESP而不是EBP来访问参数:
push %ebx # Preserve non-volatile EBX register
mov 8(%esp),%eax # EAX = Pointer to a
mov 12(%esp),%edx # EDX = Pointer to b
mov (%eax),%ecx # Temporarily save value at memory address a (*a) to ECX
mov (%edx),%ebx # Temporarily save value at memory address b (*b) to EBX
mov %ebx,(%eax) # Move value of b (EBX) to memory address of a (*a)
mov %ecx,(%edx) # Move value of a (ECX) to memory address of b (*b)
pop %ebx # Restore non-volatile EBX register
ret
注意:未能保留(每个 32 位CDECL调用约定)非易失性寄存器,如EBX、EBP、ESI和EDI是一个错误。在简单的测试代码中它可能看起来可以工作,但在更复杂的代码中,如果没有严格遵守调用约定,则可能会遇到未定义的行为。