汇编-INVOKE伪指令
INVOKE伪指令, 仅用于32位模式, 能自动将参数压入堆栈并调用过程。INVOKE是CALL指令的简便替代, 因为它用一行代码就能传递多个参数。常规语法如下:
.386 .model flat,stdcall option casemap:none .stack 4096 .data ExitProcess PROTO,dwExitCode:DWORD .code AddTwo Proc dwParam1:DWORD enter 0,0 ;================================ ;=============================== leave ret AddTwo endp main PROC INVOKE AddTwo,6 ;能自动把参数压栈 ;能检查参数的个数是否正确 INVOKE ExitProcess,0 main ENDP END main
通过反汇编看看:
多行书写
参数小于32位时
ADDR返回变量地址
ADDR操作符只能与INVOKE一起使用
ADDR用来传递指针参数
.386 .model flat,stdcall option casemap:none .stack 4096 ExitProcess PROTO,dwExitCode:DWORD .data array DWORD 0001h,00002h,00003h,00004h,00005h theSum DWORD ? .code ArraySum Proc USES esi ecx, ptrArray:PTR DWORD, ;指向数组--数组首地址 szArray:DWORD ;数组大小 mov esi,ptrArray ;数组地址 mov ecx,szArray ;数组大小 mov eax,0 ;将和数置为0 cmp ecx,0 ;是否=0 je L2 ;是就退出 L1: add eax, [esi] ;将每个整数加到和数 add esi, 4 ;指向下一个整数 loop L1 ; L2: ret ;和数在eax中 ArraySum endp main PROC INVOKE ArraySum,ADDR array,LENGTHOF array mov theSum,eax ;保存和数 INVOKE ExitProcess,0 main ENDP END main
ADDR和OFFSET的区别
一、相同点
1、addr 和 offset 操作符都是获得操作数的偏移地址;
2、addr 和 offset 的处理都是先检查处理的是全局还是局部变量,若是全局变量则把其地址放到目标文件中
二、不同点
1、addr 伪操作符,只能用在 invoke 伪指令语句中;
2、offset 伪操作符可以用在任何可能涉及偏移地址的指令(当然包括 invoke 伪指令)并想获取操作数偏移地址的场合中;
3、addr 不能处理向前引用(即 addr 引用的操作数必须在使用 addr 前就得定义或声明),而offset 则能(不管引用的操作数是
4、addr 是运行阶段在堆栈中分配内存空间,offset 是编译阶段由编译器解释。因此,addr 可以处理局部变量而 offset 则不能。
5、addr 如果检查到待处理的变量是局部变量,就在执行 invoke 语句前产生如下指令序列:
lea eax,operand
push eax
总结:为了避免出现错误,建议除在局部变量中引用 addr 操作符外,其它场合使用 offset
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
2023-01-11 MFC运行机制
2020-01-11 python--pathlib--路径操作