内存模式

  1. .386
  2. .model flat,stdcall ;子程序调用模式,win32中只能用stdcall,因为win32api调用使用的这个
  3. option casemap:none ;定义了程序中变量和子程序名是否对大小写敏感,win32api名称区分大小写,所以只需要记住这个定式
  1. 指定使用的指令集
  2. .model语句
  1. .model 内存模式[,语言模式][,其他模式]

内存模式

模式 内存使用方式
tiny 用来建立.com文件,所有的代码、数据和堆栈都在同一个64KB段内
small 建立代码和数据分别用一个64KB段的.exe文件
medium 代码段可以有多个64KB段,数据段只有一个64KB段
compact 代码段只有一个64KB段,数据段可以有多个64KB段
large 代码段和数据段都可以有多个64KB段
huge 同large,并且数据段中的一个数组也可以超过64KB
flat Win32程序使用的模式,代码和数据使用同一个4GB段

对于Win32程序来说,只有一种内存模式,flat模式

源程序结构

  1. .386
  2. .model flat,stdcall
  3. option casemap:none
  4. <一些include语句>
  5. .stack [堆栈段的大小] ;常忽略不写
  6. .data
  7. <一些初始化过的变量定义>
  8. .data?
  9. <一些没有初始化过的变量定义>
  10. .const
  11. <一些常量定义>
  12. .code
  13. <代码>
  14. <开始标号>
  15. <其他语句>
  16. end <开始标号>

局部变量的定义

  1. local 变量名1[[重复数量]][:类型],变量名2[[重复数量]][:类型]......

local伪指令必须紧接在子程序的伪指令proc后

变量的类型

名称 表示方式 缩写
字节 Byte db
word dw
双字(doubleword) dword dd
三字(farword) fword df
四字(quadword) qword dq
十字节BCD码(tenbyte) tbyte dt
有符号字节(signbyte) sbyte
有符号字(signword) sword
有符号双字(signdword) sdword
单精度浮点数 Real4
双精度浮点数 Real8
10字节浮点数 Real10

数据结构

  1. 结构名 struct
  2. 字段1 类型 ?
  3. 字段2 类型 ?
  4. ......
  5. 结构名 ends

定义

  1. .data?
  2. 变量名称 结构名 <字段1,字段2,...>
  3. ;或者
  4. .data?
  5. 变量名称 结构名 <>

使用

  1. ;前提假设结构名为WNDCLASS,结构体变量名为stWndClass,里面有字段lpfnWndProc
  2. ;1
  3. mov eax,stWndClass.lpfnWndProc
  4. ;2.esi寄存器作指针寻址
  5. mov esi,offset stWndClass
  6. mov eax,[esi + WNDCLASS.lpfnWndProc] ;注意这里是WNDCLASS
  7. ;3.assume伪指令把寄存器预先定义为结构指针
  8. mov esi,offset stWndClass
  9. assume esi:ptr WNDCLASS
  10. mov eax,[esi].lpfnWndProc
  11. ...
  12. assume esi:nothing ;注意:不使用esi做指针的时候需要用这句取消定义
  13. ;4.结构的定义可以嵌套
  14. NEW_WNDCLASS struct
  15. dwOption word ?
  16. oldWndClass WNDCLASS <>
  17. NEW_WNDCLASS ends
  18. ;5.嵌套的引用
  19. mov wax,[esi].oldWndClass.lpfnWndProc

以不同的类型访问变量

  1. ;以db定义一个缓冲区
  2. szBuffer db 1024 dup (?)
  3. ;mov ax,szBuffer ;错误,masm中,如果要用制定类型之外的长度访问变量,必须显式指出要访问的长度,这样编译器忽略语法上的长度检验,仅使用变量的地址
  4. ;类型 ptr 变量名
  5. mov ax,word ptr szBuffer
  6. mov eax,dword ptr szBuffer

movzx

把一个字节扩展到一个字或一个字或一个双字再放到ax或eax中,高位保持0而不是越界存取到其他的变量

  1. .data
  2. bTest1 db 12h
  3. .code
  4. movzx ax,bTest1
  5. movzx eax,bTest1

变量的尺寸和数量

  1. sizeof 变量名、数据类型或数据结构名 ;取得变量、数据类型或数据结构以字节为单位的长度
  2. lengthof 变量名、数据类型或数据结构名 ;取得变量中数据的项数

