导航

✨学习笔记——从零开始速通汇编(一):寄存器 | JinYu🐟

🎉学习笔记——从零开始速通汇编(二):汇编程序语句结构&寻址方式 | JinYu🐟

🎊学习笔记——从零开始速通汇编(三):数据传送类&算术运算类指令系统 | JinYu🐟

🎃学习笔记——从零开始速通汇编(四):逻辑运算与移位操作类指令系统 | JinYu🐟

🎄学习笔记——从零开始速通汇编(五):程序控制类&串操作类指令系统 | JinYu🐟


学习笔记——从零开始速通汇编(二):汇编程序语句结构&寻址方式

前言:

在经过上一文章的学习之后,接下来我们将学习汇编程序语句结构框架和寻址方式,正式开始汇编程序的编写

结构、框架、伪指令:

汇编语言分段结构:

宏汇编是微软推出的8086系统最流行的汇编语言版本,其他版本和它大同小异

汇编语言源程序采用分段结构,将源程序的指令代码、数据变量、堆栈分别定义在不同的主存段中

比较典型的源程序包含三个段:代码段数据段堆栈段

一个源程序可包含的段数是不受限制的,但8086CPU只提供了4个段寄存器,所以在一个源程序中最多只能操作4个段

汇编语言语句结构:

[名字项] 操作项 [操作数项] [; 注释项]

其中,[ ]表示为可选项

分类

