win32 汇编(MASM)
模式定义:
.386
.model flat ,stdcall
option casemap:none
.386 //指令集 伪指令,类似的指令有 .8086/.186/.285/.386/.386p等。
用于告诉编译器在本程序中使用的指令集。
.model flat ,stdcall //工作模式
.model 内存模式 [语言模式] [其它模式]
对于win32只有一种模式,就是flat。没有64k段大小限制。
.model 语句中还应该指定语言模式,即子程序和调用方式。
stdcall 指出了调用子程序或win32API时参数传递的次序和堆栈平衡方式。
其它语言类型如 C,Syscall,BASIC, FORTRAN, PASCALL
option casemap:none //格式
以上的这些并不会在编译好的可执行程序中产生什么东西,它只是一种说明。
真正的数据和代码是定义在各个段中,
告诉编译器中的变量名和子程序名是否对大小写敏感。
.data / .data?/ .const 定义的是数据段,分别对应不同方式的数据定义,
在最后生成的可执行文件,分别放在不同的节区(section).
数据定义可照归纳三类:
1、可读可写的已定义变量。 定义在.data中,__DATA节区
2、可读可写的未定义变量。一般定义在.data?中,当然也可放在.data中
3、一些常量。 使用const声明。
代码存放在.code,_TEXT节区
\ 换行。
invoke 是MASM的伪指令,并不是80386处理器的指令。
invoke 函数名,参数1,参数2.....
声明函数
proto [距离] [语言][参数1]:数据类型,[参数2]:数据类型
距离可以是NEAR ,FAR,NEAR16,NEAR32,FAR16,AKF FAR32.
一个DLL文件对应一个导入库,如user32.dll文件用于编程的导入库是user32.lib
MB_OK使得程序弹出来的时候有个确定的选项。
move cx,1234h
cmp flag,1
je @F //跳到@@
move cx,1000h
@@:
loop @B //跳到前面@@
全局变量在定义中既可以指定初值,也可以只用问号预留 空间,在.data?中
只能用?预留空间,不能指定初始值。
定义局部变量
local local[1024]:byte
local loc2
local loc3:WNDCLASS 定义了一个WNDCLASS的数据结构。
esp在程序的执行过程中随时要用到,ebp是以堆栈段为默认数据段的。
堆栈是向下增长的,esp-8.
szBuffer db 1024 dup(?) //创建一个数组
mov ax,szBuffer
编译器会报错,无效的指令 ax是word ,szBuffer是word.
在MASM中,如果要用指定类型之外的长度访问变量,必须显式地指出要访问的长度,这样
编译器忽略语法上的长度检测,仅使用变量的地址。
使用方法: 类型 ptr 变量名。
用ptr强制覆盖变量长度的时候,实质上是只用了变量的地址而禁止编译器检验。
用movezx指令进行数据长度扩展是win32汇编中经常用到的技巧。
mov 寄存器 offset 变量名
其中offset 是取变量地址的伪操作符,仅把变量的地址带到指令中,
是在编译时完成,而不是运行时。
addr 只能在invoke中使用。
invoke Test ,eax,addr,szHello
编译后
lea eax,[ebp-4]
push eax //参数 2: addr szHello
push eax //参数1 eax
call Test
数据结构 WNDCLASS ,
.DATA?中
stwindowsclass WNDCLASS <>
.DATA
stwindowsclass WNDCLASS <1,1,1,1,1,1,1,1>
使用assume指令,把结构体定义为指针。
rdtsc 取cpu时钟信号 2GHZ,取CUP硬件上面有一个时钟计数器。
寄存器在CPU硬件里面有几个小内存。
比如32位CPU,有DWORD,8个通用寄存器。
寄存器的运算速度>内存>硬盘。
eax 乘法除乘,临时值,用作函数的返回 值。
ecx 通常用作计数器
ebx
edx
edi
esp 缓冲区溢出,栈顶指针
ebp 栈底指针
eip寄存器 始终保持一个地址 ,指向下一条运行的指令。
.model flat,stdcall 内存模式,及调用的约定 。平坦内存模式,0-4 GB都可以访问。
include windows.inc 等同于 #include <windows.h>
includelib gdi32.lib ;等同于#pragma comment(lib,"gdi32.lib")
include macro.asm ;包含一个文件 myctrl.h
qie PROTO 函数的原型申明。
.DATA 常量段, 里边的数据全部是生成在exe中,
.DATA? 里面,数据是没有初始化的,类似于C中的动态数组
类型 db-byte dw- word dd-dword
变量名 类型 初始值
hwnd dd ? 初始值不确定就是?
局部变量 :local 变量名[大小]:类型
local hword:dword 申明一个dword的变量。
local arrword[100]:DWORD
结构体
abase struct 结构体开始
adb byte ?
adw word ?
add dword?
abase ends ;结构体结束 占7个字节。
lea eax,szname;lea 取地址的指令。
invoke gethandle不是汇编指令 ,它是MASM微软提供的一个宏。等效于 push 0 call gethandle
push MB_OK
push offset sztitle
push offset szclassName
push 0
call messagebox
等效于
invoke messagebox,0,szclassName,sztitle,MB_OK
全局变量写的时候 都用offset,宏操作,编译的时候展开,
局部变量是在支行的时候 ,在栈上申请。
mul ecx *ebx 超过32位,被乘数默认放在EAX中。
乘数放到另一个寄存器 ecx
mul ecx 结果会保存64位的值,高32位在edx,低32位在EAX。
mov eax,al ;eax是32位的,al是8位的,这个操作会报错。要用
movzx eax,al;
原文地址:https://blog.csdn.net/scdn1172/article/details/143283670
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!