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

RadASM环境,win32汇编入门教程之六

;运行效果

;RadASM环境,win32汇编入门教程之六
;在上一个教程里面,我们学习了如何定义数据,那么在这一章节里面,我们来学习一下,再说明怎么把这些数据显示出来
;下列就是显示出这些数据的示例程序,可以直接复制下来,然后编译运行看看效果
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.386 
.model flat,stdcall 
option casemap:none 
include      windows.inc 
include      user32.inc 
include      kernel32.inc 
include      gdi32.inc         ;增加的内容

includelib   user32.lib        
includelib   kernel32.lib 
includelib   gdi32.lib         ;增加的内容
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD       
                                                
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.DATA                                   
ClassName           db "SimpleWinClass",0        
AppName             db "窗口程序的模版",0
   
sF db "%d",0
     
hA dd 168 
hD db "世界,你好!",0  
.DATA?                                  
hInstance   HINSTANCE  ?                
CommandLine LPSTR      ?
hB          dd ?
.const;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
; Equ 等值定义
hC          equ 16800                                         
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
.CODE                      

start:                      
invoke GetModuleHandle, NULL                                                    
mov hInstance,eax 
invoke GetCommandLine                                                                                       
mov CommandLine,eax 
invoke WinMain, hInstance,NULL,CommandLine, SW_SHOWDEFAULT        
invoke ExitProcess, eax                                          
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD 
        LOCAL wc:WNDCLASSEX                                          
        LOCAL msg:MSG 
        LOCAL hwnd:HWND 
        
        mov   wc.cbSize,SIZEOF WNDCLASSEX                            
        mov   wc.style, CS_HREDRAW or CS_VREDRAW                     
        mov   wc.lpfnWndProc, OFFSET WndProc                        
        mov   wc.cbClsExtra,NULL 
        mov   wc.cbWndExtra,NULL 
        push  hInstance 
        pop   wc.hInstance 
        mov   wc.hbrBackground,COLOR_WINDOW 
        mov   wc.lpszMenuName,NULL 
        mov   wc.lpszClassName,OFFSET ClassName 
        invoke LoadIcon,NULL,IDI_APPLICATION                          
        mov   wc.hIcon,eax 
        mov   wc.hIconSm,eax 
        invoke LoadCursor,NULL,IDC_ARROW                              
        mov   wc.hCursor,eax 
        invoke RegisterClassEx, addr wc                              
        invoke CreateWindowEx,NULL, ADDR ClassName,ADDR AppName,WS_OVERLAPPEDWINDOW,100,100,400,300, NULL,NULL,hInst, NULL 
        mov   hwnd,eax 
        invoke ShowWindow, hwnd,CmdShow                              
         invoke UpdateWindow, hwnd                                    

        .while TRUE                                                   
                invoke GetMessage, ADDR msg,NULL,0,0 
                .break .if (!eax) 
                invoke TranslateMessage, ADDR msg 
                invoke DispatchMessage, ADDR msg 
        .endw 
        mov     eax,msg.wParam                                         
        ret 
WinMain endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
         LOCAL @stPs:PAINTSTRUCT
         LOCAL @szBuffer[256]:byte 
         LOCAL @hDc
        
         .if uMsg == WM_CREATE                

        .elseif uMsg == WM_PAINT       
                invoke BeginPaint,hWnd,addr @stPs
                mov    @hDc,eax 
                ;下面显示168
                invoke wsprintf,addr @szBuffer,addr sF,hA           
                invoke lstrlen,addr @szBuffer
                invoke TextOut,@hDc,100,30,addr @szBuffer,eax       ;显示函数
                ;下面显示1680
                mov hB,1680
                invoke wsprintf,addr @szBuffer,addr sF,hB
                invoke lstrlen,addr @szBuffer
                invoke TextOut,@hDc,100,60,addr @szBuffer,eax
                ;下面显示16800
                invoke wsprintf,addr @szBuffer,addr sF,hC
                invoke lstrlen,addr @szBuffer
                invoke TextOut,@hDc,100,90,addr @szBuffer,eax
                ;下面显示"世界,你好!"
                invoke lstrlen,addr hD
                invoke TextOut,@hDc,100,120,addr hD,eax
                
                invoke EndPaint,hWnd,addr @stPs  
        .elseif uMsg == WM_DESTROY                                           
                invoke PostQuitMessage,NULL                               
        .else 
                invoke DefWindowProc,hWnd,uMsg,wParam,lParam             
        ret 
    .endif 
    xor eax,eax 
    ret 
