20192415 2021-2022-2 《汇编程序设计》第1-4章学习总结
20192415 2021-2022-2 《汇编程序设计》第1-4章学习总结
第一章 基础知识
1.1 汇编语言的一般概念
计算机程序设计语言可分为以下三类:
-
机器语言
-
机器能够识别的语言。
-
01构成的信息数据指令等。包含指示运算功能的代码+参加运算的操作数据,表示非常详细。
-
最直接地表示了计算机内部的基本操作,用它编制的程序在计算机中运行的效率最高(运行速度最快,程序长度最短)。
-
-
高级语言
- 屏蔽计算机内部操作细节,类似自然语言,设计简单,但程序效率较机器语言低。
-
汇编语言
-
字母和符号表示机器语言的命令+十进制数或十六进制数表示数据。
-
在计算机系统中,某些功能必须用汇编语言程序来实现(如:机器自检、系统初始化等)。
-
1.2 汇编语言程序与机器语言程序的关系
一条汇编语言语句对应一条机器语言指令,汇编语言程序与机器语言程序效率相同。
效率:机器语言=汇编语言>高级语言
不同类型计算机有不同的机器指令系统和汇编语言描述。汇编语言与硬件密切联系。
1.3 进位计数制及其相互转换
在计算机中数据表示一般采用2进制数,人书写时常使用8进制和16进制。
1.4 带符号数的表示
真值用“+”“-”表正负,机器数用“0”“1”表正负。
-
带符号的机器数可以用原码、反码和补码表示。一般计算机中大多采用补码表示。
-
0的表示
-
原码:0 0000000 和 1 0000000
-
补码:0 0000000(1 0000000为-128或-1的补码)
-
反码:0 0000000 和 1 1111111
-
-
转化为补码
-
正数
与原码相同,符号位为0,数值为二进制绝对值
-
负数
真值→补码
(先补齐,最高位必然为0,取反后为1)各位取反后加一
原码→补码
符号位不变,其余取反后加一 或 自低向高,第一个“1”和右侧“0”不变,其他位取反,符号位不变
-
-
补码的加减运算
-
[X+Y]补=[X]补+[Y]补
-
[X-Y]补=[X]补-[Y]补=[X]补+[-Y]补
-
计算机内一般使用补码运算(当运算结果不超机器范围时):
1.符号位参与运算,符号位进位自然丢掉 2.求补运算[-Y]:将原数连同符号位一起(不管是正还是负)按位取反后加一。 3.用补码相加,和仍为补码
-
1.5 字符的表示
字符(字母、符号、数字码)按一定的方式编写成二进制信息。
不同的计算机以及不同的场合所采用的编码形式可能不同。
目前最广泛采用的是ASCII码。
-
标准ASCII码
共有128个。
每个为1字节,低7位表示字符编码,最高位表示奇偶数验位。
-
非打印ASCII码
共33个,用于控制操作, 如BEL(响铃07H)、DEL(删除7FH)、CR(回车,0DH、LF( 换行,0AH);
-
可打印ASCII码
共95个,如数字符0~9,大小写字母等。
注:0F0H,当十六进制第一个字符是字母的话前面加0
第二章 IBM-PC微机的功能结构
2.1 微机一般结构
一、微机的一般构成
一般计算机包括五大部件:运算器、控制器、存储器、输入设备和输出设备。
总线分为3种,是计算机内部不同部件之间的传输通道,起控制+传输作用。
-
1.中央处理器CPU(微处理器)= 运算器+控制器
分析从主存储器取来的各条指令的功能,控制计算机各部件完成指定功能的各项操作。
-
2.主存储器(主存/内存)
存放程序和数据;由存储单元构成,存储单元使用地址来标识,按地址进行存储单元内容的存和取。
大多数计算机存储器以字节为基本单位。每一个基本单位称为一个存储单元。
指示存储单元编号的地址长度决定了存储器的最大容量,
例如一个10位二进制数表示的地址,可以用来区分1024=1K个单元。
CPU+主存储器=主机
辅存储器(辅存/外存):主存副本;当前不在运行的程序+数据
-
3.输入输出设备及接口
输入设备将外部信息(程序、数据和命令)送入计算机。
输出设备将计算机处理后的结果转换为人或其它系统能识别的信息形式向外输出。
有的设备既具有输入功能又具有输出功能。
I/O设备要通过I/O接口才能与系统总线连接。
-
4.系统总线
二、Intel 8086/8088 CPU
CPU执行指令序列:从存储器中取指令+执行指令规定的操作
这两个步骤的执行分为串行方式和指令流水线方式。
-
1.串行方式
CPU指令执行阶段,不占用系统总线,系统总线的空闲时间多;
从存储器取指令、取存数据时,总线忙而CPU花费时间很短,大部分时间闲置。
采用串行工作方式的计算机其运行速度较慢。
-
2.指令流水线方式
CPU被划分成两个单元:执行单元(EU)+总线接口单元(BIU)
两者分工又合作,并行加快指令执行速度。
-
EU——分析与执行指令:
A 从指令队列中取出指令代码,由控制器译码后产生相应的控制信号,控制各部件完成指令规定的操作。 B 对操作数执行各种指定的算术或逻辑运算。 C 向总线接口单元BIU发送访问主存或I/0的命令,并提供相应的地址和传送的数据。
-
BIU负责CPU与存储器、I/O的信息传送:
A 取指令——根据CS寄存器和指令指针IP形成20位的物理地址,从相应的存储器单元中取出指令,暂存到指令队列中,等待EU取走并执行。 B 存取数据——在EU执行指令的过程中,需要与存储器或I/O端口传送数据时,由EU提供的数据和地址,结合段寄存器,通过外部总线与存储器或I/0。
2.2 寄存器结构及其用途
一、通用寄存器 8个
-
数据寄存器*4
结构:H高位L地位,16位长的寄存器可以分为2个8位
存放:参加运算的操作数/运算的结果
使用:多数需明确指示;有些隐含使用;个别特定使用
-
指针寄存器*2
存放16位地址,在形成20位的物理地址时常被作为偏移量使用。
-
堆栈指针SP:进行堆栈操作时被隐含使用,用来指向堆栈顶部单元。
-
基址指针BP:用来指向堆栈段内某一存储单元。也可以存放操作数和运算结果。
-
-
变址寄存器*2
16位,一般被用来作地址指针,也可以用作通用数据寄存器存放操作数和运算结果。
-
源变址寄存器SI
-
目的变址寄存器DI
-
二、段寄存器 4个
CPU访问存储器时需要知道段基址和偏移量。段寄存器存储段基址。
CPU在使用存储器时,将它划分成若干个段,每个段用来存放不同的内容(程序代码、数据等)。
程序设计中,一个程序将存储器划分成多少个存储段是任意的;程序运行的任何时刻,最多只有4个段,分别由CS、DS、ES和SS指定。
三、指令指针IP
CPU从存储器取指令时,IP内容作为偏移量。
当CPU从内存中取出一条指令后,IP内容自动修改为指向下一条指令。
不能用指令给IP赋值,但可通过某些指令的执行而自动修改IP的内容。如:
四、标志寄存器
用来反映CPU在程序运行时的某些状态,如是否有进位、奇偶性、结果的符号、结果是否为零等。
标志寄存器的长度为16位,但只定义了其中的9位。
其中,CF、PF、AF、ZF、SF、OF为状态标志;TF、DF、IF为控制标志。
-
1.进位标志位CF
算术运算,若最高位(字第15 位,字节第7位)产生进位或借位时,CF置1否则置0;
移位类指令,CF被用来存放从最高位(左移时)或最低位(右移时)移出的数值(0或1)。
-
2.奇偶标志位PF
指令操作结果的低8位中含有1的个数为偶数时,PF置1否则置0。
-
3.辅助进位标志位AF
算术运算,若低字节的低4位向高4位产生进位或借位,AF置1否则置0;
AF标志位用于十进制运算的调整。
-
4.零值标志位ZF
运算结果各位全为0,ZF置1否则置0。
-
5.符号标志位SF
将运算结果视为带符号数,运算结果为负数SF置1、为正数SF置0。
第7位是字节操作数的符号位,第15位是字操作数的符号位,因此SF位与运算结果的最高位相同。
-
6.溢出标志位OF
当运算结果超过机器用补码所能表示数的范围时,OF置1否则置0。
字节数据补码表示范围:-128 ~+127。
字数据补码表示范围为:-32768 ~+32767
-
7.单步标志位TF
单步标志也叫跟踪位,供调试程序使用。
当TF=1时,每执行一条指令后CPU暂停运行,即产生单步中断。
-
8。中断允许标志位IF
当IF=1时,CPU可以响应可屏蔽中断,否则不允许响应可屏蔽中断。
-
9.方向标志位DF
DF被用来规定串操作指令的增减方向。
当DF=0时,串操作指令自动使变址寄存器(SI和DI)的内容递增。
当DF=1时,串操作指令自动使变址寄存器的内容递减。
注:进位和溢出完全不同
进位标志表示无符号数运算结果是否超出范围,运算结果仍然正确;
溢出标志表示有符号数运算结果是否超出范围,运算结果已经不正确。
判断运算结果溢出的简单规则:当两个相同符号数相加,运算结果符号与原数据符号相反时,产生溢出,运算结果不正确。其他情况下,不会产生溢出。
2.3 存储器组织结构
一、存储器的组成
存储器是由若干个存储单元构成,一个存储单元的长度一般为1个字节。
每个存储单元有一个唯一的地址编号。若有20根地址线,则可产生20位的地址码,存储器寻址能力为1兆字节空间。
在定义一个地址时必须指出是字节或字类型属性。存储单元可分为字单元和字节单元,而访问内存的指令分为字节访问和字访问两种指令。
任何两个相邻字节单元就构成一个字单元(WORD)。字单元的地址为两个字节单元中较小地址字节单元的地址。16位长数据的存放规则是低8位放在较低地址字节单元中,高8位放在较高地址字节单元中。
二、存储器的段结构
8086/8088CPU将1MB的存储空间划分成若干个段,每个段最大长度为64K(2^16)个字节组成。
在存储器中规定从0地址开始,每16个字节称为一个小节。1MB内存就可划分为64K个小节。每个段的基址必须是一个小节的首址(小节首址最低位必为0)。
内存中的一个物理存储单元可以映象到一个或多个逻辑段(在汇编语言源程序中设置的段)中。逻辑段在物理存储器中可以是邻接的、间隔的、部分重叠的和完全重叠的等4种情况。
在任一时刻,一个程序只能访问4个当前段(代码段、数据段、堆栈段和附加段,由4个段寄存器CS、DS、SS和ES分别保存段基值)中的内容。
三、 逻辑地址与物理地址及对应关系
-
物理地址
在存储空间中,每个存储单元的物理地址是唯一的。
-
逻辑地址
在程序设计中,为便于程序开发和对存储器进行动态管理,使用了逻辑地址。
逻辑地址=段基值+偏移量
对于一个64K的段,偏移量为0FFFFH时,就是这个段的最后一个字节单元。
-
逻辑地址转换为物理地址
CPU访问存储器时,由BIU将逻辑地址转物理地址。
方法:段基值左移4位补0+16位的偏移量
-
逻辑地址的来源
允许替代来源(段超越):段基值除使用隐含的段寄存器外是否可以指定其它段寄存器提供。
有效地址EA:根据指令所采用的寻址方式计算出来的段内偏移量。
2.4 堆栈及其操作方法
堆栈是一个特定的存储区,存取时先进后出,主要用于暂存数据、在过程调用或处理中断时保存断点信息。
-
分类:专用堆栈存储器、软件堆栈(用软件在内存中划出)。
-
结构:
栈底固定,堆栈存储区的最大地址单元;栈顶浮动,随存放信息的多少而改变。 堆栈指针SP始终指向栈顶单元,堆栈中数据进出都由SP控制。 SP为堆栈段基址与栈顶之间的距离(字节数)。 当SP内容为最大(初始)值时,堆栈为空(SP指向栈底+2单元,其值是堆栈长度,堆栈长度小于等于64K字节);当SP=0时,堆栈全满。 改变堆栈段寄存器SS的内容,即可改变到另一个堆栈段;当改变了SS的内容后,必须紧接着赋予SP新值。
-
操作:设置堆栈赋值SS和SP;进栈PUSH;出栈POP。
第三章 寻址方式与指令系统
3.1寻址方式
指令=操作码+操作数
寻址方式:: 寻找指令中所需操作数的各种方法。
-
立即数操作数 操作数包含在指令代码中。
立即数作为指令的一部分直接从BIU的指令队列中取出,不需另外占用总线周期,执行速度快。
立即数只能作为源操作数,而不能作为目的操作数。
-
寄存器操作数 操作数在CPU的通用寄存器或段寄存器中。
寄存器可以是8位或16位通用寄存器,或者是段寄存器。
存取寄存器操作数完全在CPU内部进行,不需要总线周期,执行速度很快。
-
直接寻址
EA 从 位移量(可用符号或常数表示)获得
注:用常数表示时,必须用方括号括起来。段寄存器不能省略。
-
寄存器间接寻址
EA 从 基址寄存器(BX或BP)或 变址寄存器(SI或DI)获得
注:指令使用BP寄存器,隐含使用SS段寄存器;其余隐含使用DS段寄存器。
-
基址寻址/变址寻址
EA = 基址分量或变址分量 + 指令中的位移量。
指令中使用BX或BP为基址寻址;指令中使用SI或DI为变址寻址。
-
基址变址寻址
EA = 基址 + 变址 + 位移量
最灵活,可以方便地对二维数组进行访问。
-
串操作寻址方式
使用SI和DI专门指示
在寻找源操作数时,隐含使用SI作为地址指针 在寻找目的串时,隐含使用DI作为地址指针, 在串操作完成之后,自动对SI和DI进行修改,使它们指向下一个操作数
-
I/O端口寻址
(1)存储器编址方法
(2)I/O端口编址方法
3.2 指令系统
一种计算机所能执行的各种类型的指令的集合
分类
-
按种类分
- 传送类指令
- 算术运算类指令
- 位操作类指令
- 串操作类指令
- 程序转移类指令
- 处理器控制类指令
-
按格式分
-
双操作数指令:OPR DEST SRC
-
单操作数指令:OPR DEST
-
无操作数指令:OPR
无操作数指令包含: (1)指令不需要操作数,如暂停指令HLT。 (2)在指令格式中,没有显式指明操作数,但隐含指明了操作数的存放地方,如指令PUSHF。
-
一、传送类指令
将数据信息或地址信息传送到寄存器或存储单元。
-
通用数据传送指令
-
指令格式:MOV DEST,SRC
-
作用:源操作数指定内容传送到目的操作数,即DEST<=(SRC)。
指令执行完后,目的操作数和源操作数内容相同。
注: MOV指令不影响标志寄存器(无运算); MOV指令源、目的操作数的长度须一致; 立即数只能作为源操作数,且不能传送给段寄存器(存放段基址,不能轻易改变); 段寄存器CS(程序代码很重要)只能作源操作数,不能作目的操作数; 段寄存器之间、存储单元(SI是寄存器,[SI]是存储器)之间不能直接传送数据。
-
-
交换指令
-
指令格式:XCHG DEST,SRC
-
作用:源操作数和目的操作数内容互换,即(DEST)<=>(SRC)。
注: XCHG指令不影响标志寄存器; 通用寄存器(不包括段寄存器)之间可交换数据; 通用寄存器与存储单元之间可交换数据; 存储单元之间不可直接交换数据。
-
-
标志传送指令
都是无操作数指令,即指令隐含指定标志寄存器、AH寄存器或堆栈为操作数。
-
(1)取标志寄存器指令 LAHF 将标志寄存器的低8位送入AH寄存器(共8位),指令执行不影响标志寄存器。
-
(2)存储标志寄存器指令 SAHF 将AH中的第7、6、4、2、0位分别送入标志寄存器的SF、ZF、AF、PF和CF各标志位。不影响标志寄存器高8位。
-
(3)标志进栈指令 PUSHF 堆栈指针SP减2,标志寄存器16位(堆栈均已字为单位)进栈
-
(4)标志出栈指令 POPF SP指向的堆栈顶部的一个字单元送入标志寄存器后SP加2
-
-
地址传送指令
-
(1)装入有效地址
-
指令格式:LEA DEST,SRC
源操作数SRC为一个字节或字的存储器操作数(地址),DEST为16位通用寄存器
-
作用:将SRC存储单元地址中的偏移量,即有效地址EA传送到一个16位通用寄存器(传送的是一个地址,而不是地址内存的数据)
-
-
(2)装入地址指针指令
-
指令格式:LDS/LES DEST,SRC
DEST是任意一个16位通用寄存器,SRC必须是一个存储器操作数
-
作用:把SRC存储单元开始的4个字节单元的内容(32位地址指针)送入DEST通用寄存器和段寄存器DS或ES,其中低字单元内容为偏移量送通用寄存器,高字单元内容为段基值送DS或ES
-
二、算术运算类指令
加、减、乘、除指令,可对字节或字数据进行运算。
数据可以是无符号数,也可以是带符号数(补码表示)。
数据可以是二进制数,也可以是十进制数(BCD码表示)。
-
加法指令
-
指令格式:ADD DEST, SRC
-
作用:DEST <= (DEST) + (SRC),源操作数内容不变。相加结果将影响状态标志。
注: DEST只能是通用寄存器或存储器操作数,不能是立即数; SRC可以是通用寄存器、存储器或立即数操作数; DEST和SRC不能都为存储器操作数。
-
-
带进位加法指令
-
指令格式:ADC DEST, SRC
-
作用:DEST <= (DEST) + (SRC) + CF。可实现数据长度大于16位的两数相加。相加结果将影响状态标志。
-
-
加1指令
-
指令格式:INC DEST
-
作用:DEST <= (DEST)+1。影响除CF以外的其他状态标志。主要用于计数器计数和修改地址指针。
注: DEST可以是任意的8位、16位通用寄存器或存储器操作数; DEST被视为带符号二进制数。
-
-
减法指令
-
指令格式:SUB DEST, SRC
-
作用:DEST <= (DEST) - (SRC),SRC不变。操作结果将影响状态标志。
注: DEST和SRC可以是8位或16位的通用寄存器、存储器操作数, 但两者不能同时为存储器操作数; 立即数只能作源操作数
-
-
带借位减法
-
指令格式:SBB DEST,SRC
-
作用:DEST <= (DEST) - (SRC) - CF,SRC不变。
主要用于长度大于16位的数相减。
操作结果将影响状态标志。
-
-
减1指令
-
指令格式:DEC DEST
-
作用:DEST<=(DEST) - 1。影响除CF以外的其他状态标志。主要用于计数和修改地址指针,计数方向与INC指令相反。
注: DEST可以是任意的8位、16位通用寄存器或存储器操作数; DEST被视为带符号二进制数。
-
-
求负数指令(取补指令)
-
指令格式:NEG DEST
-
作用:DEST <= 0 - (DEST)。影响状态标志。主要用于计数和修改地址指针,计数方向与INC指令相反。
注: DEST可以是任意8位、16位的通用寄存器或存储器操作数; DEST被视为带符号二进制数。 影响进位标志CF——操作数为零时CF置零,其它情况置1 影响溢出标志OF——当字节操作数为-128或字操作数为-32768时,执行NEG指令的结果操作数无变化,但OF被置1。
-
三、位操作类指令
-
逻辑运算指令
与:AND DEST, SRC
或:OR DEST, SRC
异或:XOR DEST, SRC
非:NOT DEST
-
作用:执行按位逻辑运算。对字节或字数据的某些位的组合、分离或位设置。
注: DEST和SRC可以是8位、16位的通用寄存器或存储器操作数, 但两者不能同时为存储器操作数;SRC可以为立即数。 NOT指令不影响状态标志; 其余三条将影响SF、ZF和PF,而CF和OF总置0,AF不确定。
举例:中断标志位IF清零
思考:为什么不能直接对标志寄存器进行AND运算?为什么不能使用MOV指令将标志寄存器放入AX?
逻辑运算指令的DEST和SRC可以是8位、16位的通用寄存器;而中断标志位在标志寄存器,必须先用标志传送指令把它取出进入堆栈再进入通用寄存器。标志传送指令是专门对标志寄存器进行存取的指令,MOV指令对标志寄存器的各位无影响。
-
-
测试指令
-
指令格式:TEST DEST, SRC
-
作用:类似AND指令,DEST与SRC进行按位“逻辑与”运算,但运算结果不送入DEST(DEST保持不变)。主要用于测试某一操作数的一位或几位的状态。
思考:测试后跳转,是如何跳转的?JZ是什么?
使用JZ TARGET进行跳转。JZ=jump if zero (结果为0则设置ZF零标志为1,跳转)
-
-
移位/循环移位指令
四、处理器控制类指令
3.3 指令编码
一、双操作数指令编码格式
-
操作特征部分
指令编码首字节,分为以下三段:
(1) OPCODE:操作码字段
该字段长度为6bit。它表示了该指令所执行的功能和两个操作数的来源。
(2)方向字段d
该字段与第2部分寻址特征一起来决定源操作数和目的操作数的来源。
(3)字/字节字段W
当W=1时,表示两操作数长度为字;当W=0时,表示两操作数长度为字节。
-
寻址特征部分
d=l时,目的操作数由REG确定,而源操作数由MOD和R/M确定
d=0时,目的操作数由MOD和R/M确定,而源操作数由REG确定
(1) REG字段
确定的一个操作数是某一通用寄存器的内容,即寄存器寻址方式。
(2)寻址方式字段MOD和寄存器/存储器字段R/M
两个字段共同确定一个操作数。该操作数可在寄存器中,也可在存储器中
-
位移量部分
根据寻址特征中MOD和R/M字段确定的有效地址计算方法,位移量可以是:
没有位移量 1字节位移量disp8 2字节位移量displ6
-
立即数部分
指令的源操作数为立即数,则指令编码中包含该部分。总是位于指令编码的最后1〜2字节。
二、单操作数指令编码格式
适用于只有一个操作数的指令。指令编码为2〜3字节。
-
操作特征
包括OPCODE、V和W三个字段,其中V字段只有移位/ 循环指令中才有该字段。其它指令中没有该字段。
V=0时,指令中使用常数1作为移位或循环次数; V=1时,指令中使用寄存器CL作移位次数。
由于单操作数指令中只有一个操作数,因此寻址特征部分就不需要REG字段,而该字段被用作辅助操作码。
三、与AX或AL有关的指令编码格式
用于隐含指定AX/AL作为一个操作数的双操作数指令。
采用这种编码格式的指令,除一个操作数隐含指定为AX/AL外,另一个操作数可以是立即数或存储单元。
四、其它指令编码格式
除上述三种编码格式外,还有一些指令的编码格式更简单。
如标志位操作指令、堆栈操作指令等。 这些指令的编码格式一般只有一个字节。
第四章 汇编语言程序格式
4.1汇编语言语句种类及其格式
一、指令语句
-
标号字段
可选字段,后面必须有“:”。
标号是一条指令的符号地址,代表了该指令的第一个字节存放地址。
标号一般放在一个程序段或子程序的入口处,控制程序的执行转到该程序位置。
-
指令助记符字段
必选项,要求CPU完成什么具体操作。
有些指令还可在指令助记符的前面加上前缀,实现一定的附加操作。
-
操作数字段
一条指令可以有一个、两个或无操作数。
-
注释字段
可选项,该字段以分号“;”开始。
作用是为阅读程序的人加上一些说明性内容。
不会产生机器目标代码,不会影响程序和指令的功能。
二、伪指令语句
又叫命令语句。
本身并不产生对应的机器目标代码。仅仅是告诉汇编程序对其后面的指令语句和伪指令语句的操作数应该如何处理。
-
符号名字段
可选项。
根据伪指令的不同,符号名可是常量名、变量名、过程名、结构名和记录名。
一条伪指令语句的符号名可以作其它伪指令语句或指令语句的操作数,这时它表示一个常量或存储器地址。
-
伪指令符字段
必选项,规定了汇编程序所要完成的具体操作。
-
操作数字段
该字段是否需要,以及需要几个由伪指令符字段来决定。
操作数可以是一个常数
-
注释字段
注释字段为可选项,该字段必须以分号开始。 其作用与指令语句的注释字段相同。
三、标识符
指令语句中的标号利伪指令语句中符号名统称为标识符。标识符是由若干个字符构成的。
标识符构成规则:
1.字符的个数为1〜31个
2.第一个字符必须是字母、问号、@或下划线“” 这4种字符之一
3.从第二个字符开始,可以是字母、数字、@、“”或问号?
4.不能使用属于系统专用的保留字。
4.2 汇编语言数据
在汇编语言中常用的数据形式有:常数、变量和标号。
一、常数
-
二进制数:字母B结尾
-
八进制数:字母O或Q结尾
-
十进制数:字母D结尾,或者没有结尾字母
-
十六进制数:字母H结尾,如果常数的第一个数字为字母,为了与标识符加以区别,必须在其前面冠以数字“0”
-
实数
-
字符串常数:用引号(单引号或双引号)括起 来的一个或多个字符,这些字符以它的ASCII码 值存储在内存
常数在程序中可以用在以下几种情况: (1)作指令语句的源操作数 (2)在指令语句的直接寻址方式、变址(基址)寻 址方式或基址变址寻址方式中作位移量。 (3)在数据定义伪指令中使用
二、变量
-
变量的定义与预置
定义变量就是给变量在内存中分配一定的存储单元。也就是给这个存储单元赋与一个符号名,即变量名,同时还要将这些存储单元预置初值。当变量被定义后,就具有了以下三个属性:
(1)段属性:表示变量存放在哪一个逻辑段中。 (2)偏移量属性(OFFSET):表示变量所在位置与段起始点之间的字节数。 段属性和偏移量属性就构造了变量的逻辑地址 (3)类型属性:表示变量占用存储单元的字节数。
给变量赋初值的表达式可以使用4种形式:
(1)数值表达式
(2)?表达式
(3)字符串表达式
(4) DUP表达式
-
变量的使用
(1)在指令语句中引用
(2)在伪指令语句中引用
三、标号
标号写在一条指令的前面,它就是该指令在内存的存放地址的符号表示,也就是指令地址的别名。
标号主要用在程序中需要改变程序的执行顺序时, 用来标记转移的目的地,即作转移指令的操作数。
每个标号具有三属性:
(1)段属性(SEG):表示该标号所代表的地址在娜个逻辑段中,即段基值。
(2)偏移量属性(OFFSET):表示该标号所代表的地址在段内与段起点间的字节 数,即地址的偏移量。
(3)距离属性(也叫类型属性):表示该标号可以被段内还是段间的指令调用。
NEAR (近): 该标号只能作段内转移,也就是说只能是与该标号所指指令同在一个逻辑段的转移指令和调用指令才能使用它。
FAR (远): 该标号可以被非本段的转移和调用指令使用。
标号的距离属性可以右两种方法来指定:
a.隐含方式
b.用LABEL伪指令给标号指定距离属性
4.3符号定义语句
一、等值语句
-
格式:符号名 EQU 表达式
-
功能:用符号名来表示EQU右边的表达式。后面的程序中 一旦岀现该符号名,汇编程序将把它替换成该表达式。
表达式可以是任何形式,常见的以下:
1.常数或数值表达式 2.地址表达式 3.变量、寄存器名或指令助记符
二、等号语句
-
格式:符号名=表达式
-
功能:等号语句与等值语句具有相同的作用。但等号语句可以对一个符号进行多次定义。
4.4 表达式与运算符
表达式是指令或伪指令语句操作数的常见形式。它由常数、变量、标号等通过操作运算符连接而成。
一、算术运算符
+、-、*、/、MOD、SHL、SHR、[]
1. 运算符“+”和“-”也可作单目运算符,表示数的正负。
2. 使用“+”、“-”、“*”、和“/”运算符时,参加运算 的数和运算结果都是整数。
3. “/”运算为取商的整数部分,而“MOD”运算取除法运 算的余数。
4. “SHR ”和“SHL”为逻辑移位运算符
5. 下标运算符“[]”具有相加的作用
二、逻辑运算符
NOT、AND、OR和XOR四个,执行的都是按位逻辑运算。
三、关系运算符
关系运算符包括:
EQ 等于
NE 不等于
LT 小 于
LE 小于等于
GT 大于
GE 大于等于
四、数值返回运算符
-
SEG运算符
取变量或标号所在段的段基值。
-
OFFSET运算符
取变量或标号在段内的偏移量。
-
TYPE运算符
取变量或标号的类型属性, 就是取字节长度。
-
LENGTH运算符
取变量的长度。>如果变量是用重复数据操作符DUP说明的,则LENGTH运 算取外层DUP给定的值。 >如果没有用DUP说明,贝0LENGTH运算返回值总是1。
-
SIZE运算符
只能作用于变量,SIZE取值等于LENGTH和 TYPE两个运算符返回值的乘积。
五、属性修改运算符
-
PTR运算符
使用格式: 类型PTR地址表达式
作用:将地址表达式所指定的标号、变量或用其它形式表 示的存储器地址的类型属性修改为“类型”所指的值。
类型可以是BYTE、WORD、DWORD、NEAR和FAR。这种修改是临时的,只在含有该运算符的语句内有效。
-
HIGH/LOW 运算符
使用格式:HIGH表达式
LOW表达式这两个运算符用来将表达式的偵分离出高字节和低字节。
注:HIGH/LOW运算符不能用来分离一个变量、寄存器或存储器单元的高字节与低字节。
-
THIS运算符
THIS运算符一般与等值运算符EQU连用,用来定义一个变量或标号的类型属性。
所定义的变量或标号的段基值利偏移量与紧跟其后的变量或标号相同。
六、运算符的优先级
-
在一个表达式中如果存在多个运算符时,在计算时就有先 后顺序问题。不同的运算符具有不同的运算优先级别。
-
汇编程序的计算表达式规则:
先执行优先级别高的运算,再算较低级别运算; 相同优先级别的操作,按照在表达式中的顺序,从左到右进行; 可以用圖括号改变运算的顺序。
4.5 程序的段结构
一、段定义伪指令
伪指令SEGMENT和ENDS用于定义一个逻辑段。使用时必须配对,分别表示定义的开始与结束。
-
段名
用户自己任意选定、符合标识符定义规则的一个名称。
最好选用与该逻辑段用途相关的名称。如第一个数据段为DATA1,第二个数据为DATA2等。
一个段的升始与结尾用的段名必须一致。
-
定位类型
决定段的起始边界。可以有4种取值:
(1)PAGE:表示该段从一个页面的边界开始 (2)PARA:表示该段从一个小节的边界开始 (3) WORD:表示该段从一个偶数字节地址开始,即段起始单元地址的最后一位二进制数一定是0 (4) BYTE:表示该段起始单元地址可以是任一地址值 注:PAGE和PARA,段起始地址与段基址相同;WORD和BYTE,段起始地址与段基址可能不同。
-
组合类型
指定段与段之间的连接关系和定位。有六种取值选择。
(1)若未指定组合类型,表示本段与其它段无连接关系。在装入内存时,本段有自己的物理段,因此有自己的段基址 (2)PUBLIC:在满足定位类型的前提下,将与该段同名的段邻接在一起,形成一个新的逻辑段,共用一个段基址。段内的所有偏移量调整为相对于新逻辑段的段基址。 (3)COMMON:产生一个覆盖段。在多个模块连接时,把该段与其它也用COMMON说明的同名段置成相同的段基址, 这样可达到共享同一存储区。共享存储区的长度由同名段中最大的段确定。 (4) STACK:把所有同名段连接成一个连续段,且系统自动对SS段寄存器初始化为该连续段的段基址。并初始化堆栈指针SP。用户程序中应至少有一个段用STACK说明,否则需要用户程序自己初始化SS和SP。 (5) AT表达式:表示本段可定位在表达式所指示的小节边界上。表达式的值也就是段基值。 (6) MEMORY:表示本段在存储器中应定位在所有其它段之后的最高地址上。如果有多个用MEMORY说明的段,则只处理第一个用MEMORY说明的段。其余的被视为COMMON。
-
类别名
类别名为某一个段或几个相同类型段设定的类型名称。系统在进行连接处理时,把类别名相同的段存放在相邻的存储区,但段的划分与使用仍按原来的设定。
二、段寻址伪指令
段寻址伪指令ASSUME的作用是告诉汇编程序,在处理源 程序时,定义的段与哪个寄存器关联。
三、段寄存器的装入
-
DS和ES的装入
使用数据传送语句来实现对DS和ES的装入。
-
SS的装入
(1)在段定义伪指令的组合类型项中,使用STACK参数,并在段寻址伪指令ASSUME语句中把该段与SS段寄存器关联。 (2)如果在段定义伪指令的组合类型中,未使用STACK参数,或者是在程序中要调换到另一个堆栈,这时可以使用类似于DS和ES的装入方法。
-
CS的装入
(1)由系统软件按照结束伪指令指定的地址装入初始的CS和IP (2)在程序运行期间,当执行某些指令时,CPU自动修改CS和IP,使它们指向新的代码段
4.6 过程定义伪指令(PROC/ENDP)
过程名是子程序的名称,它被用作过程调用指令CALL的目的操作数。它类同一个标号的作用。具有段、偏移量和距离三个属性。而距离属性使用NEAR和FAR来指定,若没有指定,则隐含为NEAR。
NEAR过程只能被本段指令调用,而FAR过程可以供其它段的指令调用。
每一个过程中必须包含有返回指令RET, 其作用是控制CPU从子程序中返回到调用该过程的主程序。
4.7 当前位置计数器$与定位伪指令ORG(Origin)
定位伪指令ORG
-
格式:ORG 数值表达式
-
作用:将数值表达式的值赋给当前位置计数器$。ORG语句为其后的数据或指令设置起始偏移量。
-
表达式的值必须为正值。表达式中也可以包含有当前位置计数器的现行值$。
4.8 标题伪指令TITLE
-
格式:TITLE标题名
-
作用:给所在程序指定一个标题。以便在列表文件的每一页 的第一行都显示这个标题。其中标题是用户任意选用的字符 串,字符个数不能超过60。
4.9 从程序返回操作系统的方法
一、使用程序段前缀PSP (Program Segment Prefix)实现返回
为了使程序执行完后,正确返回DOS,需要以下三个操作:
1.将用户程序编制成一个过程,类型为FAR;
2.将PSP的起始逻辑地址压栈,即将INT20H指令的地址压栈;
3.在用户程序结尾处,使用一条RET指令。执行该指令将使保存在堆栈中的PSP的起始地址弹出到CS和IP中。
二、使用DOS系统功能调用实现返回
执行DOS功能调用4CH,也可以控制用户程序结束,并返回DOS操作系统。