027-【X86-汇编语言】-过程--定义与调用[程序实例]

本节用一个实例讲解过程的定义和调用

程序实例

.386
.model flat,stdcall
.stack 4096
ExitProcess PROTO,dwExit:DWORD

.code
SUBP PROC
	MOV EAX,2h
	RET
SUBP ENDP

MAINP PROC
	MOV EAX,1h
	CALL SUBP
	MOV EBX,EAX
INVOKE ExitProcess,0
MAINP ENDP
END MAINP

说明

实例中有两个过程 入口过程 MAINP,MAINP调用了另一个过程SUBP。

单步按钮

之前单步调试使用的逐过程按钮,为了调试过程需要使用逐语句按钮

进入正题

  • 在MAINP的第一条语句打断点,调试执行。先看一下程序加载到内存后反汇编的结果

--- C:\Users\DELL\Desktop\Assembly\026-PROC_AND_CALL\PROC.asm ------------------
	MOV EAX,2h
012A101C B8 02 00 00 00       mov         eax,2  
	RET
012A1021 C3                   ret  
	MOV EAX,1h
012A1022 B8 01 00 00 00       mov         eax,1  
	CALL SUBP
012A1027 E8 F0 FF FF FF       call        SUBP (012A101Ch)  
	MOV EBX,EAX
012A102C 8B D8                mov         ebx,eax  
INVOKE ExitProcess,0
012A102E 6A 00                push        0  
012A1030 E8 06 00 00 00       call        _ExitProcess@4 (012A103Bh)  
--- 无源文件 -----------------------------------------------------------------------

地址【012A101C】是【SUBP】的第一条指令的地址。地址【012A1022】是MAINP的第一条指令的地址。

【EIP】= 【012A1022】正是MAINP第一条指令地址,【ESP】=【0022FDA4】

  • 执行【MAINP】的【MOV EAX,1h】,查看寄存器的变化

【EAX】的值变成了【00000001】是我们用【MOV】指令修改的。【EIP】的值变成了【012A1027】指向了【CALL SUBP】。

  • 执行【MAINP】的【CALL SUBP】,查看寄存器和内存的变化

【EIP】的值变成了【012A101C】,正是【SUBP】第一条指令的地址。【ESP】的值变成了【0022FDA0】说明有一个DWORD数据被推入堆栈。下图是【ESP】指向堆栈地址的值【012A102C】,正是【MAINP】的第三条指令【MOV EBX,EAX】的值

  • 执行【SUBP】的【MOV EAX,2h】,查看寄存器的变化

【EAX】的值变成了【00000002】,【EIP】的值发生了变化,指向了【RET】

  • 执行【SUBP】的【RET】,查看寄存器的变化

【EIP】的值变成了【012A102C】,正是【MAINP】的第三条指令【MOV EBX,EAX】的值。【ESP】的值变成了【0022FDA4】说明有一个DWORD数据抛出,抛出的目的正是【EIP】。至此CALL和RET相互配合,通过使用堆栈来保存地址的方式完成了一次过程调用.


关于【MOV EBX,EAX】

【MAINP】的最后一条语句的目的是将【EAX】的值赋值给【EBX】。本来【MAINP】的目的是将1h赋值给【EBX】,但由于【SUBP】中修改了【EAX】的值,导致最终【EBX】的为2h。这是【MAINP】不想看到的,如何避免此类问题发生,下一节再做介绍

猜你喜欢

转载自blog.csdn.net/patronwa/article/details/89476200