2

我是汇编和内存相关内容的初学者。当我们在 reg 中有 int64 值时,mov 运算符如何改变它?我的意思是它不是字符串而是整数。也许我很傻,但我不明白!例如这段代码是做什么的?假设我们在“esp”处有一个 int64 值。

 push       edx
 push       eax
 mov        eax,dword ptr [esp+$10]
 mul        eax,dword ptr [esp]
 mov        ecx,eax
 mov        eax,dword ptr [esp+$04]
 mul        eax,dword ptr [esp+$0C]
 add        ecx,eax
 mov        eax,dword ptr [esp]
 mul        eax,dword ptr [esp+$0C]
 add        edx,ecx
 pop        ecx
 pop        ecx
 ret        8

int64 有 8 个字节,但它的地址是 esp+$10 !!!

4

1 回答 1

5

这是_llmul在问题中看到的非常有用的信息的代码。不管怎样,_llmul是一个在 32 位机器上执行 64 位整数乘法的辅助函数。

该函数的源代码如下所示:

// 64 bit integer helper routines
//
// These functions always return the 64-bit result in EAX:EDX

// ------------------------------------------------------------------------------
//  64-bit signed multiply
// ------------------------------------------------------------------------------
//
//  Param 1(EAX:EDX), Param 2([ESP+8]:[ESP+4])  ; before reg pushing
//

procedure __llmul;
asm
        push  edx
        push  eax

  // Param2 : [ESP+16]:[ESP+12]  (hi:lo)
  // Param1 : [ESP+4]:[ESP]      (hi:lo)

        mov   eax, [esp+16]
        mul   dword ptr [esp]
        mov   ecx, eax

        mov   eax, [esp+4]
        mul   dword ptr [esp+12]
        add   ecx, eax

        mov   eax, [esp]
        mul   dword ptr [esp+12]
        add   edx, ecx

        pop   ecx
        pop   ecx

        ret     8
end;

这清楚地表明,在两次PUSH操作之后,操作数将在[ESP+16]:[ESP+12]和中找到[ESP+4]:[ESP]

[ESP+8]您将找到函数的返回地址。

该函数的整个设计依赖于这样一个事实,即在MUL对 32 位操作数进行操作时,该操作在EDX:EAX. 因此,该函数本质上是对被视为两个 32 位数字的操作数执行长乘法。

让我们用 where 表示操作数H1:L1H2:L2其中H表示高 32 位,L表示低 32 位。那么前两个乘法是H1*L2H2*L1。结果的高部分 inEDX被忽略,因为它不适合 64 位结果。最后的乘法是L1*L2与前两个乘法的低部分相结合的高部分。H1*H2甚至没有尝试过,因为显然它不适合。此函数忽略溢出。

于 2013-08-05T16:10:44.633 回答