获取变量地址

  1. mov 寄存器,offset 变量名 ;offset是取变量地址的伪操作符
  2. lea eax,[ebp-4] ;运行时按照ebp的值实际计算出地址放到eax
  3. ;invoke伪指令参数要用到一个局部变量的地址时,参数中不可能写入lea指令,用offset又是不对的,可用addr
  4. addr 局部变量名和全局变量名 ;全局变量名时编译器按照odffset的用法来用;局部变量名时,编译器用lea先把地址取到wax中,然后用eax代替变量地址使用
  5. ;invoke中使用addr时,它的左边不能使用wax,否则eax的值会被覆盖

子程序的定义

  1. 子程序名 proc [距离][语言类型][可视区域][USES寄存器列表][,参数:类型]...[VARARG]
  2. local 局部变量列表
  3. 指令
  4. 子程序名 endp

参数传递和堆栈平衡

不同语言调用方式的差别

C SysCall StdCall BASIC FORTRAN PASCAL
最先入栈参数
清除堆栈者 调用者 子程序 子程序 子程序 子程序 子程序
允许使用VARARG

条件测试语句

  1. 寄存器或变量 操作符 操作数
  2. (表达式1) 逻辑运算符 (表达式2) 逻辑运算符 (表达式3) ...
  3. ;举例,左边表达式,右边是表达式为真的条件
  4. x==3 ;x等于3
  5. eax!=3 ;eax不等于3
  6. (y>=3)&&ebx ;y大于等于3ebx为非零值
  7. ;表达式的左边只能是变量或寄存器,不能为常数;表达式两边不能同时为变量,但可以同时是寄存器

标志位的状态指示

  1. CARRY? 表示Carry位是否置位
  2. OVERFLOW? 表示Overflow位是否置位
  3. PARITY? 表示Parity位是否置位
  4. SIGN? 表示Sign位是否置位
  5. ZERO? 表示Zero位是否置位

分支语句

  1. .if eax && (bx >= dWX) || !(dWY != ecx)
  2. mov esi,1
  3. .elseif edx
  4. mov esi,2
  5. .elseif esi & 1
  6. mov esi,3
  7. .elseif ZERO? && CARRY?
  8. mov esi,4
  9. .endif

循环语句

  1. .while 条件测试表达式
  2. 指令
  3. [.break [.if 退出条件]]
  4. [.continue]
  5. .endw
  6. ;或
  7. .repeat
  8. 指令
  9. [.break [.if 退出条件]]
  10. [.continue]
  11. .until 条件测试表达式 (或 .untilcxz [条件测试表达式])

变量和函数的命名

匈牙利表示法

  1. 类型前缀+变量说明(类型用小写字母,说明则用首字母大写的几个引文单词组成)

汇编语言中常用的类型前缀

b 表示byte
w 表示word
dw 表示dword
h 表示句柄
lp 表示指针
sz 表示以0结尾的字符串
lpsz 表示指向0结尾的字符串的指针
f 表示浮点数
st 表示一个数据结构

举例

hWinMain 主窗口的句柄
dwTimeCount 时间计数器,以双字定义
szWelcome 欢迎信息字符串,以0结尾
lpBuffer 指向缓存区的指针
stWndClass WNDCLASS结构

本书的作者建议

  • 全局变量的定义使用标准的匈牙利表示法,在参数的前面加下划线;在局部变量的前面加@符号,这样引用的时候就能随时注意到变量的作用域。
  • 在内部子程序的名称前面加下划线,以便和系统API区别。

举例

  1. _Calc proc _dwX,_dwY
  2. local @dwResult
  3. finit
  4. fild _dwX
  5. fld st(0)
  6. fmul ;i * i
  7. fild _dwY
  8. fld st(0)
  9. fmul ;j * j
  10. fadd ;i * i + j * j
  11. fsqrt ;sqrt(i * i + j * j)
  12. fistp @dwResult ;put result
  13. mov eax,@dwResult
  14. ret
  15. _calc endp

