当前位置: 首页 > article >正文

win32汇编环境,函数的编写与调用、传值或返回值等

;运行效果

;win32汇编环境,函数的编写与调用、传值或返回值等
;函数在被调用的时候,如果此函数实体在前面,可以不用声明。如果实体在后面,则需要先声明。类似于下面的DlgProc函数,因为它的实体在后面,所以需要在调用之前声明。
;看这一段  DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD   ;对话框窗口函数
;DlgProc是函数名称,proto是说明此函数是私有的,就是本程序可以调用。反之则是public,即是公共类型的,可以让其它外面的程序调用,这个一般写在dll文件里面。
;:DWORD则说明这个参数的类型,即为四字节,32位的值。
;下面为asm文件
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386 
.model flat,stdcall 
option casemap:none 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Include 文件定义
include    windows.inc 
include    user32.inc 
include    kernel32.inc 
includelib user32.lib 
includelib kernel32.lib 
; 自定义函数声明
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
DlgProc proto :DWORD,:DWORD,:DWORD,:DWORD   ;对话框窗口函数声明
AProc   proto                               ;无参数函数声明
BProc   proto :DWORD,:DWORD                 ;有参数函数声明
CProc   proto :DWORD                        ;有参数函数,且参数为指针的声明,看起来体现不出指针的意思,和上面差不多。在汇编的眼中,其实没有什么指针的概念,都是数值,要么是8位的,要么是16位或32位的,就是一串二进制的值。它代表的是什么,由你来决定。
; 数据段;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.data 
DlgName      db "MyDialog",0
szCaption    db "提示",0 
szFormat01   db "得到的数值是 %d",0
szText01     db "ABCDE",0 
.data? 
hInstance HINSTANCE             ? 
.const 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
ICO_MAIN   equ 1000      ;图标
IDB01      equ 11        ;按钮控件标识符 
IDB02      equ 12  
IDB03      equ 13    
; 代码段
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.code 
start:     
        invoke GetModuleHandle, NULL     
        mov    hInstance,eax     
        invoke DialogBoxParam, hInstance, ADDR DlgName,NULL, addr DlgProc, NULL     
        invoke ExitProcess,eax 
DlgProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
        LOCAL   @szBuffer01[256]:byte 
        LOCAL   @szBuffer02[256]:byte 
       
        .if     uMsg == WM_INITDIALOG                 
                        invoke    LoadIcon,hInstance,ICO_MAIN            
                        invoke    SendMessage,hWnd,WM_SETICON,ICON_BIG,eax  
        .elseif uMsg == WM_COMMAND                                                  
                mov eax,wParam                                        
                .if     eax == IDB01
                        invoke AProc                                     ;调用无参函数AProc
                        inc eax
                        invoke  wsprintf,addr @szBuffer01,addr szFormat01 ,eax
                        invoke  MessageBox,hWnd,addr @szBuffer01,addr szCaption,MB_OK
                .elseif eax == IDB02
                        invoke BProc,1,2                                 ;调用有参函数BProc并给参数赋值 
                        inc eax                                          ;eax加1.因为返回值是3,再加1,则结果为4
                        invoke  wsprintf,addr @szBuffer01,addr szFormat01 ,eax
                        invoke  MessageBox,hWnd,addr @szBuffer01,addr szCaption,MB_OK
                .elseif eax == IDB03
                        invoke lstrcpy,addr @szBuffer02,addr szText01    ;这里是多此一举,本来可以直接定义一个全局字符数组,就不用在函数里面要地址传进去又传出来。这里这样做,是为了说明这种逻辑,理解这种意思
                        invoke CProc,addr @szBuffer02                    ;调用函数,把地址值,或者说指针当参数传进去,其返回值也是地址值
                        invoke  MessageBox,hWnd,eax,addr szCaption,MB_OK                
                .endif            
        .elseif uMsg == WM_CLOSE                 
                        invoke EndDialog, hWnd,NULL         
        .else                
                mov eax,FALSE                 
                ret                 
        .endif                 
        mov eax,TRUE         
        ret 
DlgProc endp 

AProc   proc                        ;无参数函数实体,因为前面进行了声明,所以可以放调用的后面  
        mov eax,1                   ;返回值放eax里面。这是默认的,因为很多的时候,在调用此函数时,可能还调用了其它系统内的函数。如果返回值放其它寄存器,会导致混乱,其它的寄存器不一定是空值,可能在使用中。
        ret 
AProc   endp 

BProc   proc A:DWORD,B:DWORD           
        mov eax,A
        mov ebx,B
        add eax,ebx                 ;A是1,B是2,加了后值在eax里,而eax是返回值
        ret 
BProc   endp 

CProc   proc A:DWORD
    mov esi,A                  ;让esi指向A地址的内容
    mov al,byte ptr [esi+1]    ;把第2个字符复制过来再覆盖第1个字符
    mov byte ptr [esi],al
    mov eax,esi                ;把地址给eax,成为返回值      
        ret 
CProc   endp 

end start 

;下面为rc文件内容
#include "resource.h"              //提示缺少该文件,可以在资源里下载
#define    ICO_MAIN    1000    //图标  
#define    IDB01       11         
#define    IDB02       12
#define    IDB03       13

ICO_MAIN    ICON        "Main.ico"

//定义对话框
MyDialog DIALOG 10, 10, 120, 100 
STYLE  DS_CENTER | WS_CAPTION | WS_MINIMIZEBOX | WS_SYSMENU | WS_VISIBLE | WS_OVERLAPPED | DS_MODALFRAME | DS_3DLOOK 

CAPTION "对话框程序模版"
 BEGIN
     PUSHBUTTON      "调用无参函数AProc", IDB01,  10,20,100,14           
     PUSHBUTTON      "调用有参函数BProc", IDB02,  10,40,100,12           
     PUSHBUTTON      "调用带指针参数的函数BProc", IDB03,  10,60,100,14           
END 
 


http://www.kler.cn/a/518692.html

相关文章:

  • PyQt4 的图片切割编辑器
  • RocketMQ优势剖析-集成云原生环境
  • 【知识】可视化理解git中的cherry-pick、merge、rebase
  • Python爬虫基础总结笔记
  • wangEditor富文本编辑器,Laravel上传图片配置和使用
  • Kimi 1.5解读:国产AI大模型的创新突破与多模态推理能力(内含论文地址)
  • 在 Vue 项目中快速引入和使用 ECharts
  • Golang 中除了加锁还有哪些安全读写共享变量的方式?
  • 计算机网络-运输层
  • Golang笔记——GPM调度器
  • 《探秘鸿蒙Next:人工智能助力元宇宙高效渲染新征程》
  • vue2和vue3组件之间的通信方式差异
  • 【C++】特殊类设计、单例模式与类型转换
  • 探秘数据仓库新势力:网络建模
  • 基于微信的原创音乐小程序的设计与实现(LW+源码+讲解)
  • 机器人SLAM建图与自主导航
  • 2025年美赛数学建模B题管理可持续旅游
  • vue3中自定一个组件并且能够用v-model对自定义组件进行数据的双向绑定
  • 如何有效利用数据采集HTTP代理
  • ASP.NET代码审计 SQL注入篇(简单记录)