汇编语言学习笔记(三)

CH3、Windows汇编基础

.386

.model flat,stdcall

option casemap:none

定义程序使用的指令集、工作模式

相应的还有:.8086,.486,.586,.586p

内存模式有很多,如:

tiny  small  medium  compact  large  huge  flat

汇编经常遇到这样的代码:

mov ax,DATA

mov       ds,ax

作用是给DS赋值。参考前面描述CPU结构的知识,知道不能直接写成

mov           ds,DATA

但对于.model flat模式,MASM自动做了下面的定义:

ASSUME CS:flat,       DS:flat,       ES:flat,       SS:flat,       FS:ERROR,GS:ERROR

flat是内存平坦模式,意思是段寻址4G空间。

因此,CS,DS,ES,SS可以在程序中平坦使用。使用FS和GS则会报错。

.model 语句用于指定调用规则,即子程序的调用方式。就是说明了在调用API时的参数传递次序和堆栈平衡的方法。

option casemap:none  说明程序对大小写敏感。注意,Windows API是大小写敏感的,因此这里这么定义。

使用includelib 链接需要用到的lib库,如:

includelib    user32.lib

对于所有要用到的库函数,在程序的开始部分必须预先声明。包括:

函数名称       PROTO[调用规则]:[第一个参数类型][,:后续参数类型]

全部声明所用到的Api函数显然很麻烦,因此可以使用include把声明包括进来,用法和C一样。

.data

数据段

.code

代码段,遇到end代码段结束。

.stack [堆栈大小]

定义堆栈段

有的变量一开始并不赋值,在程序运行过程中才赋值,因此放到:

.data?中。

如果定义一个缓冲区,则:

buffer byte 65536 dup(?)

定义固定变量,程序运行过程中不再修改:

.const

==========

一段Hello World例子代码

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

.386

.model flat,stdcall

option casemap:none

MessageBoxA       PROTO :dword , :dword, :dword, :dword

MessageBox       equ        <MessageBoxA>

includelib        user32.lib

NULL            equ        0

MB_OK          equ  0

.stack     4096

.data

szTitle       byte 'Hi!',0

szMsg       byte 'Hello world!',0

.code

start:

invoke       MessageBox, NULL, offset szMsg, offset szTitle, MB_OK

ret

end        start

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

编译指令:

ml /coff hello.asm /link /subsystem:windows

操作数的寻址方式:

1、  立即数寻址,操作数是常数

mov AL,0

mov EAX, 0fffffffH

2、  寄存器寻址,不和内存打交道。

MOV EAX, EBX

除了1、2两种外,其它寻址都要和内存打交道。

3、  直接寻址,给出操作数的内存地址。

定义变量dVar,寻址时

MOV  EAX,  dVar

MOV  dVar,  EBX

这相当于在C语言里用指针赋值一样

4、  寄存器间接寻址,地址在寄存器中。

MOV  ESI, 00404011H

MOV  EAX, [ESI]

5、  寄存器相对寻址,地址是寄存器和一个立即数相加得到的结果。

MOV  ESI,00404011H

MOV  EAX,[ESI + 4]

6、  基址变址寻址,地址是两个寄存器相加的结果。

MOV    ESI, 0040200AH

MOV    EBX,4

MOV    EDI,[EBX + ESI]

7、  基址变址相对寻址,两个寄存器相加后再加一个立即数

MOV    ESI, 0040200AH

MOV    EBX,4

MOV    EDI,[EBX + ESI + 4]

8、  基址变址比例相对寻址,变址寄存器需要乘以一个比例数。

MOV    ESI, 0040200AH

MOV    EBX,4

MOV    EDI,[EBX*2 + ESI + 4]

段超越

为了确定内存中的地址,还需要借助段寄存器。

如果在基址寄存器中用了ESP(保存栈顶偏移)和EBP(栈数据访问),则段寄存器中的内存操作数在SS中,这是一种默认。

使用段超越前缀能够改变寻址方式中的默认使用的段寄存器。

MOV  EAX, CS:[EDI]        ;默认是DS

MOV  EBX, ES:[ESP – 4]   ;默认是SS

MOV DS: [EBP] ,ECX

CS段只能用来读取数据,因此只能作为源操作数的段前缀

MOV  CS:[0040200AH] , EAX