通过作用分为三类:

  1. 伪指令语句

    伪指令语句用来说明程序运行的处理器平台,进行段定义、变量与常量定义、过程定义、宏定义以及源程序的开始与结束定义等

    伪指令语句作用于汇编过程,用来指示汇编程序如何进行源程序汇编(不是实现操作

  2. 指令语句

    指令语句包含一条汇编语言指令

    程序的操作功能是由指令语句来实现的

  3. 宏指令语句

    宏指令是宏汇编语言允许程序员自定义的一种特殊形式的指令(类比C语言的函数)

    宏指令语句用来描述宏指令的使用

组成

  1. 名字项

    名字项是一个符合特定规则的字符串,其最大长度不超过31个字符,组成名字项的字符定为:26个英文字母(不分大小写),数字符0-9,以及?,·'_,@,$等

    数字不能作为名字项的第一个字符

    ·只能作为名字项第一个字符用

  2. 操作项

    操作项是一条语句中必不可少的部分

  3. 操作数项(了解即可)

    可以是一个、两个或没有,可以是常量、变量、寄存器、指令标号、过程名、段名或表达式

常用伪指令:

段定义伪指令

格式:

1
2
3
段名 SEGMENT [定位类型] [组合类型] ['类别']
......;段的具体内容
段名 ENDS

[定位类型]:PARA(默认)、BYTE(任何)、WORD(段首地址必须为偶数)、DWORD(段首地址被4整除)、PAGE(段首地址被256整除)

[组合类型]

PUBLIC:多个模块中具有该组合类型的同名,同类别连成一个段,总容量不能超过64KB

STACK:同PUBLIC,但是堆栈段

COMMON:段容量为组合段中的最大段

[‘类别’]:在任意一个合法的字符串,起到组合作用

ASSUME伪指令

ASSUME是建立段寄存器与段之间联系的语句,是必不可少的,格式为:

1
ASSUME 段寄存器名:段名 [,段寄存器名:段名,[,...]]

源程序结束伪指令格式

1
END [指令标号]

标准堆栈段、数据段、代码段框架结构:

框架结构

注意这块内容作用为结束程序运行,返回操作系统命令状态(类比C语言return 0)

1
2
MOV AH,4CH
INT 21H

这里END后面没有带S,因为是源程序结束,段程序结束才有S

1
END START

变量定义与存储空间分配:

DB-定义字节类型 例:VAR1 DB 46H

DW-定义字类型 例:VAR2 DW 2A05H

DD-定义双字类型 例:VAR3 DB 26*3,-53,00101001B

DQ-定义四字类型 例:VAR4 DW 12H,0A186H

DT-定义十字节类型 例:VAR5 DB ?,?,?,?,?,?,?,?,?,? |但是有DUP操作符简化:重复次数 DUP (数据项)

属性运算符

OFFSET:用于取变量或标号的段内偏移地址

1
OFFSET 变量或标号

SEG:用于取变量或标号的段地址

1
SEG 变量或标号

PTR:用于重新指定变量、标号或地址表达式的访问类型

1
新类型 PTR 变量或标号或地址表达式

可重新定义的类型有:BYTE\WORD\DWORD\NEAR(近类型)\FAR(远类型)

例:

(1)OFFSET VAR1

(2)OFFSET VAR2+1

(3)SEG VAR3

(4)WORD PTR VAR3

替代符定义伪指令

EQU伪指令定义替代符

1
替代符 EQU 表达式

=伪指令定义替代符

1
替代符 = 表达式

※=伪指令定义替代符可在同一个源程序中重复定义,有效范围是从被定义开始到下一次被定义

※替代符变量有本质的区别:变量需要分配存储空间,但替代符不会,它只是某个表达式的别名,汇编程序在对其进行汇编时,会用表达式的值置换

EQU在程序中只能指定一次(类比C语言的const),而**=在程序中可以指定多次**

段内偏移地址指针设置伪指令

段内偏移地址$

段内偏移地址指针设置伪指令ORG

1
2
3
4
5
DSEG SEFMENT
DATE1 DB 14H DUP(?)
ORG 100H
DATE2 DW 1375H,2468H
DSEG ENDS

说明:ORG使指针在段内偏移100H,所以1357H不是从段首开始存储,而是从段首偏移100H的地方开始存储

存储的时候采用的是小端存储,存的时候整体往下存储,但比如 VAR1 DW 3B04H 存储的时候是04H在上,3BH在下

寻址方式:

寻址方式:指令指定操作数的位置,即给出地址信息,在执行时需要根据这个地址信息找到需要的操作数

这种寻找操作数的过程称为寻址,而寻找操作数的方法称为寻址方式

立即数:指令中操作数字段实质上是指出操作数存放于何处,一般来说,操作数可以跟随在指令操作码之后,称为立即数

寄存器操作数:操作数也可以存放在CPU内部的寄存器中

存储器操作数:绝大多数的操作数存放在内存储器中

寄存器寻址

参加操作的操作数在CPU的通用寄存器

例:

1
MOV AX,BX

对于8086,寄存器可以是AX,BX,CX,DX,SI,DI,SP,BP

也可以是AL,AH,BL,BH,CL,CH,DL,DH

立即寻址

指令中的源操作数是立即数,即源操作数是参加操作的数据本身

例:

1
MOV BX,2200H

存储器寻址

存储器寻址:直接寻址、寄存器间接寻址、寄存器相对(+某数)寻址、基址变址寻址、相对基址变址寻址

直接寻址

指令中直接给出操作数的偏移地址

例:

1
MOV AX,[1100H]  (默认在数据段中)

寄存器间接寻址

参与操作的操作数存放在内存中,其偏移地址伪指令中的寄存器的内容

例:

1
设BX=2400H,MOV AX,[BX]

16位寻址时可用的寄存器是BX,DI,SI和BP

寄存器相对地址

操作数的有效地址为基址寄存器变址寄存器的内容和指令中指定的位移量之和,有效地址由两种成分组成

例:

1
2
3
MOV AX,COUNT[SI]

MOV AX,[COUNT+SI]

16位寻址时可用的寄存器是BX,DI,SI和BP

基址变址寻址

操作数的有效地址是一个基址寄存器和一个变址寄存器的内容之和,所以有效地址由两种成分组成

例:

1
2
MOV AX,[BX][DI]
MOV AX,[BX+DI]

基址寄存器是BX是,段寄存器默认DS;基址寄存器是BP时,段寄存器默认SS

相对基址变址寻址

操作数的有效地址是一个基址寄存器和一个变址寄存器的内容和指令中指定的位移量之和,所以有效地址由三种成分组成

例:

1
2
3
MOV AX,D[BX][SI]
MOV AX,D[BX+SI]
MOV AX,[D+BX+SI]

基址寄存器是BX是,段寄存器默认DS;基址寄存器是BP时,段寄存器默认SS

隐含寻址

在8086指令系统中,有些指令默认操作数存放在某个特定的寄存器中,从而可省略对该操作数的描述,称为隐含寻址

例:

1
MUL BX

总结对照

总结

另外,还有转移地址的寻址方式

段内寻址

  • 段内直接寻址 JMP NEAR PTR NEXT
  • 段内间接寻址 JMP TABLE[BX]

段间寻址

  • 段间直接寻址 JMP FAR PTR NEXT
  • 段间间接寻址 JMP DWORD PTR [BX]