为什么我的内联汇编程序不能按预期工作?

时间:2012-02-23 17:22:01

标签: c++ visual-studio-2010 inline-assembly

也许我错过了一些关于功能或其他的东西? 我使用VS 2010。 这是我的代码:

#include <iostream>

void swap (int& a, int& b)
{
     __asm push a
     __asm push b
     __asm pop a
     __asm pop b
     std::cout << "Inline function check: a=" << a << " b=" << b << "\n\n";
}

void main()
{
    int arg1=1, arg2=9000;
    std::cout << "Before swap we have: a=" << arg1 << " b=" << arg2 << "\n\n";
    swap(arg1, arg2);
    std::cout << "After swap we have: a=" << arg1 << " b=" << arg2;
    std::cin.get();
}

2 个答案:

答案 0 :(得分:4)

内联汇编不知道引用,因此您要交换参数而不是它们的值。

引用通常实现为指针,在这种情况下,您交换指针,而不是值。

答案 1 :(得分:3)

当您使用Visual Studio通过引用传递时,编译器会传递引用变量的地址。您的交换实际上是交换传递给交换函数的地址;它实际上并没有交换内容。

为了交换内容,您需要取消引用指针。不幸的是,编译器不允许您直接执行此操作,因此您必须使用寄存器。

这是一个简短的例子。这只是一个示范;如果直接访问堆栈,而不是使用ab,则可以使用更少的指令来交换这两个变量。重要的是要注意只能使用寄存器修改存储器。

void swap(int& a, int& b) {
__asm {
    // Preserve our registers
    push eax 
    push ebx 
    push ecx 
    push edx 
    // Store the address of a in eax and b in ebx
    mov eax, a
    mov ebx, b
    // Store the value of a in ecx and b in edx
    mov ecx, [eax]
    mov edx, [ebx]
    // Swap the values pointed to by a and b
    mov [eax], edx
    mov [ebx], ecx
    // Restore the registers
    pop edx
    pop ecx
    pop ebx
    pop eax
}
}