汇编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这样的语句手动恢复堆栈。

汇编invoke和call的关系

时间: 2024-10-07 02:14:32

汇编invoke和call的关系的相关文章

汇编--常用汇编指令与标志位关系

加法指令 ADD (addition) 指令对标志位的影响: CF=1   最高有效位向高位有进位 CF=0   最高有效位向高位无进位 OF=1   两个同符号数相加(正数+正数 或 负数+负数),结果符号与其相反. OF=0   两个不同符号数相加,或同符号数相加,结果符号与其相同. 带进位加法指令 ADC (add with carry) 指令对标志位的影响: CF=1   最高有效位向高位有进位 CF=0   最低有效位相高位无进位 OF=1   两个同符号数相加,结果符号与其相反, O

win32汇编 INVOKE 和 call区别

INVOKE 的语法如下: INVOKE expression [,arguments] expression 既可以是一个函数名也可以是一个函数指针.参数由逗号隔开. INVOKE是编译器支持的伪指令,会检查参数. CALL会直接去栈里取参.   INVOKE最后也会变成 PUSH PUSH ... CALL 的形式 所以最好用invoke 调用函数,编译器会帮你检查参数是否传对.

汇编,寄存器,内存,mov指令

一.代码 和 汇编 和 二进制之间的关系 二.复习一下计算机组成原理的知识 1.寄存器 计算机中有三个存储 32位cpu提供的寄存器有三种类型8位 16位 32位 64位的只是32位的扩展 并且程序大多是32位 以下是32位的8个通用寄存器(有宽度) 2.MOV指令 mov eax ,1(向eax寄存器存1) mov  edx , eax(把edx里面的值存到eax) 例子:  EAX:32位通用寄存器 假如FFFFFFFF   一个F(16进制)化为2进制 1111,也就是4位 所以为什么叫3

golang select

golang的select典型用法 golang 的 select 的功能和 select, poll, epoll 相似, 就是监听 IO 操作,当 IO 操作发生时,触发相应的动作. 示例: ch1 := make (chan int, 1) ch2 := make (chan int, 1) ... select { case <-ch1: fmt.Println("ch1 pop one element") case <-ch2: fmt.Println("

DroidPlugin源码分析Hook过程

插件运行环境初始化过程中我们知道,Hook的初始化是在PluginHelper的initPlugin函数中通过调用PluginProcessManager.installHook来实现的.而在分析DroidPlugin Hook过程之前需要先简单了解一下Java的动态代理. Java动态代理与之相关的一个类Proxy,一个接口InvocationHandler,一个函数invoke他们之间的关系.就通过DroidPlugin 的BinderHook类的部分代码来解释一下他们的关系; abstra

深入理解计算机系统(3.1)------汇编语言和机器语言

<深入理解计算机系统>第三章--程序的机器级表示.作者首先讲解了汇编代码和机器代码的关系,阐述了汇编承上启下的作用:接着从机器语言IA32着手,分别讲述了如何存储数据.如何访问数据.如何完成运算以及如何进行跳转.通过这些步骤,又告诉了我们分支语句.循环语句是怎么完成的,函数调用.栈帧结构以及递归过程.最后能通过编译器产生的汇编代码表示,我们要了解编译器和它的优化能力,知道编译器能为我们完成哪些工作. 而这篇博客我们将讲解汇编和机器代码的关系.首先下面一张图是C语言.汇编语言以及翻译过的机器语言

20155232 《信息安全系统设计基础》课程总结

20155232 <信息安全系统设计基础>课程总结 每周作业链接汇总 第一周作业:学习课本第一章和第七章内容--预处理 编译 汇编 链接 四者的关系和具体用法,并且对每章提出问题 第二周课堂实践补充:gcc测试gdb测试,静态库,共享库的测试,myod实现. 第三周学习总结:学习第二章 主要内容就是信息的表示和处理,信息的存储,16进制表示法,寻址,c语言中的运算以及数据的表示. 第四周学习总结以及课上myod练习补充博客 本周学习第十章和附录A--系统编程错误处理的方式:掌握Unix/Lin

同步机制

什么是同步机制? 同步机制 :在并发程序设计中,各进程对公共变量的访问必须加以制约,这种制约称为同步.(引用百度百科,题外话:虽然百度百科并不那么可信,但也是有准确的东西,注意自己甄别就好了.) 为什么需要同步机制? 当计算机只运行一个线程的时候,自然不需要同步.所有的资源都是这个线程独享.那么就不会有任何竞争. 但是当计算机出现了多个线程的时候,那么就出现了各种麻烦,为了处理这些麻烦我们就需要使用一些办法来解决这些麻烦. 多线程引出的麻烦(对资源的竞争导致的出错) : 设想存在A,B两个线程.

C51指针与A51汇编接口之间关系研究

最近在研究单片机C51对汇编的接口问题.char和int等都比较简单,使用寄存器或固定地地址传值都是可以的,具体可以参考keil的C51 user's guide.本篇短文主要重点讨论一下A51下如何遵循C51的接口标准来实现C51的指针.主要原因是,现在用C51的人越来越多,大家都图省事和方便.网上面有关A51的资料少得可怜,知道用汇编来实现代码优化的少之又少.本人是一直坚持用汇编写东西的.在嵌入式领域,很多东西都与硬件有关,多知道点底层东西还是有好处. 使用工具主要为keil,在window