win32汇编语言学习笔记(三)

CH3Windows汇编基础

 

.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空间。

 

 

因此,CSDSESSS可以在程序中平坦使用。使用FSGS则会报错。

 

 

.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

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

 

 

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环境下,CSDSESSS在内存中指向同一个段,大小为4G,程序中一般不需要使用段超越前缀。

 

 

数据定义

 

 

二进制:后跟b/B0001b

八进制:后跟o33o

十进制:后跟D27d

十六进制:后跟H2Ah

 

 

程序中可以指明默认使用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就会报错,因为AX16位,而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] ;

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值