20192416汇编语言学习总结
第一章 基础知识
1.1 汇编语言的一般概念
1.机器语言
机器语言就是把控制计算机的命令和各种数据直接用二进制数码表示的一种程序设计语言
特点:运行速度快,程序长度短,但内容不便于记忆且难于阅读
2.高级语言
使用类似于自然语言的一些语句来编制程序
特点:程序设计简单,但程序效率较机器语言低
3.汇编语言
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。在汇编语言中,用助记符代替机器指令的操作码,用地址符号或标号代替指令或操作数的地址。在不同的设备中,汇编语言对应着不同的机器语言指令集,通过汇编过程转换成机器指令。特定的汇编语言和特定的机器语言指令集是一一对应的,不同平台之间不可直接移植。
1.2 学习和使用汇编语言的目的
从根本上认识、理解计算机的工作过程
1.3 进位计数制及其相互转换
1.进位计数制
使用一定个数的数码的组合来表示数字,这种表示方法成为进位计数制
位权:一个数的各个位置上所表示的基本数值,简称权
基数:每个数位上能使用不同数码的个数称为基数,例如十进制基数为10,二进制基数为2
在计算机中数据表示一般采用二进制数,对人来说二进制不便于书写和阅读,因此书写时常使用8进制和16进制
在书写不同进位计数制数时,为了区别,在数的尾部用一个字母来表示对应的进制
B(Binary)——二进制数
O(Octal)或Q——八进制数
D(Decimal)——十进制数
H(Hexadecimal)——十六进制数
若未使用字母,则默认为十进制数
2.各种数制间的相互转换
十进制整数转换为二进制数:减权定位法、除基取余法、减权定位法、乘积取整法
二进制整数转换为十进制数:按权相加法、逐次乘基相加法、按权相加法、逐次除基相加法
1.4 带符号数的表示
1.原码
二进制数的最高位表示符号,0表示正,1表示负。数值部分用二进制数绝对值表示
2.补码
带符号数X的补码表示[X]补定义:[X]补 = M+X(Mod M),其中M为机器数的位数
对于正数,补码与原码相同,对于负数,将真值的各位取反再加一即可得到补码;或者将原码的符号位保持不变,其余各位取反再加一即可得到补码
[X+Y]补 = [X]补+[Y]补
[X-Y]补 = [X]补-[Y]补 = [X]补+[-Y]补
1.5 字符的表示
1.ASCII码
标准ASCII码为一字节,其中用低七位表示字符编码,用最高位作为奇偶校验位
标准ASCII码共有128个
1.6 基本逻辑运算
计算机内部采用二进制数表示信息,而“0”和“1”正好对应逻辑“真”和“假”两个状态。
包括:
“与”运算
“或”运算
“非”运算
“异或”运算
第二章 IBM-PC微机的功能结构
2.1 IBM-PC微机基本结构
1.微机的一般构成
微机的一般构成:运算器、控制器、存储器、输入和输出设备
其中将运算器和控制器两大部件集成在一个集成电路芯片上,称为中央处理器,简称CPU
系统采用总线结构,系统总线分为地址总线、数据总线、控制总线三类
2.Intel 8086/8088 CPU的功能结构
汇编语言程序由一系列的指令(指令序列)构成。
CPU执行指令序列就是重复“取指令——执行指令”两个步骤
串行方式特点:系统总线空闲时间较多,大部分时间处于闲置状态
指令流水线方式特点:减少了系统总线的空闲时间
2.2 Intel 8086/8088CPU寄存器结构及其用途
1. 段寄存器
需执行程序的各部分(指令代码、数据、堆栈)分别放在主存的指定段中。
段寄存器:用来存放每个段的段基值,即段基址的高16位,每个段寄存器有特定功能,不能互换。
当前段:由CS、DS、SS、ES指向的段,如图:
CS ----- 代码段用来存放程序的指令代码序列,CS用来存放当前代码段首址的高16位,即段基值。
DS ----- 数据段用来存放程序的有关数据,DS用来存放当前数据段的段基值。
SS ----- 堆栈段用来存放按后进先出顺序存取的信息,SS用来存放当前堆栈段的段基值。
ES ----- 附加段用来存放运算结果或辅助数据,ES用来存放当前附加段的段基值。
2. 通用寄存器
8个16位通用寄存器按使用情况分为三种:指针寄存器、变址寄存器、数据寄存器。
(1)指针寄存器:主要提供全部或部分偏移量
SP:专门存放堆栈段中栈顶单元的偏移量。
BP:存放堆栈段中某个单元的全部/部分偏移量,也可存放16位操作数或运算结果。
(2)变址寄存器
SI/DI:存放主存操作数的全部/部分偏移量,也可存放16位操作数和结果,在多数情况功能可以互换。 但在串操作指令中作用不能互换,源操作数必须用SI提供偏移量,目的操作数必须用DI提供偏移量。
(3)数据寄存器
数据寄存器既可以作为4个16位的寄存器,也可以作为8个8位的寄存器 ,(H表示高字节,L表示低字节)。
程序中,数据寄存器用来存放操作数、运算结果或其他信息。
3. 控制寄存器
指令指针IP和标志寄存器FR
(1)指令指针IP(16位)
CS提供指令地址的段基值,IP提供偏移量,CS的内容左移4位,与IP中偏移量相加,形成下一指令首字节的存储单元地址。
(2)标志寄存器FR(16位) —— 用来记录程序执行时的状态
-----进位标志位CF(Carry Flag)
算术运算:结果最高位有进位/借位置‘1’
移位操作:存放移出的位
-----奇偶标志位PF(Parity Flag)
结果低8位中‘1’的个数为偶数置‘1’
-----辅助进位标志位AF(Auxiliary Carry Flag)
低字节中的低4位产生进位/借位置‘1’
-----零值标志位ZF(Zero Flag)
运算结果为全0置‘1’;不为零置‘0’
-----符号标志位SF(Sign Flag)
带符号数运算结果为负置‘1’;为正置‘0’
-----溢出标志位OF(Overflow Flag)
运算结果N发生溢出时,OF置‘1’,即 字节运算(8位) :N ≤ -129 或 N ≥ 128; 字运算(16位): N ≤ -32769 或 N ≥ 32768
-----单步标志位TF(Trace Flag)
TF=1时,CPU执行完一条指令后产生单步中断,进入单步中断程序
-----中断标志位IF(Interrupt-enable Flag)
IF=1时,允许CPU响应可屏蔽中断请求
-----方向标志位DF(Direction Flag)
规定串操作指令中串地址的增减方向:DF=0时,SI/DI内容自动递增;DF=1时,SI/DI内容自动递减
为了便于了解微处理器各个寄存器的情况,将所有寄存器集成到一起,如图所示:
2.3 存储器的组织结构
存储器的组成
不管是临时存储器还是永久存储器,存储器的组成结构都是一样的,所不同的只是实现材料和实现工艺,因为材料和工艺而不同,一个是临时存储的,另一个是永久存储的。
1.例子:3*8存储器结构
不论哪种存储器(临时还是永久的),都必须有数据线,地址线,控制线,比如以3*8的存储器为例来介绍存储器的结构
图:3*8存储结构
三根地址线A0,A1,A2,三根地址线可以产生2^3=8个地址。
一些重要概念
(1)存储单元
存储单元的字节数=数据线数量 / 8
比如前面的3*8存储器,存储单元字节数 = 8 / 8,刚好等于1字节。
(2) 字与字长
a.字指的就是一个存储单元
b.字长就是存储单元的字节数
比如还是以3*8的存储器为例,
字长 = 存储单元的字节数 = 数据线根数 / 8 = 1.
- 存储容量的计算和存储单位
(1)如何计算存储容量大小
计算总容量,其实就是计算总的字节数,所以,
总的字节数= 地址数量*字长(存储单元的字节数)
地址数量 = 2^地址线数量, 字长 = 数据线根数 / 8,最后,
总的字节数 = 2^地址线数量 * 数据线根数 / 8
2.4 堆栈及其操作方法
堆栈是一个特定的存储区,访问该存储区一般需要按照专门的规则进行操作
堆栈的用途:主要用于暂存数据以及在过程调用或处理中断时保存断点信息
堆栈的构造
堆栈一般分为:专用堆栈存储器和软件堆栈
堆栈的一端是固定的,称为栈底,是存储器的最大地址单元
另一端是浮动的,称为栈顶,随着堆栈中存放信息的多少而改变
为了确定栈顶的位置,通常使用堆栈指针SP指示栈顶
堆栈存取数据的规则:“先进后出FILO”
8086/8088堆栈的组织
当SP被初始化时,指向栈底+2单元,其值就是堆栈的长度
指向栈底+2单元的原因是当栈为空的时候,栈中没有元素,也就不存在栈顶元素,所以SP只能指向栈的最底部单元下面的单元,该单元的偏移地址为栈最底部的字单元的偏移地址+2
数据在堆栈中存放格式:以字(两字节)为单位存放,数据的低8位放在较低地址单元,高8位放在较高地址单元
第三章 寻址方式与指令系统
3.1 寻址方式
寻址方式:寻找指令中所需操作数的各种方法,也就是提供指令中操作数的存放信息的方式
Intel 8086/8088各指令中提供操作数的方法有一下四种:
立即数操作数——操作数在指令代码中提供。立即数可以是8位,也可以是16位
寄存器操作数——操作数在CPU的通用寄存器或段寄存器中
存储器操作数——操作数在内存的存储单元中
I/O端口操作数—— 操作数在输入/输出接口的寄存器中
存储器存储单元的逻辑地址由端基值和偏移量组成。
由于需要考虑系统的向下兼容,所以现在的计算机一般采用段地址*16加上段内偏移地址计算出20位的物理地址,由于偏移地址长度最大为16位,所以段也有大小,一般为64kb。
寻址方法一般有:立即寻址、寄存器寻址、直接寻址、寄存器间接寻址、寄存器相对寻址、基址变址寻址等等。
3.2 指令系统
一种计算机所能执行的各种类型的指令的集合称为该计算机的指令系统
1、标志位操作指令:对CF、IF、DF进行操作
这些指令都是无操作数指令,指令中未直接给出操作数的地址,但隐含指出操作数在标志寄存器的某些标志位上,能直接操作的标志位有CF、IF、DF。
(1)、清除进位标志指令 (Clear carry flag)
CLC ;置CF=0
(2)、进位标志置位指令 (Set carry flag)
STC ;置CF=1
(3)、进位标志取反指令 (Complement carry flag)
CMC ;CF取反
(4)、清除方向标志指令 (Clear direction flag)
CLD ;置DF=0
(5)、方向标志置位指令 (Set direction flag)
STD ;置DF=1
(6)、清除中断标志指令 (Clear interrupt-enable flag)
CLI ;置IF=0
(7)、中断标志置位指令 (Set interrupt-enable flag)
STI ;置IF=1
2、与外部事件同步的指令
(1)、HLT ;停机指令
(2)、WAIT ;等待指令
(3)、ESC ;外部协处理器指令的前缀
(4)、LOCK ;总线封锁前缀指令
3、空操作指令
指令格式: NOP
该指令使CPU执行一次空操作,占3个时钟周期,不影响寄存器、存储单元及标志位。
3.3 指令编码
汇编:将汇编语言程序转换为机器语言程序的过程
汇编程序:在计算机中实现汇编过程的系统程序
Intel8086/8088汇编指令的编码格式有四种基本格式:
双操作数指令编码格式
操作数可以是以下两种情形:
一个操作数在寄存器中,另一操作数在寄存器或存储器中
目的操作数在寄存器或存储器中,源操作数是立即数
这类指令的机器目标代码长度为2~6个字节。整个指令编码可以包含4个部分,但其中某些部 分在一些指令的编码中可以没有:
操作特征部分:OPCODE操作码字段+方向字段d+字/字节字段W
寻址特征部分:MOD+REG+R/M
位移量部分:根据寻址特征中MOD和R/M字段确定的有效地址计算方法,位移量可以是:
没有位移量
1字节位移量disp8
2字节位移量disp16
立即数部分:总是位于指令编码的最后1~2字节
单操作数指令编码格式
指令编码为2~3字节,包括操作特征、寻址特征和位移量三部分
操作特征部分:OPCODE+V(移位/循环指令限定)+W
V=0时,指令中使用常数1作为移位或循环次数
V=1时,指令中使用寄存器CL作移位次数
与AX或AL有关的指令编码格式
用于隐含指定AX/AL作为一个操作数的双操作数指令。采用这种编码格式的指令,除一个操作数隐含指定为AX/AL外,另一个操作数可以是立即数或存储单元
其它指令编码格式
如标志位操作指令、堆栈操作指令等。这些指令的编码格式一般只有一个字节
第四章 汇编语言程序格式
4.1 汇编语言语句种类及其格式
汇编语言的语句可以分为指令语句和伪指令语句
指令语句:每一条指令语句在汇编时都要产生一个可供CPU执 行的机器目标代码,它又叫可执行语句。一条指令语句最多可以包含4个字段:标号字段、指令助记符字段、操作数字段、注释字段
伪指令语句:又叫命令语句。伪指令本身并不产生对应的机器目标代码。它仅仅是告诉汇编程序对其后面的指令语句和伪指令语句的操作数应该如何处理。一条伪指令语句可以包含四个字段:符号名字段、伪指令符字段、操作数字段、注释字段
标识符:指令语句中的标号和伪指令语句中符号名统称为标识符。标识符是由若干个字符构成的
4.2 汇编语言数据
数据是指令和伪指令语句中操作数的基本组成部分。一个数据由数值和属性两部分构成
在汇编语言中常用的数据形式有:常数、变量和标号
常数:在汇编期间其值已完全确定,并且在程序运行过程中,其值不会发生变化
变量:变量用来表示存放数据的存储单元,这些数据在程序运行期间可以被改变
标号:标号写在一条指令的前面,它就是该指令在内存的存放地址的符号表示,也就是指令地址的别名
4.3 符号定义语句
在源程序设计中,使用符号定义语句可以将常数或表达式等内容用某个指定的符号来表示。在8086/8088汇编语言中有两种符号定义语句:
等值语句。语句格式:符号名 EQU 表达式
功能:用符号名来表示EQU右边的表达式。后面的程序中一旦出现该符号名,汇编程序将把它替换成该表达式。表达式可以是任何形式,如:常数或数值表达式、地址表达式、变量、寄存器名或指令助记符
等号语句。语句格式:符号名=表达式
功能:与等值语句具有相同的作用。但等号语句可以对一个符号进行多次定义
4.4 表达式与运算符
表达式是指令或伪指令语句操作数的常见形式。它由常数、变量、标号等通过操作运算符连接而成
8086/8088宏汇编语言中的操作运算符可以分为五类:
算术运算符
包括:+、—、*、 / 、MOD、SHL、SHR、[ ]
逻辑运算符
包括:NOT、AND、OR和XOR等
关系运算符
包括:EQ(等于)、NE(不等于)、LT(小于)、 LE(小于等于)、GT(大于)、GE(大于等于)
数值返回运算符,用于将变量或标号的某些特征值或存储单元地址的一部分提取出来
包括:SEG运算符、OFFSET运算符、TYPE运算符、LENGTH运算符、SIZE运算符
属性修改运算符,用来对变量、标号或存储器操作数的类型属性进行修改或指定
包括PTR运算符、HIGH/LOW运算符、THIS运算符
4.5 程序的段结构
8086/8088在管理内存时,按照逻辑段进行划分, 不同的逻辑段可以用来存放不同目的的数据。在程序中使用四个段寄存器CS,DS,ES和SS来访问它们。在源程序设计时,使用伪指令来定义和使用这些逻辑段。
段定义伪指令
伪指令SEGMENT和ENDS用于定义一个逻辑段。使用时必须配对,分别表示定义的开始与结束
段寻址伪指令
段寻址伪指令ASSUME的作用是告诉汇编程序,在处理源程序时,定义的段与哪个寄存器关联。ASSUME并不设置各个段寄存器的具体内容,段寄存器的值是在程序运行时设定的
段寄存器的装入
段寄存器的初值(段基值)装入需要用程序的方法来实现。四个段寄存器的装入方法略有不同
DS和ES的装入:
在程序中,使用数据传送语句来实现对DS和ES的装入
SS的装入:
在段定义伪指令的组合类型项中,使用STACK参数,并在段寻址伪指令ASSUME语句中把该段与SS段寄存器关联,如果在段定义伪指令的组合类型中,未使用STACK参数,或者是在程序中要调换到另一个堆栈,这时,可以使用类似于DS和ES的装入方法
CS的装入:
CPU在执行指令之前根据CS和IP的内容来从内存中提取指令,即必须在程序执行之前装入CS和IP的值。因此,CS和IP的初始值就不能用可执行语句来装入