2

我正在使用 Visual Studio 并从 C++ 调用程序集。我知道当您将参数传递给程序集时,第一个参数在 ECX 中,第二个在 EDX 中。为什么不先将ECX复制到EAX就不能直接比较两个寄存器?

C++:

#include <iostream>

extern "C" int PassingParameters(int a, int b);

int main()
{
    std::cout << "The function returned: " << PassingParameters(5, 10) << std::endl;

    std::cin.get();
    return 0;
}

ASM:直接比较两个寄存器时会给出错误的值。

.code
PassingParameters proc
    cmp edx, ecx
    jg ReturnEAX

    mov eax, edx

ReturnEAX:
    ret
PassingParameters endp
end

但是如果我这样写我得到正确的值,并且可以直接比较两个寄存器,这是为什么呢?

.code
PassingParameters proc
    mov eax, ecx ; copy ecx to eax.
    cmp edx, ecx ; compare ecx and edx directly like above, but this gives the correct value.
    jg ReturnEAX

    mov eax, edx

ReturnEAX:
    ret
PassingParameters endp
end
4

1 回答 1

5

在您的第一个版本jg中,如果使用 ,您将eax完全按照进入函数时的状态离开(即,我们几乎不知道)。由于返回值通常在 eax 中,因此无论何时获取它都会给出未定义的返回jg值。换句话说,你写的大致是这样的:

int PassingParameters(int a, int b) { 
    if (a < b)
        return a;
}

在这种情况下,如果a==b,或a>b,您的返回值是垃圾。

在第二个代码序列中,您将一个值加载到 eax 中。然后,如果 jg 没有被取走,则将另一个值加载到 eax 中。无论哪种方式,返回值将是一个输入参数或另一个(取决于哪个更大)。换句话说,你所拥有的大致相当于:

int PassingParameters(int a, int b) { 
   if (a<b)
       return a;
    return b;
}

PS我还要注意你的代码看起来像x86,根本不是64位代码。对于 64 位代码,您应该使用 RAX、RCX 等,而不是 EAX、ECX 等。

于 2013-01-25T04:16:58.667 回答