总结win32汇编的前3章

来源:互联网 发布:数据分析师前景 编辑:程序博客网 时间:2024/05/18 02:28

上个礼拜看win32汇编看的很晕,主要水平不够,今天抽空总结了一下

 

.*p/.*    特权
flat        平坦的内存,4G
stdcall
casemap:none    表示区别大小写

.data .data?(在pe中只有描述信息) .stack(flat常常忽略)(其中代码可以执行!)
.code

';'表示注释
'/'表示换行符,有区别于Makefile,/后可以有空格或注释

api
kernel32.dll--系统服务功能,内存管理、任务管理、动态链接等
gdi32.dll--图形设备接口
user32.dll--用户接口,建立窗口、传送消息

invoke 函数名[,参数1][,参数2].....
类似于[push 1,push 2,.....,call funcation]

API的返回值放在eax中,如果返回值多余一个eax中是一个指针(内存或缓冲区地址)

调用api之前要声明
函数名 proto [距离] [语言] [参数1]:数据类型 [参数2]:数据类型
        默认为.model
            默认为.model
                    参数的名称对于编译器来说无用,可省

win32下,to strings 1.ANSII(A) 2.Unicode(W)
            MessageBoxA        MessageBoxB

include name [<name>]
includelib

win32下,函数代码放在dll文件中,导入库中只留有函数懂得定位信息和参数数目等简单信息,这种库文件叫做导入库,一个dll文件对应一个导入库,user32.dll-》user32.lib

masm下标号和变量的命名规范
1.字母、数字、下划线和@、¥、?
2.第一个符号不能是数字
3.长度不超过240
4.不能使用指令名等关键字
5.作用域内唯一

标号:         当前子程序
标号::    全局

@f    只找最近的一个@@
@@
@b    只找最近的一个@@
@@的使用尽量小,不然在以后的维护中容易发生错误

全局变量    定义可以用?预留空间,运行是os复位0(。data?只能用?)
变量名        类型    初始值1.......
变量名        类型    重复数量 dup (1,2......)

只有定义全局变量的类型时,才可以使用缩写(db,dw,dd.....)
byte    db    字节
word    dw    字
dword dd    双字
fword df    三字
qword dq    四字
tbyte dt    十字节BCD码
sbyte        有符号字节
sword        有符号字
wdword    有符号双字
real4        单精度
real8        双精度
real10    十字节

局部变量
local        变脸名1[[重复数量][:类型]],变量2[[重复数量][:类型]]......
                    类型默认为dword(32)
local伪指令必须紧接在子程序proc之后,且要在指令开始之前把局部变量确定下来

push ebp        暂存ebp
mov ebp,esp        因为esp随时都会被用到,所以用ebp作为局部变量的指针
add esp,XXXXXXX    esp+负值,以预留出局部变量的空间
..........        内存以dword对其读写最快,masm下会是2的倍数
leave            1.mov esp,ebp
            2.pop ebp

从局部变量的实现来看,ebp是实现的关键,所以在子程序中修改ebp的结果会很严重

局部变量和全局变量定义时有所不同,os会给全局变量赋值0,局部变量则是随机的

最好的全局变量初始化方法是调用RrlZeroMemory,因为0通常是api参数的默认值

数据结构(汇编)

结构名 struct
字段1    类型    ?
字段2    类型    ?
......

结构名    ends

使用数据结构定义变量的方法
变量名    结构名    <>[<1,2.......>]

1.变量名.结构成员,直接指向逻辑地址    mov eax,stWndClass.lpfnWndProc
2.结构名.结构成员,以变量名为基址加上偏移地址得到逻辑地址   
mov esi,offset stWndClass
mov eax,[esi+WNDCLASS.lpfnWndProc]

3.
mov esi,offset stWndClass
assume esi:ptr WNDCLASS        把esi假定为指向WNDCLASS的结构指针
mov eax,[esi].lpfnWndProc
...

assume esi:nothing        在不用的时候,必须将esi设定为nothing

结构可以嵌套 引用的方式 mov eax,[esi].oldWndClass.lpfnWndProc

变量的“强制类型转化”
类型 ptr 变量名
word ptr bTest

以字节为单位算长度    sizeof    变量名、数据类型、数据结构名
取得变量中的项数    lengthof    same

变量的取地址
全局变量    offset(lea可以写入寄存器,在运行是计算地址)
局部变量    addr    addr会覆盖eax的值
addr 会自动判断全局和局部
全局同 offset
局部 lea eax,以eax为基址计算
所以 addr对局部变量只能用在invoke中

addr会覆盖eax的值,又由于invoke调用参数从右push,所以eax必须在addr的右边

子程序的定义

子程序名 proc [距离][语言类型][可视区域][USES 寄存器列表][,参数:类型]......
        忽略    忽略        默认public     
    local 局部变量列表

    codes

子程序名 endp

不同语言模式的参数传递与子函数回归page95
proto

高级语法最终被翻译为test cmp等比较指令

分支语句    编译器会对分支语句进行很好的优化,但是只有第一条成功匹配后就会跳转。所以有时,会用多条。if语句进行处理
.if 1
...
[.elseif 2]
...
[.elseif 3]
...
[.else]
...
.endif
不要忽视小数点

循环语句
.while 条件
    code
    [.break [.if 条件]]
    [.continue]
.endw


.repeat
    code
    [.break [.if 条件]]
    [.continue]
.until 条件        此处可以用.untilcxz,不过要提前设定ecx
@@以上的高级语法都是多无符号数来说的,要注意判断有符号数时自己取反

代码风格
1.匈牙利表示法
b    byte
w    word
dw    dword
h    headle
lp     point
sz    string end with 0
lpsz    point point to sz
f    float
st    struct

2.补充
全局变量-》    匈牙利
参数-》        _匈牙利
局部变量-》    @匈牙利
内部子程序-》    _匈牙利

书写格式
指令,寄存器小写
equ定义的常量大写
变量、标号大小混写

缩进
变量、标号    不缩进
指令        2个tab
分支        +个tab

就这么多,其实分页管理那块很复杂,要慢慢来

原创粉丝点击