过程调用如何在汇编程序中工作?

int*_*nt3 8 x86 assembly call function-calls

我刚刚开始修补ASM,我不确定我对程序调用的理解是否正确.

在代码中的某个时刻说有一个过程调用

call dword ptr[123]
Run Code Online (Sandbox Code Playgroud)

并且该过程只包含一个命令,ret:

ret 0004
Run Code Online (Sandbox Code Playgroud)

这个过程调用会产生什么影响,返回值将存储在何处?我在某处读到了一个2字节的返回值将存储在AX中,但当我替换过程调用时

mov AX, 0004
Run Code Online (Sandbox Code Playgroud)

(连同必要的NOP)程序崩溃.

Nat*_*man 12

在x86汇编程序中,ret指令的参数意味着:

RET immediate

返回调用过程并从堆栈中弹出立即字节.

(引自英特尔®64和IA-32架构软件开发人员手册 第2B卷)

所以当你输入:

ret 0004
Run Code Online (Sandbox Code Playgroud)

你告诉CPU在它之后立即返回指令call,并从堆栈中弹出4个字节.如果在调用之前 4个字节压入堆栈,这非常有用.

push eax
call dword ptr[123]
Run Code Online (Sandbox Code Playgroud)

请注意,这与返回值无关.实际上,Assembly中的过程无法指定值是返回值.这都是按惯例完成的.我所知道的大多数编译器都会EAX用来保存返回值,但这只是因为调用函数会在那里得到结果.

所以你的调用代码是:

call dword ptr [123]
mov dword ptr [result], eax
Run Code Online (Sandbox Code Playgroud)

并且返回值4的函数将是:

mov eax, 4
ret
Run Code Online (Sandbox Code Playgroud)