指令系统(一)
名词解释
-
指令:使计算机执行某种特定操作的二进制编码
-
指令系统:所有指令的集合
-
指令的组成
-
操作码:规定所要执行的操作类型
-
操作数:所需要处理的数据或者数据的地址信息
MOV AX, 1234H; AX=1234H MOV dst, src; src:源操作数,dst:目的操作数
-
-
寻址方式:获取数据或者数据地址信息的方式
- 寻址方式分为立即数寻址、寄存器寻址和存储器寻址
8086汇编语句的组成
概念
- 伪指令:只是告诉汇编程序如何进行汇编,汇编后没有生成机器语言指令,它在程序汇编时得以执行。
伪指令与指令的区别
伪指令不产生对应的机器码,其功能在在编译阶段实现功能
指令产生对应的机器码,其功能在在执行阶段实现功能
汇编语句的构成
情况一:
DAT1 DW ?;注释
DAT1
:变量名。必须字母开头,代替了内存空间DW,方便记忆
DW
:助记符
?
:操作数。?代表一个随机数
;
:注释
情况二:
NEXT: MOV AX, BX
ADD AX, DAT1
JZ NEXT;跳转到NEXT
NEXT
:标号名,用户自定义,后接冒号
常数和表达式
常数
常见的常数
作为十六进制数,第一个字符必须是数字,如果以字母开头,则应该在其前面添加0
表达式
表达式由操作数和操作符组成,而操作数可以是常数、标识符、表达式(子表达式)。
MOD运算是取两数相除的余数,两数应该均为正整数。
例如,79 MOD 16 结果为 15
,0B5H MOD 10H 结果为 5。
逻辑运算是针对位的。应该注意:逻辑操作符本身又是逻辑运算指令的助记符,只
有当它们出现在操作数中时,它们才是操作符,如AND AL,41H OR 20H中,
AND为指令助记符,而OR为操作符。
标号
标号是由指令语句所定义的标识符,它与助记符之间用冒号间隔,用于指示相应指令的地址。
START:MOV AX,1000
标号 START 代表了指令MOV AX,1000
的地址
标号具有3个属性。
-
段地址:指示标号所在段的段地址。
使用属性操作符获取:
SET
-
偏移地址:指示标号在段内的偏移地址。
使用属性操作符获取:
OFFSET
例:MOV BX, OFFSET NEXT;OFFSET NEXT是16位的
-
类型:如果标号仅在本段内使用,则其类型为近程(
NEAR
,段内),如果标号还将在段间使用,则其类型为远程(FAR
,段间)。使用属性操作符获取:
TYPE
变量及变量定义伪指令
伪指令语句
变量是由伪指令来定义的。下面共介绍13种
伪指令的分类:
- 数据定义伪指令
- 符号定义伪指令:
EQU
- 段定义伪指令:
SEGMENT
- 设定段寄存器伪指令:
ASSUME
- 过程伪指令:
PROC
- 开始伪指令:
ORG
- 模块定义与连接伪指令:
NAME
、TITLE
、END
数据定义伪指令
伪指令 | 说明 |
---|---|
DB |
定义字节变量,8位(1字节) |
DW |
定义字变量,16位(2字节)。高字节放在高地址,低字节放在低地址 |
DD |
定义双字变量,32位(4字节) |
DQ |
定义长字变量,64位(8字节) |
DT |
定义5字变量(10字节) |
DAT1 DB 'THIS' DAT2 DW 'TH', 'I', 'S' ;用DB定义时,一对单引号内字符串长度任意,用DW、DD定义时,一对单引号内字符串长度最大是2
注意DW中,单字节字符占用两个字节
重复操作符
当同样的操作重复多次时,使用重复操作符 DUP
例:
DAT1 DB 5 DUP(30H)
输出:
使用场景:预留存储区域,如:定义堆栈、数据缓冲区等
可以嵌套
符号伪指令
一般格式:名字 EQU 表达式
不能对同一个名字重复定义,解决:使用
=伪指令
NUM1 EQU 11H NUM1 EQU 22H;报错 NUM2 = 11H NUM2 = 22H
段定义伪指令
段名 SEGMENT [定位类型] [组合类型] ['类别']
.
.
.
段名 ENDS
说明:
-
定位类型
告诉汇编程序,本段起始地址的要求。
段的定位类型与段起始物理地址的关系
段的定位类型 段起始物理地址 特性 PAGE
(页)xxxx xxxx xxxx 0000 0000
段起始物理地址可被 256 整除 PARA
(节) (默认值)xxxx xxxx xxxx xxxx 0000
段起始物理地址可被 16 整除 WORD
(字)xxxx xxxx xxxx xxxx xxx0
段起始物理地址可被 2 整除 BYTE
(字节)xxxx xxxx xxxx xxxx xxxx
段起始物理地址为任意地址 -
组合类型
多模块程序中,告诉Link.exe同段名、同组合类别、逻辑段如何连接
组合类型 说明 NONE
连接时将不与其它模块中的同名段合并 PUBLIC
该段连接时将与其它同名段连接在一起,连接次序由连接命令指定 STACK
将多个同名堆栈段连接在一起,SP设置在第一个堆栈段的开始 COMMON
该段在连接时与其它同名段有相同的起始地址,所以会产生覆盖 MEMORY
与PUBLIC同义 AT表达式
段地址=表达式的值,其值必为16位但AT不能用来指定代码段 -
类别
多模块程序使用
设定段寄存器伪指令
功能:告诉编译程序(MASM)各个段寄存器当前存放的是哪个段的段地址,但这并不意味着在段寄存器中装入了这些段地址
一般格式:ASSUME 段寄存器名:段名 [, 段寄存器名:段名[,...]]
段寄存器名可以是:CS、DS、ES或SS
应用:完整的代码段定义方法(假设数据段、附加段、堆栈段都已定义):
CODE SEGMENT PARA PUBLIC 'CODE'
ASSUME CS:CODE, DS:DATA, ES:EDATA, SS:STACK
MOV AX,DATA ;取出DATA的段地址送给AX。由于DATA的段地址为立即数,因此不能直接传送给段寄存器
MOV DS,AX ;将数据段的段地址送人DS
MOV AX,EDATA
MOV ES,AX ;将附加段的段地址送人ES
MOV AX,STACK
MOV SS,AX ;将堆栈段的段地址送人SS
.
.
.
CODE ENDS
过程伪指令
功能:实现一部分功能的程序段称为过程,可以用 CALL
调用
一般格式:
过程名 PROC [NEAR/FAR]
.
.
.
RET
过程名 ENDP
过程是近过程(与调用程序在同一代码段),NEAR可以省略;过程是远过程(与调用程序不在同一代码段),FAR不可以省略
例:10ms延时子程序(只展示过程的定义,算法到后续学完汇编再回头看)
DELAY PROC
PUSH BX
PUSH CX
MOV BL, 2
NEXT: MOV CX, 4167
W10MS: LOOP W10MS
DEC BL
JNZ NEXT
POP CX
POP BX
RET
DELAY ENDP
开始伪指令
功能:用于为后续指令指定段内偏移地址,可以方便地将程序存入适当的地址,这一点对中断设计非常有用。
一般格式:ORG 表达式
模块定义与连接伪指令
NAME伪指令
功能:给汇编得到的目标程序一个名字
一般格式:NAME 模块名
前面不允许加标号
TITLE伪指令
功能:为汇编过程产生的列表文件指定一个标题,它不能超过 60 个字符。在列表文件的每一页的第一行将打印出这个标题
一般格式:TITLE 标题名
如果没有NAME和TITLE操作,则汇编程序将源文件的文件名作为目标程序的模块名
END伪指令
功能:表示源程序到此结束,汇编程序结束汇编
一般格式:END [标号]
变量的属性
-
段地址
使用属性操作符获取:
SET
-
段内偏移地址(段内有效地址)
使用属性操作符获取:
OFFSET
例:
DAT3 DB 12, -12 MOV BX, OFFSET DAT1;目的寄存器最好选地址寄存器(BX,BP,SI,DI)
DAT4 DW DAT3;把DAT3的OFFSET存入DW中
演示:
-
类型
DB:1,DW,2,DD:3
使用属性操作符获取:
TYPE
例:
DAT5 DB 12, -12 MOV AL, TYPE DAT5;等价于MOV AL, 1
-
长度
在变量定义语句中,所定义的变量的个数。若在定义时使用
DUP
则重复次数为该语句的长度使用属性操作符获取:
LENGTH
例:
DAT6 DB 12, -12;长度:1 DAT6 DB 4 DUP(?);长度:4
-
大小
在变量定义语句中,所定义的变量的总字节
SIZE=TYPE * LENGTH
使用属性操作符获取:
SIZE
PTR操作符
作用:强制类型转换(临时)
DAT1 DB DUP(?)
MOV AX, DAT1; 错误:DAT1是字节类型(8位),AX是字类型(16位)
MOV AX, WORD PTR DAT1;把DAT1临时(只在本条语句起作用)转换为字类型
类型:
BYTE
(字节)、WORD
(字)、DWORD
(双字)、NEAR
(近程)、FAR
(远程)
MOV [BX], 10H;错误:类型不明确
MOV BYTE PTR [BX], 10H