ham*_*mid 2 delphi assembly int64
我是汇编和内存相关的东西的初学者.当我们在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
Run Code Online (Sandbox Code Playgroud)
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;
Run Code Online (Sandbox Code Playgroud)
这清楚地表明,在两个PUSH
操作之后,操作数将在[ESP+16]:[ESP+12]
和中找到[ESP+4]:[ESP]
.
在[ESP+8]
你会发现函数的返回地址.
该函数的整个设计依赖于以下事实:MUL
当操作32位操作数时,操作返回64位结果EDX:EAX
.因此,该函数基本上对被视为两个32位数字的操作数执行长乘法.
让我们表示操作数by H1:L1
和H2:L2
where H
表示高32位,并L
表示低32位.然后前两个乘法是H1*L2
和H2*L1
.结果的高位部分EDX
被忽略,因为它不适合64位结果.最后的乘法是将L1*L2
其中的较高部分与前两次乘法的低部分组合.而且H1*H2
是没有尝试,因为显然它不适合.此函数忽略溢出.