我刚开始修补 ASM,我不确定我对过程调用的理解是否正确。
在代码中的某个位置说有一个过程调用
call dword ptr[123]
该过程仅包含一个命令 ret:
ret 0004
这个过程调用会产生什么影响,返回值将存储在哪里?我在某处读到 2 个字节的返回值将存储在 AX 中,但是当我将过程调用替换为
mov AX, 0004
(连同必要的 NOP)程序崩溃。
我刚开始修补 ASM,我不确定我对过程调用的理解是否正确。
在代码中的某个位置说有一个过程调用
call dword ptr[123]
该过程仅包含一个命令 ret:
ret 0004
这个过程调用会产生什么影响,返回值将存储在哪里?我在某处读到 2 个字节的返回值将存储在 AX 中,但是当我将过程调用替换为
mov AX, 0004
(连同必要的 NOP)程序崩溃。
在 x86 汇编程序中,ret
指令的参数意味着:
RET immediate
返回调用过程并从堆栈中弹出立即字节。
(引自Intel® 64 and IA-32 Architectures Software Developer's Manuals Vol 2B)
所以当你输入:
ret 0004
您是在告诉 CPU 在 之后立即返回指令call
,并从堆栈中弹出 4 个字节。如果您在调用之前将4 个字节压入堆栈,那就太好了。
push eax
call dword ptr[123]
请注意,这与返回值无关。事实上,Assembly 中的过程无法指定一个值是返回值。这都是按惯例完成的。我知道的大多数编译器都会EAX
用来保存返回值,但这只是因为调用函数会期望那里的结果。
所以你的调用代码是:
call dword ptr [123]
mov dword ptr [result], eax
您返回值 4 的函数将是:
mov eax, 4
ret
// possibly there are arguments pushed here
...
call dword ptr[123] // push next OP code offset in the stack and jump to procedure
// procedure
...
ret 0004 // pop offset, set EIP to that offset and decrease ESP by 4
如果我们在调用过程之前将参数压入堆栈,我们还会减少 ESP。
如果有推送的参数,你的程序会因为你没有弹出它们而崩溃。当前过程的返回偏移量将是错误的,因为它将从推送的参数之一中获取一个值作为偏移量。
我不认为返回值存储在寄存器 AX 中