自学内容网 自学内容网

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)!