Windows 32环境中,FS段保存系统使用的一些信息,如果要访问,必须明确指出段寄存器为FS。另外,Win32环境下,CS、DS、ES、SS在内存中指向同一个段,大小为4G,程序中一般不需要使用段超越前缀。

数据定义

二进制:后跟b/B、0001b

八进制:后跟o、33o

十进制:后跟D、27d

十六进制:后跟H、2Ah

程序中可以指明默认使用16进制数

.radix 16

简单数据类型

类型              助记符           简写              占用字节数           范围

字节              BYTE             DB                 1                          0~255

字                  WORD           DW

双字              DWORD        DD

远字              FWORD         DF

四字              QWORD        DQ

十字              TBYTE          DT

有符号字节       SBYTE

有符号字       SWORD

有符号双字       SDWORD

定义变量:

[变量名]  助记符           表达式,[,表达式]

表达式是 ? 则不进行初始化

数组定义

ch   DWORD 50 DUP (0)

定义ch为数组,共50个元素,每个元素初始值为0。

DUP是重复数据操作符。可以嵌套

ch DWORD 3 DUP (2 DUP  (-1,-2))

相当于char ch[3][2],  ch[0] = {-1,-2},ch[1] = {-1,-2} 。。。。

伪操作符,不真正生成数据。

PTR ,作用有二,

一是临时改变变量类型:

dVar        DWORD    01020304H

MOV       AX , WORD PTR dVar

MOV       DX, WORD PTR dVar + 2

如果不用PTR就会报错,因为AX是16位,而dVar是双字类型。

MOV        BYTE    PTR    dVar + 1 , 0FFH

MOV        BYTE    PTR    dVar + 3 , 12H

将dVar的第一字节设置成0ffH,第三字节设置成12H。

作用二,指明操作传递的数据类型

有些语句能够知道传递的类型,比如

MOV        AL    ,   0           ;传一个字节

MOV        AX    ,    [EBX]     ;传一个字

但下面的语句就不知道了:

MOV    [EBX] , 0

需要这样写:

MOV    BYTE PTR [EBX] , 0

EQU,相当于C语言的#define

比如:

NULL   EQU    0

MB_OK  EQU   0

等于符号

为一个变量或者表达式定义一个等价符号名。

I                           =                          100

DwFirst                DWORD               I

I                           =                         I + 1

DwSecond            DWORD               I

$ 当前地址计数器值

MOV    EAX  , $

EAX中是该指令所在的地址。

注意,程序中的每一行都有一个地址。

ORG  为程序的地址计数器赋值

aVar     BYTE    01h

ORG    $ + 10

bVar     BYTE    02h

计数器当前值的基础上增加了10。

Offset 取地址

下面两条语句是等价的

dVar3    DWORD    wVar2

dVar3    DWORD    offset    wVAr2

下面语句不等价

MOV    EBX   ,   dVar2

MOV    EBX   ,   offset   dVar2

Type    返回变量占用字节数

 

Length 返回变量用DUP重复的数目,无重复返回1

 

Size 返回type * length的值

操作符

算术操作符

+ - × / MOD

MOV EAX , 4 * 5

MOV EAX , OFFSET dVar2 – 10

Mov eax , 30 / 8

Mov eax , 30 mod 8

逻辑操作符

AND OR XOR NOT

关系操作符

EQ(等于) NE(不等于) LT(小于) LE(小于等于)  GT(大于)  GE(大于等于)

关系成立,结果为真,关系不成立,结果为假。

寻址问题

在实际寻址时,操作数类型很关键,比如:

MOV AL , -1

MOV AX , -1

MOV EAX , -1

同样是-1,但第一个-1 = 0FFH,第二个-1 = 0FFFFH,第三个-1 = 0FFFFFFFFH 。

数组元素的访问

可以这样定义变量

bVar    byte    01h , 02h , 03h , 04h

wVar    word    0101h , 0102h , 0103h , 0104h

dVar    dword    01010101h , 01010102h , 01010103h , 01010104h

访问时

mov    ebx , 2

mov    al , bVar[ebx]    ; al 中为03h

mov    ax , wVar[ebx * 2] ; 加入比例因子,ax 中为0103h

mov    eax , dVar[ebx * 4] ;

