我是汇编和内存相关内容的初学者。当我们在 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!!!
最佳答案
这是_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
中返回 64 位结果。因此,该函数本质上是对被视为两个 32 位数字的操作数执行长乘法。
让我们用 H1:L1
和 H2:L2
表示操作数,其中 H
表示高 32 位,L
表示低 32 位。那么前两个乘法是 H1*L2
和 H2*L1
。 EDX
中结果的高位部分将被忽略,因为它不适合 64 位结果。最终的乘法是L1*L2
,其中的高位部分与前两个乘法的低位部分相结合。而且 H1*H2
甚至没有尝试过,因为显然它不适合。该函数忽略溢出。
关于delphi - 程序集和 64 位整数 - 从 pascal(delphi 6) 创建?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18062344/