win32汇编
[TOC]
win32汇编
模式定义
定义了程序使用的指令集、互作模式和格式
win32环境中
.386
是必不可少的后面带
p
则是伪指令内存模式
但是主要使用的是
flat
因win32程序只有一种内存模式,flat模式,没有64kb的限制
语言模式
除了在
.model
语句中指定内存模式意以外,还应该指定语言模式- stdcall的参数压栈方式是:从右往左
option
语句
短的定义
数据段
可读可写的已定义的变量
这些数据在
.data
的段中,是已初始化的数据段。.data
的段存放在可执行文件的_DATA字节区内可读可写的未定义的变量
常量
代码段
- 所有的指令都在代码段里面
- 代码段是放在_TEXT的节区中的
简单知识点
注释
在代码前面写”;”,代表注释处理
换行
- 由于程序的某一行过长,不利于阅读时可以使用
\
做换行符
调用API函数
动态链接库(dll)
使用invoke语句
API函数的返回值
返回值保存在
eax
寄存器当中‘返回值都是4个字节。
如果超出4个字节的字符串,这个时候返回的就是指针(32位下的指针是4个字节)
函数声明
使用
proto
距离
win32是4G 的平坦段,无所谓距离
在Win32汇编中,函数定义时使用的距离(distance)是指函数内部的相对偏移量,用于表示函数内部的标签或指令之间的距离。
在汇编语言中,函数通常由一系列的指令组成,每个指令都有一个相对于函数起始地址的偏移量。这个偏移量被称为距离。
对于win32汇编的参数值只有dword一种,也就是说只有4个字节
include语句
包含头文件
包含的两个方式】
include <头文件的名字>
include 头文件的名字
includelib
导入库文件
一般库文件和动态链接库的名字相同,后缀不同
使用lib更像是一个借用,但是使用include是将文件拷贝到程序当中
宏
MB_OK是一个按钮,表示确定
具体的信息可以查vs的字典
在win32汇编里面不需要使用je,jmp等
可以使用if,elseif,else
标号
可以理解为c语言的
goto
为了解决标号名称的浪费可以使用
变量
全局变量
类型
局部变量
通过修改堆栈的指针
esp
来预留需要的空间其实这个和C语言的调用是一样的
使用
local
定义局部变量而且数据必须在代码之前
局部变量的使用
对局部变量的初始化
RtlZeroMemory
这个API函数经行初始化
变量的使用
强制类型转换
变量的尺寸
数据的长度计算
获取变量的地址
使用
lea
解析addr
在有addr的程序中,不用eax
使用子程序
相当于函数
参数的传递和堆栈的平衡
数据结构
- 实现的语法
例子:
实现引用
使用点操作符
使用
assume
伪指令把寄存器预先定义为结构指针
win汇编的高级语法
- 补充了:条件测试,分支和循环等高级语法
条件测试
但是注意条件判断的左边只能是变量,不能为常数;而且两边不能同时为变量,但可以是寄存器
分支语句
下面是格式
循环语句
while语法
使用break 的时候我们记得指出退出的条件
do_while()语法
代码风格
匈牙利命名法
- 格式是类型前缀加上变量说明
类型使用小写字母表示
sz
表示以0结尾的字符串,dw
表示double word
,h
表示句柄常用的前缀
变量名采用的双峰命名法
全局变量和局部变量
代码的书写风格
排版方式
对于指令和寄存器是不区分大小写
但是指令和寄存器等要使用小写字母
而用
equ
等位操作符定义的变量则使用大写的字母变量和标号使用匈牙利表示法
注释和空行
总结的开说我们需要写合适的注释就好了,不要太多但是也不来能没有
代码的组织模式
窗口程序执行过程
使用satrt开始,endsatrt结束,但是需要添加
invoke ExitProcess,NULL
,不然会报错1
2
3
4.code ; 写在代码段
start:
invoke ExitProcess,NULL ;退出程序
end start ;结束详细的过程
PostMassage
和SendMessage
主要是用于消息的转发机制有两个问题
为什么windows调用窗口,直接处理信息不是更简单吗?
窗口程序的解剖
句柄
可以理解为窗口的序号
模块和句柄
得到句柄使用
GetModuleHandle
例子
如果使用的参数是
NULL
那么我们就是调用的是调用者的句柄
创建窗口
注册窗口类
RegisterClassEx
创建窗口类
WNDCLASSEX
的结构各字段的含义建立窗口
建立窗口的函数CreatWindowEx`
下面是使用方法:
第二个参数
IpClassName
就是表明使用的窗口的类型,这里使用自己自定义的窗口第三个参数是
IpWindowName
这个是窗口的名称第十个参数是菜单的句柄
第十一个参数
HInstance
指定窗口所属的层序模块第九个参数
hWndParent
设置父窗口第四个参数
dwstyle
指出需要的风格(预定的值可以查看)
ShowWindow
主要是显示窗口和控制窗口的显示状态
消息队列
一般形式:
当指定没有信息的不在获取cpu时间片
我们使用的是PeekMessage
加上条件判断来控制cpu的时间片的
窗口过程
下面这张图的意思就是说我们不能直接使用DestroyWindow来摧毁窗口。而是我们使用PodtQuiTMessage
来摧毁信息回环机制
关于程序接受信息的顺序
在使用
CreatWindowEx
时发送窗口接收到的信息使用DestroyWindow摧毁窗口的时候发送的信息
大部分的信息都不需要程序自己关心,windows只是尽义务的通知窗口过程而已
下面是程序需要自己关心的
Defwindowproc
信息的默认处理机制
窗口间的消息互发
主要是使用
PostMessage
和SendMessage
类似于
printf
的函数wsprintf
为什么字符串的地址不一样
因为windows对字符串进行了拷贝
在窗口见传递数据
使用
WM_COPYDATA
信息类似于C语言的传址的传参
因为使用的是共享的内存
SendMessage
和PostMessage
的区别
实践性
使用资源
- 程序运行=代码的创建+资源的运行
- 源文件是以
rc
为扩展名的脚本文件
菜单的定义框架
方法
方法一:
方法二:定义的是菜单项之间的分割线
方法三
定义的是子菜单
加载菜单和加速键
菜单项的修改
插入菜单项
修改菜单项
删除菜单项
区别:
添加系统菜单
右键弹出菜单
二级菜单
获取鼠标的位置
菜单窗台的检测
图标和光标
定义
装载图标和光标
通过发送信息
改变窗口的属性然后改变光标的设定
位图
是一种存储方式
linux也是这种
矢量和位图的关系
区分位图,设备无关位图,位图文件
在资源中定义位图
对话框
模态对话框和非模块对话框
相当于特殊的窗口
对话框的创建
tab停留位
就是使用tab经行焦点的转变
使用对话框
创建部分和对话框过程(回调函数)的部分
创建模态对话框
结束模态对话框
创建非模块对话框
两个创建函数的不同
使用子窗口控件
子窗口的控件
定义
通用的使用方法
通过id获取句柄
向控件发送信息
其中的换行符出现了错误
使用单选钮和复选框
使用静态控件
不向对话框发送信息
可以用来构造简单的线条图形
使用文本编辑控件
使用滚动条、
发送信息获取返回