汇编-调用API

 

Win32API是用堆栈来传递参数的, 调用者把参数一个个压入堆栈, DLL中的函数程序再从堆栈中取出参数处理, 并在返回之前将堆栈中已经无用的参数丢弃。

Win32API调用中要把参数放入堆栈,顺序是最后一个参数最先进栈

invoke语句

invoke伪指令,它的格式是:

注意, invoke并不是80386处理器的指令, 而是一个MASM编译器的伪指令, 在编译的时候由编译器把上面的指令展开成我们需要的4个push指令和1个call指令, 同时, 进行参数数量的检查工作,如果带的参数数量和声明时的数量不符,编译器会报错:

 

 

 

API函数的返回值

有的API函数有返回值, 如MessageBox定义的返回值是int类型的数, 返回值的类型对汇编程序来说也只有dword一种类型, 它永远放在eax中。

如果要返回的内容不是一个eax 所能容纳的, Win32API采用的方法一般是eax中返回一个指向返回数据的指针, 或者在调用参数中提供一个缓冲区地址,干脆把数据直接返回到缓冲区中去。

 

 

函数的声明PROTO

看:https://blog.csdn.net/lm68140318/article/details/134567662?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22134567662%22%2C%22source%22%3A%22lm68140318%22%7D

 

 

 

 

 

 

复制代码
.386
.model flat,stdcall
.stack 4096

ExitProcess PROTO,dwExitCode:DWORD
MessageBoxA PROTO :DWORD,:DWORD,:DWORD,:DWORD
.data
lptext BYTE "消息",0
lpcaption BYTE "标题",0

.code
main PROC
    invoke MessageBoxA, 0, OFFSET lptext, OFFSET lpcaption,0

    INVOKE ExitProcess,0
main ENDP
END  main
复制代码

 

 

通过反汇编看函数调用

源代码:

复制代码
 
.386  
.model flat,stdcall 
option casemap:none
.stack 4096

ExitProcess PROTO,dwExitCode:DWORD  
 
.data   
 
    
 
.code  
 
TestProc Proc dwParam1:DWORD,bwParam1:DWORD
        local loc1:dword ,loc2:dword   ;用local语句定义了2个局部变量:loc1和loc2
                
        mov ebx, dwParam1   
        mov loc1,ebx       
        mov ecx,bwParam1
        mov loc2,ecx
                                        
        ret
TestProc endp
   
 
main PROC   
    
    invoke TestProc,10101010h,202020h
        
 
 
    INVOKE ExitProcess,0  
main ENDP   
END main  
复制代码

 

反汇编后

复制代码
EAX = 003EF884 EBX = 10101010 ECX = 00202020 EDX = 01021005 ESI = 01021005 EDI = 01021005 EIP = 01022046 ESP = 003EF814 EBP = 003EF81C EFL = 00000217 


 
TestProc Proc dwParam1:DWORD,bwParam1:DWORD
01022034  push        ebp                                                 ;保存ebp的值,函数执行完毕后需要恢复这个值
01022035  mov         ebp,esp                                          ;把当前的堆栈指针给ebp,保存esp的值,函数执行完毕后需要恢复这个值
        ;参数在调用函数前已经存入堆栈,从[EBP+8]、[EBP+C]、……开始
01022037  add         esp,0FFFFFFF8h                               ; esp指向参数地址 【在执行第一条指令之前esp指向最右边参数】
        local loc1:dword ,loc2:dword   ;
                
        mov ebx, dwParam1   
0102203A  mov         ebx,dword ptr [dwParam1]  
        mov loc1,ebx       
0102203D  mov         dword ptr [loc1],ebx  
        mov ecx,bwParam1
01022040  mov         ecx,dword ptr [bwParam1]  
        mov loc2,ecx
01022043  mov         dword ptr [loc2],ecx  
                        
        ret
01022046  leave       
        ;相当于执行两条指令
        ;mov esp,ebp   恢复函数调用前的esp【在函数内部不要修改ebp的值】
        ;pop ebp         恢复函数调用前的ebp
01022047  ret         8  
    
    invoke TestProc,10101010h,202020h
0102204A  push        202020h                             ;保存参数,从右向左保存
0102204F  push        10101010h  
01022054  call        TestProc (01022034h)  
        
 
复制代码

 

 

 

 

 

posted @   天子骄龙  阅读(71)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
历史上的今天:
2022-11-24 MFC-VS2019创建win32项目
2022-11-24 MFC对话框之间传递数据
2021-11-24 opencv-invert求逆矩阵
2021-11-24 opencv-transpose转置
2021-11-24 opencv-SVD奇异值分解
2021-11-24 opencv-mean计算均值
2020-11-24 Arduino--防撞模块
点击右上角即可分享
微信分享提示

目录导航