Windows环境下32位汇编语言程序设计笔记-基础篇的更多相关文章

  1. 读书笔记——Windows环境下32位汇编语言程序设计(9)ANSII字符大小写转大写

    在罗云彬的<Windows环境下32位汇编语言程序设计>中第321页 ... .const szAllowedChar db '0123456789ABCDEFabcdef',08h .. ...

  2. Windows环境下32位汇编语言程序设计(典藏版)

    Windows环境下32位汇编语言程序设计(典藏版)(含CD光盘1张)(年,经典再现!) 罗云彬 著 ISBN 978-7-121-20759-4 2013年7月出版 定价:99.00元 756页 1 ...

  3. Windows环境下32位汇编语言程序设计(典藏版)

    <Windows环境下32位汇编语言程序设计(典藏版) > 基本信息 作者: 罗云彬 出版社:电子工业出版社 ISBN:9787121207594 上架时间:2013-7-8 出版日期:2 ...

  4. 读书笔记——Windows环境下32位汇编语言程序设计(2)配置环境

    一直想买本罗云彬的Win32汇编书,现在终于出典藏版了,就买了本,读一读,涨涨姿势. 我把笔记本光驱拆下来添加了个硬盘,现在想装回去发现坏了,所以守着CD盘,代码却用的是第三版的,这真是个悲剧啊. - ...

  5. 读书笔记——Windows环境下32位汇编语言程序设计(13)关于EXCEPTION_DEBUG_INFO结构体

    在动手自己尝试编写书上第13章的例子Patch3时,遇到了一个结构体EXCEPTION_DEBUG_INFO. 这个结构体在MASM的windows.inc中的定义和MSDN中的定义不一样. (我使用 ...

  6. 读书笔记——Windows环境下32位汇编语言程序设计(6)使用浮点指令进行64位除法

    罗云彬 典藏版Page192,mark下. 这段代码看不懂,手册上根本没有fdivr不带操作数的指令. .data dqTickCounter1 dq ? dqTickCounter2 dq ? dq ...

  7. 读书笔记——Windows环境下32位汇编语言程序设计(5)模态对话框

    资源可以用VC之类的生成,然后拷贝出来. 例如:每一个MFC工程都有一个resource.h,没有做任何修改时,这个resource.h文件是原来自带的.当对资源进行过修改添加之类的时,新添加的资源的 ...

  8. 读书笔记——Windows环境下32位汇编语言程序设计(3)一些基础知识

    声明函数用proto 定义函数用proc 局部变量只能定义,不能赋初值,类型不能用缩写. 全局变量可以定义的时候赋初值,默认值为0. 在invoke中,参数可以使用addr取址. sizeof 字节长 ...

  9. 读书笔记——Windows环境下32位汇编语言程序设计(3)求复数模的子程序

    3.6.1.1中的例子 _Calc proc _dwX,_dwY local @dwResult finit fild _dwX fld st(0) fmul ;i*i fild _dwY fld s ...

随机推荐

  1. Rpgmakermv(16) YEP MainmenuManager

    ---------------------------------------------------------------------------------------------------- ...

  2. 4.无监督学习--K-means聚类

    K-means方法及其应用 1.K-means聚类算法简介: k-means算法以k为参数,把n个对象分成k个簇,使簇内具有较高的相似度,而簇间的相似度较低.主要处理过程包括: 1.随机选择k个点作为 ...

  3. VIM For Windows 1

    some tips for using vim in windows. 1,download the software vim and install it, you can go to the Of ...

  4. window下安装cross-env解决NODE_ENV ts-node 不是内部或外部命令,也不是可运行的程序 或批处理文件 问题

    window下安装cross-env解决NODE_ENV ts-node 不是内部或外部命令,也不是可运行的程序 或批处理文件 问题 在git bash上启动无法进行调试,采用cross-env后可以 ...

  5. Python这么热,要不要追赶Python学习热潮?

    Python这么热,要不要追赶Python学习热潮? Python 可以用来做什么?在我看来,基本上可以不负责任地认为,Python 可以做任何事情.无论是从入门级选手到专业级选手都在做的爬虫,还是W ...

  6. apiCloud中的API对象

    1.属性 appId apiready = function () { var appId = api.appId; //比如: A6980386445546 var appName = api.ap ...

  7. PS火焰文字制作

    火焰文字制作: 最终效果 第一步: 新建图层,并输入文字(这里不做详细解说)

  8. C Language Deep Analyse

    1.记录几个少见的关键字    auto 声明为自动变量,缺省时编译器一般默认为auto    register 声明寄存器变量    volatile 说明变量在程序执行中可被隐含地改变    ex ...

  9. Percona Server 5.6 安装TokuDB

    系统:Red Hat Enterprise Linux Server release 6.3 (Santiago) 数据库:Percona-Server-5.6.29-rel76.2-Linux.x8 ...

  10. Spring RestController 请求参数详解

    Spring RestController 请求参数详解 引用作者jpfss 在阅读之前,最好先了解http请求的get,post,以及各种head头类型,请求参数类型. 无参数,设置RestCont ...