一、汇编语言概述
1.汇编语言程序的处理过程
2.汇编语言语句
(1)语句类型
- 指令语句:汇编后产生目标代码,可以被CPU执行
- 伪指令语句:不产生目标代码(计算机不执行),主要用于定义段、子程序、变量、常量以及给变量分配存储单元。
- 宏指令语句:是用户定义的一个指令序列集合。
(2)语句格式
对于指令语句:【标号:】 指令助记符 【操作数】【;注释】
对于伪指令语句:【名称】 伪指令指示符 【参数】 【;注释】
- 说明:
- 方括号中的内容为可选项
- 指令助记符(伪指令指示符)与参数之间用空格分隔
- 操作数(参数)之间用逗号分隔
- 操作数(参数)与注释之间用分号分隔
- 名称和标号:以80X86的规则进行说明:
- 可用的符号有数字、字母、特殊符号“?” “$” “@” “_”
- 数字不能放在开头
- 名字长度不能超过31个字符
- 保留字比如操作码、寄存器名等不能作为名字使用。
- 不区分大小写
- 注释:
- 超过一行的注释,每行都必须以分号开头。
3.汇编语言数据项
(1)常量
- 对于数值常数
- 十进制数以D结尾,默认情况可省略。
- 二进制数以B结尾
- 八进制数以Q结尾
- 十六进制数以H结尾,且以字母A ~ F开头的十六进制数,最前面要加0
- 对于字符串常数:用英文引号括起来,他们的数值是每个字符对应的ASCII码值
- 对于符号常数:利用一个名字项符号表达的一个数值。
(2)变量
通常指存放在存储单元中的值
- 第一个属性为段值:变量所在的段地址
- 第二个属性为段内偏移地址:变量所在地址与所在段首地址之间的偏移量
- 第三个属性为类型:指变量中每个元素所包含的字节数,有字节变量(BYTE)、字变量(WORD)、双字变量(DWORD)等
(3)标号
又称符号地址,用来表示指令在主存中的位置。
4.汇编语言表达式
- 表达式:由运算对象和运算符构成的式子。
- 运算对象:可以是常量、变量和标号
- 运算符的分类:
- 算术运算符:包括+、-、×、÷、求余(MOD)、左移(SHL)、右移(SHR)都是双操作数
- 逻辑运算符:包括逻辑乘(AND)、逻辑或(OR)、异或(XOR)、逻辑非(NOT),最后一个为单操作数运算符。
- 关系运算符:包括EQ(相等)、NE(不相等)、LT(小于)、GT(大于)、LE(小于等于)和GE(大于等于)6种。
注意:关系运算符连接的两个运算对象必须都是数字或同一段内的存储器地址,运算规则为:如果两个运算对象的关系成立,结果为全“1”,否则为全“0”。 - 取值运算符:包括SEG(返回段基址)、OFFSET(返回偏移地址)、TYPE(返回元素字节数)、LENGTH(返回变量单元数)、SIZE(返回变量总字节数)。
注意:取值运算符的操作数必须是存储器操作数,即变量或地址标号。 - 合成运算符:包括PTR(修改类型属性)、THIS(指定类型/距离属性)、SHORT (短转移说明)
- 分离字节运算符:包括HIGH (分离高字节)、 LOW (分离低字节)
- 运算符优先级:
二、80X86汇编语言伪指令
1.数据定义伪指令
- 格式:[变量名] <类型> [;注释]
- 变量名:可选项,代表所定义的第一个单元的地址
- 类型:说明初值表中每个数据占几个字节,有如下几个类型:
DB:字节型,其后的每个初值占1字节
DW:字型:其后的每个初值占2字节,低字节在低地址
DD:双字型:其后的每个初值占4字节,低字节在低地址
DQ:四字型:其后的每个初值占8字节,低字节在低地址
DT:五字型:其后的每个初值占10字节,低字节在低地址 - 功能:为源程序中的数据和堆栈区分配数据存储单元,定义变量类型,并为可分配的存储单元赋值。
- 举例:
D1 DB 23H,11H,33H
D2 DW 110*230
D3 DB ‘GOOD!’
D4 DD 2.4E+3
S1 DB 5 DUP(?) 为S1预留5个字节的存储空间,初值不确定。DUP是重复数据操作符
2.符号定义伪指令
(1)等值伪指令EQU
- 格式:<符号名> EQU <表达式>
- 功能:用来给数值、字符串或表达式定义一个等价的符号。
- 举例:
TIMES EQU 50 TIMES代表50
DATA DB TIMES DUP(?)
GREETING EQU ‘How are you!’ - 注意:符号定义可以写在程序的任何地方,符号一经定义,不可再重复
(2)等号伪指令“=”
- 格式: <符号名> = <表达式>
- 功能:功能与EQU 类似
ABC = 10 + 200 * 5
ABC1 = 5 * ABC + 21 - 注意:EQU 与 =的区别
- EQU定义的符号名不能与其他符号名不能重名且不能重新定义,但=定义的符号名可以重名,也可以被重新定义、重新复制
- EQU定义的符号名不仅可以代表某个常数或常数表达式,还可以代表字符串、关键字、指令码等,但=定义的符号名仅用于代表数值表达式
(3)符号定义伪指令LABEL
- 格式:<符号名> LABEL <数据类型>
- 功能:与存储单元合成操作符THIS功能类似,为当前存储单元定义一个指定类型的变量或标号
- 举例:
A1 LABEL WORD
A2 DB 200DUP(?)
3.段和过程定义伪指令
(1)段定义伪指令SWGMENT/ENDS
- 格式:
<段名> SEGMENT [定位类型] [组合类型] [‘类别’]
<段内语句序列>
<段名> ENDS - 段名:由编程者指定
- 定位类型:用来规定对段起始边界的要求:
PAGE:段起始地址的最低8位必须是0,即从页边界开始;
PARA:段起始地址的最低4位必须是0,即从一个节边界开始;(默认)
WORD:段起始地址最低1位必须是0,即从字边界开始,段的起始地址为偶数;
BYTE:段起始地址为任意值,即从字节边界开始 - 组合类型:为连接程序提供信息的,用于指示连接程序当前端是否与其他段进行连接:
NONE:表示本段与其他逻辑段上不发生关系(默认)
PUBLIC:表示连接程序首先将本段与其他同名同类别的段相邻地连接在一起,然后为所有这些PUBLIC段指定一个共同段基址,连接的先后次序由连接命令指定
STACK:和PUBLIC功能一样,但用于堆栈段,定义堆栈段必须有
COMMON:所有同名同类型段具有相同段地址,但后面的会覆盖前面的,用于共享数据。
AT表达式:表示本段的起始地址由表达式的值给出
MEMORY:将本段定义在其他段之后 - 类别:类别名是用户自定义的标识符,必须用单引号引起来,连接程序会把类别名相同的所有段装入内存的连续区域
- 举例:用段定义伪指令定义一个数据段
DATA SEGMENT
BUF DB 10H , 20H
BUF1 DW 10H , 20H
DATA ENDS - 注意:
代码段和数据段必须定义
CS寄存器不需要初始化
(2)假定伪指令ASSUME
- 格式:ASSUME <段寄存器名> : 段名 [,段寄存器名: 段名,…]
- 功能:建立段寄存器和源程序中各个段之间的关系
- 举例:ASSUME CS: CODE,DS:DATA,SS:STACK
(3)过程定义伪指令
- 格式:
过程名 PROC [NEAR]/FAR
过程体
RET
过程名 ENDP - PROC:表示过程的开始
- ENDP指示过程的结束
- NEAR/FAR:若所定义的过程为段内调用,使用NEAR进行说明,若为段间调用过程,使用FAR进行说明
- RET:返回指令,RET不一定是定义过程中最后一条指令,但一定是最后被执行的指令
- 说明:具有一定功能的程序段看成一个过程(相当于一个子程序),可以被其他程序调用(CALL指令)或者说JMP指令转移。
- 举例:设计一个延时的子程序,循环程序执行10000次
SOFTDLY PROC ;过程开始
MOV BL,10 ;外循环次数为10
DELAY:MOV CX,1000 ;内循环次数为1000次
WALT1:LOOP WAIT1 ;循环指令
DEC BL ;减量指令
JNZ DELAY ;不等于0时跳转
RET
SOFTDLY WNDP
(4)程序结束伪指令END
汇编程序对END之后的语句不予处理
三、系统功能调用和程序的动态调试
1.系统功能调用
DOS擦做系统主要包括设备管理、目录管理和文件管理三方面的功能,所有系统功能的调用格式是一致的,分为以下4步。
- 在AH寄存器中设置系统功能调用号
- 在指定寄存器中设置入口参数
- 用INT 21H指令执行功能调用
- 根据出口参数分析功能调用执行情况
(1)单个字符输入(1号功能调用)
- 格式:
MOV AH ,1
INT 21H - 功能:等待用户通过键盘输入一个字符,并将输入字符的ASCII码送入AL寄存器中,同时将该字符显示在显示器上。
- 说明:无入口参数,出口参数:AL ← 键入字符的ASCCI码
- 举例:判断键盘输入的字符是a还是b
GETKEY:MOV AH,01H
INT 21H
CMP AL,‘a’ ;比较指令
JE YESKEY ;结果是a
CMP AL,‘b’
JE NOKEY ;结果是b
JNE GETKEY ;都不相等
(2)单个字符显示(2号功能调用)
- 格式:
MOV AH,2
MOV DL,<字符的ASCII码>
INT 21H - 功能:在屏幕当前位置显示DL寄存器中的字符,并将光标移后一格
- 说明:入口参数:DL ←显示字符的ASCII码,无出口参数
- 举例:在显示器上显示字符A
MOV AH,2
MOV DL,‘A’
INT 21H
(3)字符串输出(9号功能调用)
- 格式:
MOV AH,9
MOV DX
INT 21H - 功能:将当前数据区DS:DX所指向的字符串输出到显示器上,字符串以’$'结尾
- 说明:入口参数:DS:DX ←字符串首地址,无出口参数
- 举例:
MOV AH,09H
MOV DX,OFFSET D3 (D3为字符串的存放区)
INT 21H
(4)字符串输入(10号功能调用)
- 格式:
MOV AH,10
MOV DX,<字符串首地址>
INT 21H - 功能:从键盘接收一个字符串,并存入用户定义的输入缓冲区内,遇回车键结束输入
- 说明:入口参数:DS:DX ←缓冲区首地址,无出口参数
- 举例:
MOV AH,0AH
MOV DX,OFFSET D2 (D2为字符串存放区)
INT 21H
(5)4CH号功能调用
- 功能:由.EXE文件返回DOS
- 调用:
MOV AH,4CH
INT 21H
2.程序的实现
- 一个源程序必须至少包含一个代码段和END伪指令
- 数据段、附加段和堆栈段可以视程序的具体功能而定
- 操作系统在装载没有堆栈段的程序时,会指定一个段作为堆栈段
- 段地址的装入
- CS不需要装入,系统自动完成
- 若堆栈段定义时,给出了参数STACK,自动完成
- DS、ES必须装入
3.程序的调试
- R:查看寄存器
- RF:查看标志寄存器
- D:查看主存
- U:反汇编命令
- T:单步操作
- G:执行命令
- Q:退出调试
四、80X86汇编语言程序结构
1.顺序结构 2.分支程序 3.循环程序 4.子程序