win32汇编语言学习笔记(三)相关推荐

  1. windows下32位汇编语言学习笔记

    windows下32位汇编语言学习笔记 第一章  第一章 背景知识 80x86处理器的存储器 4个数据寄存器 EAX,EBX,ECX,EDX EAX寄存器 所有API函数的返回值都保存在EAX里,注意 ...

  2. J2EE学习笔记三:EJB基础概念和知识 收藏

    J2EE学习笔记三:EJB基础概念和知识 收藏 EJB正是J2EE的旗舰技术,因此俺直接跳到这一章来了,前面的几章都是讲Servlet和JSP以及JDBC的,俺都懂一些.那么EJB和通常我们所说的Ja ...

  3. tensorflow学习笔记(三十二):conv2d_transpose (解卷积)

    tensorflow学习笔记(三十二):conv2d_transpose ("解卷积") deconv解卷积,实际是叫做conv_transpose, conv_transpose ...

  4. Ethernet/IP 学习笔记三

    Ethernet/IP 学习笔记三 原文为硕士论文: 工业以太网Ethernet/IP扫描器的研发 知网网址: http://kns.cnki.net/KCMS/detail/detail.aspx? ...

  5. iView学习笔记(三):表格搜索,过滤及隐藏列操作

    iView学习笔记(三):表格搜索,过滤及隐藏某列操作 1.后端准备工作 环境说明 python版本:3.6.6 Django版本:1.11.8 数据库:MariaDB 5.5.60 新建Django ...

  6. 吴恩达《机器学习》学习笔记三——多变量线性回归

    吴恩达<机器学习>学习笔记三--多变量线性回归 一. 多元线性回归问题介绍 1.一些定义 2.假设函数 二. 多元梯度下降法 1. 梯度下降法实用技巧:特征缩放 2. 梯度下降法的学习率 ...

  7. Python基础学习笔记三

    Python基础学习笔记三 print和import print可以用,分割变量来输出 import copy import copy as co from copy import deepcopy ...

  8. Mr.J-- jQuery学习笔记(三十二)--jQuery属性操作源码封装

    扫码看专栏 jQuery的优点 jquery是JavaScript库,能够极大地简化JavaScript编程,能够更方便的处理DOM操作和进行Ajax交互 1.轻量级 JQuery非常轻巧 2.强大的 ...

  9. MYSQL学习笔记三:日期和时间函数

    MYSQL学习笔记三:日期和时间函数 1. 获取当前日期的函数和获取当前时间的函数 /*获取当前日期的函数和获取当前时间的函数.将日期以'YYYY-MM-DD'或者'YYYYMMDD'格式返回 */ ...

最新文章

  1. EID-:宏病毒组技术在新发腹泻病毒鉴定中的应用
  2. GNU make 工具
  3. 高德地图JavaScript API开发研究
  4. SmartFoxServer资料
  5. 【转】 ADO.NET最佳实践
  6. Mysql探究与学习大纲--主要是为了自己复习方便
  7. 拓端tecdat|R语言ggmap空间可视化机动车碰撞–街道地图热力图
  8. tomcat设置独立jvm的例子
  9. MySQL数据库通过cmd窗口导入sql文件
  10. rust进水器怎么用_RO反渗透净水器的正确使用方式 你都Get了吗?
  11. 数据库基础知识和SQL语言
  12. SQLSERVER 查询分析器快捷键
  13. Scrum敏捷开发流程
  14. 要怎么在计算机里清除桌面内存,告诉你电脑内存怎么清理
  15. mkt sensor1.0 alps
  16. 正则表达式-匹配中英文、字母和数字
  17. oppoK9Pro游戏性能怎么样
  18. 机器学习实战教程(三):决策树实战篇
  19. java 5,8,9章复习
  20. 使用注解失败的原因及解决方法

热门文章

  1. 六下计算机教学总结,关于六年级信息技术教学工作总结
  2. 机器学习算法应用场景实例
  3. java 导出文字与多张图片
  4. nii文件python可视化并转化为gif
  5. 在VSCode中将Maven项目打包成jar文件
  6. artDialog和iframe嵌入页面
  7. RFM模型原理详解与实操运用
  8. arm平台的录屏软件
  9. 计算机一级考试题发邮件是怎么发的,计算机一级考试ie题和收发邮件模拟题
  10. VUE中echart自适应外部div大小