我刚开始摆弄ASM,我不知道如果我的程序调用的理解是正确的。
说在代码中的某些点有一个过程调用
call dword ptr[123]
并且过程仅由一个命令,保留的:
ret 0004
这将是这个过程调用的效果,将在其中存储返回值? 我什么地方读到的2个字节的返回值将被存储在AX,但是当我更换由程序调用
mov AX, 0004
(连同必要的NOP指令)的程序崩溃。
我刚开始摆弄ASM,我不知道如果我的程序调用的理解是正确的。
说在代码中的某些点有一个过程调用
call dword ptr[123]
并且过程仅由一个命令,保留的:
ret 0004
这将是这个过程调用的效果,将在其中存储返回值? 我什么地方读到的2个字节的返回值将被存储在AX,但是当我更换由程序调用
mov AX, 0004
(连同必要的NOP指令)的程序崩溃。
在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
这一切都依赖于调用约定使用。 我在这里就不重复了维基百科的文章,只是读的定义。
在C调用约定 ,例如,返回值将是EAX / AX / AL。 你的单指令没有一个:这是一个什么都不做的空函数取周围4个字节的参数(可能是单个int)。 由于这是被叫方的责任来清理这个调用约定堆栈,忽略做到这一点,用“MOV AX”更换不能正常工作。
此外,我怀疑你可能有32位汇编进行修修补补,而读一个16位的文件。 这不是一个大问题,但你应该知道的差异。
// 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