如何做到过程调用汇编工作?(how do procedure calls work in assem

2019-09-22 16:08发布

我刚开始摆弄ASM,我不知道如果我的程序调用的理解是正确的。

说在代码中的某些点有一个过程调用

call dword ptr[123]

并且过程仅由一个命令,保留的:

ret 0004

这将是这个过程调用的效果,将在其中存储返回值? 我什么地方读到的2个字节的返回值将被存储在AX,但是当我更换由程序调用

mov AX, 0004

(连同必要的NOP指令)的程序崩溃。

Answer 1:

在x86汇编的参数到ret指令装置:

RET immediate

返回到调用程序,从栈中弹出直接字节。

(从引用64和IA-32架构软件开发人员手册 卷2B )

所以,当你键入:

ret 0004

你说的是CPU返回指令后立即call ,并弹出4个字节堆栈。 这是伟大的,如果你 4个字节到调用之前堆栈。

push eax
call dword ptr[123]

请注意,这已经无关的返回值。 事实上,在大会过程有没有指定的值是一个返回值的方式。 这一切都是按照惯例进行。 其中的大多数编译器我知道会用EAX来保存返回值,但仅仅是因为调用函数将期望的结果存在这是真的。

所以,你调用的代码将是:

call dword ptr [123]
mov dword ptr [result], eax

和你的函数返回值4将是:

mov eax, 4
ret


Answer 2:

这一切都依赖于调用约定使用。 我在这里就不重复了维基百科的文章,只是读的定义。

在C调用约定 ,例如,返回值将是EAX / AX / AL。 你的单指令没有一个:这是一个什么都不做的空函数取周围4个字节的参数(可能是单个int)。 由于这是被叫方的责任来清理这个调用约定堆栈,忽略做到这一点,用“MOV AX”更换不能正常工作。

此外,我怀疑你可能有32位汇编进行修修补补,而读一个16位的文件。 这不是一个大问题,但你应该知道的差异。



Answer 3:

// 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如果我们先调用程序推参数在堆栈中。


如果有推争论,你的程序崩溃,因为你不弹出他们。 返回当前程序偏移将是错误的,因为它会从的推一个参数得到的值作为偏移。



Answer 4:

我不认为返回值存储在寄存器AX



文章来源: how do procedure calls work in assembler?