WndProc endp 
;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
end start   

;在这个示例里面,我们显示4个东西,分别是数字168、1680、16800和字符串"世界,你好!"
;首先,需要增加1个头文件和库文件,就是上面添加的
include      gdi32.inc
includelib   gdi32.lib
;这些文件里面定义了一些基本的数据结构之类的,就是微软公司先把一些最基础的定义好了,后面就可以直接调用一些函数。
;经常编译不过的时候,提示没有定义某个函数之类的,往往就是缺少了这些头文件。gdi32文件是关于一些绘画的函数。

;先看这句: hA dd 168 ,这就是定义一个叫hA的4字节数字168,hA是名称,dd是dword的简称,即4字节,就是32位的意思,因为每个字节是8位
;可不可以定义成hA db 168 呢,也可以,这样定义的话就是定义1个单字节的值。但很少这样做,因为后面调用的函数参数基本是32位的,如果定义成1个字节的话
;后面要转成32位的值,还要保证高位字节都是零,才能当做参数调用函数,所以默认的都是定义成dd类型。
;上面有个单词 .DATA,这个指的是数据区,设定初值的数据放在这个区里面。

;看第2个定义:  hB dd ?
;它放在 .DATA? 这里,这是未初始化的数据区,就是先定义,不赋值先。

;看第3个定义:  hC equ 16800 
;它放在 .const ,这个是固定数据区,就是放在这儿的是不能改变的数据。这里用了一个命令equ,它是等同的意思。就是说hC就是16800,但不能说16800就是hC,因为在程序中或程序运行中,可能也会产生16800的值。

;看第4个定义: hD db "世界,你好!",0 
;它放在 .DATA,即放在数据区,是设定了初值的,在程序中也可以改变
;它是定义1个字符串,db是dword byte的缩写,就是4字节作为地址值。我们需要这样理解,hD并不等于这个字符串,而是这个字符串的地址,也叫指针值。

;后面研究一下,在窗口函数WndProc中有哪些内容
;先定义1个名叫@stPs的PAINTSTRUCT结构变量,这个名字@stPs随便取的,一般约定成俗的局部变量前面加@而已。
;那什么叫局部变量,局部变量就是在函数运行期内,它是有效的,离开函数时就被电脑收回了。
;那什么时候离开?当程序运行时,走到最后一个命令ret,就是返回上一层,即调用它的那一层,就是离开了这个函数了。
;像@stPs这个变量,它定义在WndProc函数内,当WndProc函数运行完,返回上一层后,它就不能再被其它的函数调用了,不能再使用了。

;PAINTSTRUCT这个结构是什么东西,看它的字面意思就知道,它是画的结构
;简单地说,就是重新画这个窗口时,根据这个结构内的设定值重新画它。
;为什么要重画它?
;很多情况要重画,比如里面要显示的内容发生变化,或最小化状态恢复原状,或被其它窗口挡住又恢复了等等。
;具体的我们以后再研究,这里可以先定义,当然,只是定义,结构内的成员还没有实际值的。

;@szBuffer是准备中转用的字符串数组的变量。因为前面定义的像hA,hB,hC是数值,不是字符串,后面在显示前要转化为字符串才行。
;我们要知道,数值是不能直接显示出来的,就算你看到窗口上写着123之类的这些东西,它并不是数值,而是字符串。
;就像你拍了一张文档,看起来是文字,但其实它是相片。

;@hDc是为后面储值用的变量,也可以这样写 @hDc:dword,只是后面的dword省略了,后面没有像:dword这样或类似的类型说明的,都是默认为dword型,即4字节型。

;看.elseif uMsg == WM_PAINT 这句,这句的意思是,当要重绘时,要干什么
;就是说,当重绘消息来时,要怎么画这个窗口
;比如电脑刚把程序运行起来,需要重绘
;比如最小化之后又恢复原状,怎么重新画出来,需要重绘等等
;电脑要怎么重绘时,就在WM_PAINT下面找这些代码


