精易模块中的汇编调用子程序
16行,这里为什么要从栈上弹出124字节,参数总计16个,这个是怎么计算的,每个参数不是占用4字节吗
是不是只要使用了push指令,就需要对应的pop指令,或着leave来恢复栈针
资料:[backcolor=rgba(27, 31, 35, 0.05)]stdcall 调用约定
在 stdcall 调用约定中,函数的参数从右到左依次压入栈中。被调用的函数负责在返回之前清理栈上的参数。这意味着,当函数执行完毕后,它会使用 ret 指令并附带一个立即数来弹出所有由该函数压入的参数。这个立即数通常等于所有参数所占用的总字节数
00000000 56 push esi:将esi寄存器的值压入栈中。esi通常用于字符串和数组操作中的索引或指针。 00000001 BE0F000000 mov esi,0xf:将值0xf(即15)移动到esi寄存器中。这里esi可能被用作循环计数器或数组索引。 00000006 8D4D08 lea ecx,[ebp+0x8]:将ebp+0x8的地址加载到ecx寄存器中。ebp是基指针寄存器,常用于访问栈上的局部变量,这里[ebp+0x8]可能是一个指向局部变量的指针或数组的开始。 00000009 8D4CF1FC lea ecx,[ecx+esi*8-0x4]:计算新的ecx值,这里是基于当前ecx值(来自上一步)、esi寄存器的值乘以8(可能是因为数组的每个元素大小是8字节),然后减去4。这通常用于访问数组或结构体的元素。 0000000D 8B4104 mov eax,[ecx+0x4]:将ecx+0x4地址处的值移动到eax寄存器中。这可能是访问一个结构体或数组的特定成员。 00000010 85C0 test eax,eax:进行逻辑与操作来测试eax的值,主要用于设置条件码(如零标志ZF)。 00000012 7402 jz 0x16:如果eax为零(ZF=1),则跳转到地址0x16。 00000014 FF31 push dword [ecx]:将ecx寄存器指向的地址处的值压入栈中。这可能是为了函数调用准备参数。 00000016 4E dec esi:将esi寄存器的值减1,可能是用于循环计数器。 00000017 83E908 sub ecx,byte +0x8:将ecx寄存器的值减去8,这可能是为了移动到数组或结构体的下一个元素。 0000001A 85F6 test esi,esi:再次测试esi的值,设置条件码。 0000001C 75EF jnz 0xd:如果esi不为零(ZF=0),则跳转到地址0xd(即循环回lea ecx,[ecx+esi*8-0x4]这一行)。 0000001E FF5508 call [ebp+0x8]:调用一个函数,其地址存储在ebp+0x8处。这通常是一个局部变量或参数指向的函数指针。 00000021 5E pop esi:从栈中弹出值并存储到esi寄存器中,恢复esi的原始值。 00000022 C9 leave:leave指令是mov esp,ebp; pop ebp的简写,用于恢复栈指针和基指针寄存器到函数调用前的状态。 00000023 C27C00 ret 0x7c:从函数返回,并清理栈上的0x7c(124)字节的参数。这表明函数可能接收了多个参数或使用了较大的栈空间。
|