汇编invoke和call的关系
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
汇编invoke和call的关系
win32汇编⾥⾯,我们既可以⽤invoke也可以⽤call调⽤⼦程序/函数,不过invoke使⽤简单⽅便,所以绝⼤多数情况我们都⽤invoke。
但是很多⼈只是知道使⽤它,对它却不是很了解。
我以前对这个问题也是⼀直没搞透彻,说实话,之前借的汇编书讲解的实在有些烂,NND 连个上机调试的⽅法都没有。
学东西,找⼀本好书还是蛮重要的。
invoke伪指令其实是MASM为了我们⽅便调⽤API,只是把我们的书写格式简单化了。
当程序编译后,编译器还是会把它汇编成⼏条push语句和⼀条call语句,所以它和先push参数后call的结果是没有差别的。
以两个最简单的HelloWorld为例来⽐较。
;FILE:MSG-A.ASM
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.data
sztitle db 'By Invoke!',0
szctent db 'Hello,zerosoul!',0
.code
start:
lea eax,sztitle
lea ebx,szctent
invoke MessageBox,NULL,ebx,eax,MB_OK
invoke ExitProcess,NULL
end start
;MSG-B.ASM
.386
.model flat,stdcall
option casemap:none
include windows.inc
include user32.inc
includelib user32.lib
include kernel32.inc
includelib kernel32.lib
.data
sztitle db 'By Push!',0
szctent db 'Hello,zerosoul!',0
.code
start:
lea eax,sztitle
lea ebx,szctent
push MB_OK
push eax
push ebx
push NULL
call MessageBox
push NULL
call ExitProcess
end start
这两个HelloWorld的区别就是A程序直接⽤invoke调⽤API,B程序先push参数,然后⽤call函数。
为了保持程序的⼀致性,我都先把参数地址⽤lea eax,sztitle,lea ebx,szctent传⼊了eax,ebx。
然后⽤ml /c /coff MSG-1.ASM,link /subsystem:windows MSG-A.obj,分别编译和连接这两个程序,双击运⾏正常
然后我们把这连个程序分别放到OllyDBG⾥⾯反汇编看看它们的机器码,结果证明他们编译以后的机器码⼏乎是完全⼀样的!
Tips:⽤call调⽤函数后,很多⼈会想到堆栈平衡的问题。
由于我们这⾥⽤的是StdCall,堆栈平衡的⼯作由⼦程序来完成,所以我们调⽤的时候可以不⽤使⽤add ESP,8这样的语句⼿动恢复堆栈。