;invoke BeginPaint,hWnd,addr @stPs 这句的意思是,得到窗口原来的设定,并把它保存到@stPs里面去。
;就是把窗口有多长,有多宽,要不要在重绘之前,把原来没被挡住的部分保存原样,或者要不要原来显示的擦除掉等等。
;这些具体的我们不用管它,让电脑自已处理。我们要做的就是把我们需要增加上去的内容,告诉电脑,一起画出来。
;这些内容,就是我们想显示的4个东西了。

;mov    @hDc,eax 就是把得到的设定保存起来,可以理解为把这个程序窗口保存下来。后面要显示什么的,告诉电脑,把要显示的东西显示到这个程序窗口上去,而不是其它的程序窗口。

;invoke wsprintf,addr @szBuffer,addr sF,hA 这句的意思是,因为hA是个数字,不能直接显示,要先通过格式化函数wsprintf把hA转化为字符串,并保存到@szBuffer里面去。
;invoke lstrlen,addr @szBuffer 这句的意思是,得到@szBuffer这个字符串的长度,后面紧跟着的eax就是这个函数的返回值,即字符串的长度
;invoke TextOut,@hDc,100,30,addr @szBuffer,eax 这句的意思是在坐标为100.30的地方把字符串@szBuffer显示出来,坐标从左上角开始算。

;显示1680时,因为前面是未初始化的,就是没有给定值的,所以这里要赋值给它。mov hB,1680
;显示16800时,前面也相当于初始化了,所以同样操作进行显示。
;而显示"世界,你好!"时,因为它是已经初始化了的,且定义的是字符串,所以可以直接使用函数TextOut把它显示在窗口上。

;invoke EndPaint,hWnd,addr @stPs  这一句的意思是,在指定窗口中标记绘制的结束
;BeginPaint与EndPaint是配对出现在,在它们的之间是重绘的内容。

;以上是显示数字或字符串的示例,当然,仅仅是显示了内容。
;看起来还是不太好看,还有一些东西可以改变,比如字体、字体大小、前景色或文本色等。这些我们在下一个教程里再学习。

相关文章:

  • HDFS应用-后端存储cephfs-java-API
  • qt实现文字跑马灯效果
  • Windows服务器搭建时间同步服务
  • QT QLineEdit 如何支持文件拖放
  • DeepSeek R1生成图片总结2(虽然本身是不能直接生成图片,但是可以想办法利用别的工具一起实现)
  • Unity Mirror 多房间匹配
  • DeepSeek AI 完全使用指南:从入门到精通
  • CSDN、markdown环境下如何插入各种图(流程图,时序图,甘特图)
  • 线性模型 - Logistic回归(参数学习具体示例)
  • PHP Web 开发基础
  • 什么是网络安全?网络安全防范技术包括哪些?
  • 【DeepSeek-R1】 API申请(腾讯云)
  • 2022年SCI1区TOP:K-means聚类算法KO,深度解析+性能实测
  • 蓝桥杯 Java B 组之哈希表应用(两数之和、重复元素判断)
  • 基于Odoo与IMAX-8工业物联技术的倍捻机智慧运维实施方案
  • Aseprite详细使用教程(9)——渐变工具
  • 电磁兼容(EMC):整改案例(十二)调整PCB叠层设计解决静电问题
  • SpringAI系列 - RAG篇(四) - QuestionAnswerAdvisor
  • 【拥抱AI】GPT Researcher如何自定义配置LLM
  • 纯新手教程:用llama.cpp本地部署DeepSeek蒸馏模型
  • 杭勇已任常州市政协党组成员,此前任常州市委常委、秘书长
  • 赖清德为“临阵脱逃”作准备,国台办:绝不会任“台独”祸首逍遥法外
  • 国台办:民进党当局刻意刁难大陆配偶,这是不折不扣的政治迫害
  • 国内首家破产的5A景区游客爆满,洛阳龙潭大峡谷:破产并非因景观不好
  • 人民日报任平:从汽车产销、外贸大盘看中国经济前景
  • 第十届影像上海博览会落幕后,留给中国摄影收藏的三个问题