20192408胡益琳 汇编语言程序设计前四章学习笔记
汇编语言的一般概念
- 机器语言:二进制数
1.3 进位计数制及其相互转换
一、进位计数制
1.概念
- 位权:各个位置上所表示的基本数值
- 基数:每个数位上能使用不同数码的个数
2.对应关系
3位二进制数与一位八进制数对应,4位二进制数与一位16进制数对应
3.表示方式
- B-二进制数
- 0或Q-八进制数
- D-十进制数
- H-十六进制数
- 默认表示为十进制
二、各种数制间的相互转换
1.十进制转换为二进制
- (1)减权定位法
- (2)除基取余法(整数)
- (3)乘基取整法(小数)
2.二进制转换为十进制
- (1)按权相加法
- (2)逐次乘基相加法(整数)
- (3)逐次除基相加法(小数)
3.二进制、八进制和十六进制之间的转换
3位二进制数与一位八进制数对应,4位二进制数与一位16进制数对应
1.4 带符号数的表示
用正负号表示正负的数叫真值,用0和1表示正负的数叫机器数
一、原码
最高位为0是正数,最高位为1是负数
二、补码
1.定义
- 【X】补=M+X(Mod M)
- M根据机器数的位数而定,符号位0为正,1为负。
- 对于正数,补码与原码相同,对于负数则需要进行变换
2.由真值、原码变换为补码
- 负数的真值变换为补码:各位取反,最低位加1
- 负数的原码变换为补码:符号位不变,各位取反,最低位加1
3.补码数的表示范围
- 位数为8时:+127~-128
- 位数为16时:-32768~+32767
4.补码的加减运算
- 规则:【X+Y】补=【X】补+【Y】补
- 【X-Y】补=【X】补-【Y】补=【X】补+【-Y】补
- 求补运算是将原数连同符号位一起按位求反,再在最低位加1
1.5 字符的表示
ASCII码
- 一字节,低七位表示字符编码,最高位表示奇偶校验位
- 共有128个,分为非打印(用于控制操作)和可打印两类
1.6 基本逻辑运算
1.与运算
- 仅当逻辑变量A与B都是1时,运算结果才为1,否则为0
2.或运算
- 逻辑变量A和B中至少有一个为1时,结果为1,否则为0
3.非运算
- 取反
4.异或运算
- 当两个数相同时为0,不同时为1
2.1 微机基本结构
一、微机的一般构成
- 包括五大部件:运算器、控制器、存储器、输入设备和输出设备。
- 运算器和控制器集成在一个芯片上,称为中央处理器CPU
- 系统采用总线结构,具有较大的灵活性和扩展性
- 系统总线包括地址总线、数据总线和控制总线
1.CPU
- 功能:分析从主存储器取来的各条指令的功能,控制计算机各部件完成指定功能的各项操作。
2.主存储器
- 用来存放程序和数据的部件,由若干个存储单位构成
- 存储单元的多少表示存储器的容量。
- 在大多数计算机中,存储器的组织都是以字节为基本单位(存储单元)的
- 习惯上将CPU与主存储器合称为主机
3.输入输出设备及接口
- I/O设备要通过I/O接口才能与系统总线连接
- I/O接口是主机与I/O设备之间设置的逻辑控制部件。实现信息传送
4.系统总线
- 将CPU、存储器和I/O设备连接起来,实现各大部件之间的各种信息传送。
- 系统总线包括地址总线、数据总线和控制总线
二、CPU的功能结构
1.CPU执行指令就是重复执行以下两个步骤:
- 从存储器中取指令
- 执行指令规定的操作
执行方式
- 串行方式:利用率不高
- 指令流水线方式:效率高,CPU被分成两个单元
CPU结构:执行单元EU和总线接口单元BIU
2.2 CPU寄存器结构及其用途
一、通用寄存器
1.数据寄存器
*包括AX、BX、CX、DX四个寄存器
2.指针寄存器
- 堆栈指针寄存器SP和基址指针BP
- SP指针用来指向堆栈顶部单元
3.变址寄存器
- 16位的SI和DI
- SI:源变址寄存器
- DI:目的变址寄存器
- 一般被用来作地址指针,也可以存放操作数和运算结果
二、段寄存器
- 每个存储段用一个段寄存器来指明该段的起始位置(也叫段基址)
- 地址从上往下由低到高
三、指令指针IP
- IP的内容为偏移量,与CS(基址指针)共同形成一条指令的存放地址
- 当CPU从内存中取出一条指令后,IP内容自动修改为指向下一条指令
- IP的内容不能被直接访问,可以通过某些指令的执行而自动修改
四、标志寄存器
- 用来反映CPU在程序运行时的某些状态
- 如是否有进位、奇偶性、结果的符号、结果是否为零等
- 长度为16位,但只定义了其中的9位
- 标志位分为状态标志和控制标志
1.进位标志位CF
- 在进行算术运算时,若最高位产生进位或借位时CF被自动置1,否则置0
- 在移位类指令中,CF也被用来存放从最高位或最低位移出的数值
2.奇偶标志位PF
- 当指令操作结果的低8位中含有1的个数为偶数时被置1
3.辅助进位标志位AF
- 在进行算术运算时,若低字节的低四位向高4位产生进位或借位,即第3位产生进位或借位时,AF位被置1,否则置0
4.零值标志位ZF
- 若运算结果各位全为0置1,否则置0
5.符号标志位SF
- 将运算结果视为带符号数,当运算结果为负数时SF被置1,否则置0
6.溢出标志位OF
- 若运算结果溢出置1
7.单步标志位TF
- 用于调试,程序走一步停一步
8.中断允许标志位IF
- 当被设置为1时,CPU可以响应可屏蔽中断,否则不允许
9.方向标志位DF
- 被用来规定串操作指令的增减方向
- 当DF=0时,串操作指令自动使变址寄存器(SI和DI)的内容递增;DF=1时递减
2.3 存储器组织结构
一、存储器的组成
1.存储器是由若干个存储单元构成
- 存储单元的多少就表示了存储器的容量
2.每个存储单元存放相同长度的二进制数
- 一个存储单元的长度一般为8位二进制数
3.每个存储单元有一个唯一的地址编号——地址
- 20根地址线可以产生20位的地址码
为了方便书写,常用5位十六进制数或一个符号来表示一个存储单元的地址
4.任何两个相邻字节单元构成一个字单元
- 一个字存储单元的长度为16位二进制数,即两个字节。
5.在定义一个地址时必须指出时字节或字类型属性
- 访问内存的指令分为字节访问和字访问两种
二、存储器的段结构
- 每个段的最大长度为64K个字节单元组成
- 每个段的基址必须是一个小节的首址
- 段基址——一个段的起始地址
- 小节——在存储器中规定从0地址开始,每16个字节单元称为一个小节
- 1MB内存可以划分为64K小节
- 每个小节的首地址最低位必为0(16进制数表示)
- 逻辑段在物理存储器中可以是邻接的、间隔的、部分重叠的和完全重叠的
- 内存中的一个物理存储单元可以映像到一个或多个逻辑段中
- 在任一时刻,一个程序只能访问4个当前段中的内容
三、逻辑地址与物理地址及其对应关系
1.物理地址
- 每个存储单元的物理地址是惟一的
2.逻辑地址
- 包括段基值和偏移量
- 表示方法 段基值:偏移量 如3267H:0A0H
3.逻辑地址转换为物理地址
- 转换方法:将逻辑地址的段基值左移4位,形成20位的段基址(低位为0)然后与16位的偏移量相加,结果即为20位的物理地址。
4.逻辑地址的来源
如图
- 允许替代来源也叫做段超越
- 有效地址EA,它表示根据指令所采用的寻址方式计算出来的段内偏移量
2.4 堆栈及其操作方法
- 主要用于暂存数据以及在过程调用或处理中断时保存断点信息
一、堆栈的构造
- 分为专用堆栈存储器和软件堆栈
- 一端固定,称为栈底,是堆栈存储区的最大地址单元
- 另一端是浮动的,称为栈顶,是最后存入信息的存储单元
- 堆栈指针SP内容始终指向栈顶单元,堆栈中数据进出都由SP来控制
- 存储数据的原则是 先进后出FILO
二、堆栈的组织
- SP中内容表示堆栈段基址与栈顶之间的距离(字节数)。当SP内容为最大(初始)值时,表示堆栈为空,SP=0时表示堆栈全满
- 当SP被初始化时,指向栈底+2单元,其值就是堆栈的长度
- 由于SP是十六位寄存器,因此堆栈长度<=64K字节
- 数据在堆栈中以字为单位存放,低八位放在较低地址单元
三、堆栈操作
1.设置堆栈
- 对堆栈段寄存器SS和堆栈指针SP赋值
2.进栈PUSH
- (1)将堆栈指针SP减2
- (2)将数据送入SP指向的字单元中
3.出栈POP
- (1)将SP指向的字单元内容送往指定寄存器或存储器
- (2)SP内容加2
第三章 寻址方式与指令系统
3.1寻址方式
- 指令由操作码和操作数组成
- 操作数由以下四种
1. 立即数操作数
- 立即数寻址方式的指令中,所需操作数直接包含在指令代码中
- 立即数可以是8位,也可以是16位
- 立即数只能作为源操作数,不能作为目的操作数
2. 寄存器操作数
3. 存储器操作数
- 段基值由某个段寄存器提供
- 偏移量表示了该存储单元与段起始地址之间的距离,也叫做有效地址EA(要用【】)
- 直接寻址:操作数的有效地址EA只有位偏量地址分量
- (1)用符号表示
- (2)用常数表示:要带【】
- 寄存器间接寻址:操作数有效地址EA直接由基址寄存器(BX或BP)或变址寄存器(SI或DI)中获得
- 就是事先将偏移量存放在某个寄存器中,这些寄存器就如同一个地址指针
- 段寄存器可以省略。当指令中使用的是BP寄存器,则隐含表示使用SS段寄存器,其余情况则隐含使用DS段寄存器
- 基址寻址/变址寻址
- 有效地址EA等于基址分量或变址分量加上指令中给出的位移量
- 指令由操作码 寻址特征 位移量三部分构成
- 隐含使用规则与寄存器间接寻址方式相同
- 当位移量为常数时,不能加方括号
- 叫做寄存器相对寻址,可对一位数组与表格进行访问
- 基址变址寻址
- 操作数的有效地址是三个地址分量的和即
- EA=基址(BX或BP)+变址(SI或DI)+位移量
- 指令由操作码 寻址特征 位移量三部分构成
- 其中寻址特征包含了基址和变址两部分
- 当指令中使用的是BP寄存器,则隐含表示使用SS段寄存器,其余情况则隐含使用DS段寄存器
- 可对二维数组进行访问
- 串操作寻址方式
- 在寻找源操作数时,隐含地使用SI作为地址指针
- 在寻找目的串时,隐含使用DI作为地址指针
- 在串操作完成之后,自动对SI和DI进行修改,使他们指向下一个操作数
- 直接寻址:操作数的有效地址EA只有位偏量地址分量
4. I/0端口操作数
I/O端口寻址
存储器编址方法
- 将I/O端口视为存储器的一个单元
I/O端口编址方法
- 最多可以访问64K个字节端口或32K个字端口,有专门的IN和OUT指令访问
- 寻址方式有如下两种:
- 直接端口寻址
- 在指令中直接给出端口地址,一般采用2位十六进制数,也可以用符号表示
- 可访问的端口数位0~255个
- 寄存器间接端口寻址
- 把I/O端口的地址先送到DX中,用DX作间接寻址寄存器。
- 如果访问的端口地址大于255,则必须使用I/O端口的间接寻址方式
- 直接端口寻址
3.2 指令系统
- 一种计算机所能执行的各种类型的指令的集合称为该计算机的指令系统
- 可分为六大类
一、 传送类指令
- 通用数据传送指令
- 源在后,目的在前,长度一致
- MOV指令对标志寄存器的各位无影响
- (1)立即数传送到通用寄存器或存储单元
- 立即数只能作为源操作数,立即数不能传送给段寄存器CS
- (2)寄存器之间的传送
- 段寄存器CS只能作源操作数,段寄存器之间不能直接传送
- (3)寄存器与存储单元之间传送
- 存储单元之间不能直接传送数据
- (1)立即数传送到通用寄存器或存储单元
- 交换指令
- 指令格式:XCHG DEST,SRC
- 对标志寄存器的各位无影响
- 寄存器之间或寄存器与存储器单元之间进行
- 寄存器只能使用通用寄存器
- 标志传送指令
- 取标志寄存器指令
- 指令格式:LAHF
- 作用:将标志寄存器的低八位送入AH寄存器,而AH的第5/3/1位不确定
- 对标志寄存器的各位无影响
- 存储标志寄存器指令
- 指令格式:SAHF
- 作用:将寄存器AH中的第7/6/4/2/0位分别送入标志寄存器的各低八位标志位。高8位不受影响
- 标志进栈指令
- 指令格式:PUSHF
- 标志出栈指令
- 指令格式:POPF
- 取标志寄存器指令
- 地址传送指令
- 这类指令有3条,作用是将存储单元的地址送寄存器
- 装入有效地址
- 格式:LEA DEST,SRC
- 源操作数必须是一个地址,DEST必须是一个16位的通用寄存器
- 作用:将有效地址EA传送到一个16位的通用寄存器
- 装入地址指针指令
- 格式:LDS DEST,SRC
-
或LES DEST,SRC
- 其中,DEST是任意一个16位通用寄存器,SRC必须是一个存储器操作数
- 作用:把SRC存储单元开始的4个字节单元的内容(32位地址指针)送入DEST通用寄存器和段寄存器DS(LDS指令)或ES(LES指令),其中低字单元内容为偏移量送通用寄存器,高字单元内容为段基值送DS或ES
二、算术运算类指令
- 有加、减、乘、除指令,这些指令可以对字节数据或字数据进行运算
- 参加运算的数可以是无符号数,也可以是带符号数。带符号数用补码表示
- 可以是二进制数,也可以是十进制数(以BCD码表示)
- 加法指令
- 格式:ADD DEST,SRC
- 功能:相加和放在目的操作数中,源操作数内容不变
- 根据相加的结果将影响到标志寄存器的CF、PF、AF、ZF、SF和OF
- DEST只能是通用寄存器或存储器操作数,不能是立即数
- SRC可以是通用寄存器、存储器或立即数操作数
- 不能都为存储器操作数
- 可以按字操作数相加或者按字节操作数相加
- 带进位加法指令
- 格式:ADC DEST,SRC
- 功能与ADD基本相同,不同的是其结果还要加上进位标志CF的值
- 根据相加的结果将影响到标志寄存器的CF、PF、AF、ZF、SF和OF
- 注:参加运算的进位CF是本条指令执行之前的值
- 用ADC指令可以实现数据长度大于16位的两数相加
- 加1指令
- 格式:INC DEST
- 目的操作数被视为带符号二进制数
- 根据相加的结果将影响到标志寄存器的PF、AF、ZF、SF和OF,但不影响CF
- 主要用于某些计数器的计数和修改地址指针
- 减法指令
- 格式:SUB DEST,SRC
- 根据指令执行的结果将影响到标志寄存器的CF、PF、AF、ZF、SF和OF
- 目的操作数减去源操作数
- 可以是8或16位的通用寄存器、存储器操作数,但两者不能同时为存储器操作数。立即数只能作源操作数
- 注:减法指令对借位标志的影响,若采用变减为加的运算方法,则产生的进位与CF标志结果相反
- 带借位减法
- 格式:SBB DEST,SRC
- 功能与SUB基本相同,不同的是其结果还要减去进位标志CF的值
- 注:参加运算的CF是本条指令执行之前的值
- 用SBB指令可以实现数据长度大于16位的两数相减,即将低16位的结果引入高位部分的减法中
- 根据指令执行的结果将影响到标志寄存器的CF、PF、AF、ZF、SF和OF
- 减1指令
- 格式:DEC DEST
- 目的操作数被视为带符号二进制数
- 根据指令执行的结果将影响到标志寄存器的PF、AF、ZF、SF和OF,但不影响CF
- 可以是8或16位的通用寄存器、存储器操作数
- 主要用于某些计数器的计数和修改地址指针,计数方向与INC指令相反
- 求负数指令
- 格式:NEG DEST
- 目的操作数被视为带符号操作数
- 由于机器中带符号数用补码表示,求操作数的负数就是求补操作,因此也叫取补指令
- 根据指令执行的结果将影响到标志寄存器的PF、AF、ZF、SF、CF和OF
- 对进位标志CF的影响:只有当操作数位0时,CF为0
- 对溢出标志OF的影响:当字节操作数为-128,或字操作数为-32768时,执行NEG指令的结果操作数将无变化,但溢出标志OF被置1
- 加法指令
三、位操作类指令
1.逻辑运算指令
- 与 AND
- 或 OR
- 异或 XOR
- 非 NOT
- 可以是8或16位的通用寄存器、存储器操作数,但两者不能同时为存储器操作数。立即数只能作源操作数
- NOT指令对标志无影响。而其余三条指令将影响SF、ZF、PF,而CF和OF总是置0,AF为不确定。
- 逻辑运算指令除用来实现各种逻辑运算外,还常用于对字节或字数据的某些位的组合、分离或位设置
2.测试指令
- 格式:TEST DEST,SRC
- 功能与AND指令相似,实现按位与的运算,对标志位的影响相同,但运算结果不送入目的操作数
- 主要用于测试某一操作数的一位或几位的状态
3.移位/循环移位指令
- 算术移位
- 算术左移SAL DEST,COUNT
- 算术右移SAR DEST,COUNT 保持符号位不变
- 逻辑移位
- 逻辑左移SHL DEST,COUNT
- 逻辑右移SHR DEST,COUNT 最左补0
- 循环移位
- 小循环:
- 循环左移ROL DEST,COUNT
- 循环右移ROR DEST,COUNT
- 大循环:
- 带进位循环左移 RCL DEST,COUNT
- 带进位循环右移 RCR DEST,COUNT
- 小循环:
- DEST可以是字节或字操作数,可以是通用寄存器或存储器操作数
- 当移位次数为1时,可以使用常数1或寄存器CL
- 当移位次数大于1时,必须使用寄存器CL
- 前四条移位结束后修改标志位CF、PF、ZF、SF、OF,而AF不确定。
- 后四条循环移位指令仅修改CF和OF
四、串操作类指令
五、程序转移类指令
六、处理器控制类指令
1.标志位操作指令
- 都是无操作数指令,操作数隐含为标志寄存器的某个标志位。
- 能直接操作的标志位有CF、IF和DF
- (1)清除进位标志 CLC:置CF为0
- (2)置1进位标志 STC:置CF为1
- (3)进位标志取反 CMC:CF的值取反
- (4)清除方向标志 CLD:置DF为0
- (5)置1方向标志 STD:置DF为1
- (6)清除中断标志 CLI:置IF为0
- (7)置1中断标志 STI:置IF为1
2.与外部事件同步的指令
- HLT:暂停指令
- WAIT:等待指令
- ESC:外部协处理器指令前缀
- LOCK:总线锁定指令
3.空操作指令 NOP
- 执行一次NOP占用CPU三个时钟周期,他不改变任何寄存器或存储单元内容,主要用于延时
3.3 指令编码
- 汇编:将汇编语言程序转换为机器语言程序的过程
- 汇编程序:在计算机中实现汇编过程的系统程序
- 编码格式有以下四种:
一、双操作数指令编码格式
- 一个操作数在寄存器中,另一操作数在寄存器或存储器中。
- 目的操作数在寄存器或存储器中,源操作数是立即数。
- 这类指令的机器目标代码长度为2~6个字节
1. 操作特征部分
- (1)OPCODE:操作码字段
- 该字段长度为6bit。它表示了该指令所执行的功能和两个操作数的来源。
- 如果指令的源操作数是立即数,则需要使用指令编码的第2字节中REG字段作辅助操作码。
- (2)方向字段d
- 该字段与第2部分寻址特征一起来决定源操作数和目的操作数的来源。
- 注意:当源操作数为立即数时,d字段无效,它被并入操作码字段。
- (3)字/字节字段W
- 当W=1时,表示两操作数长度为字;当W=0时,表示两操作数长度为字节。
2.寻址特征部分
- 它包括MOD、REG和R/M三个字段,REG字段确定一个操作数,而MOD和R/M字段确定另一个操作数。
- 当d=1时,则目的操作数由REG字段确定,而源操作数由MOD和R/M字段确定。当d=0时反之。
- (1)REG字段
- 由REG字段确定的一个操作数是某一通用寄存器的内容,即使用的是寄存器寻址方式。
- 第一部分中的W字段决定操作数是字或是字节。
- 如图所示
- (2)寻址方式字段MOD和寄存器/存储器字段R/M
- 这两个字段共同确定一个操作数。该操作数可以在寄存器中,也可以在存储器中
3.位移量部分
- 没有位移量
- 1字节位移量disp8
- 2字节位移量disp16
4.立即数部分
- 如果指令的源操作数为立即数,则指令编码中包含有该部分。它总是位于指令编码的最后1~2字节。
二、单操作数指令编码格式
- 适用于只有一个操作数的指令,如INC、DEC、移位/循环等指令
- 指令编码为2~3字节
- 由操作特征、寻址特征、位移量组成
- 操作特征部分
- 包括OPCODE V 和W三个字段,其中V字段只有移位/循环指令中才有
- V=0时,指令中使用常数1作为移位或循环次数
- V=1时,指令中使用寄存器CL作移位次数
- 寻址特征部分
- 由于单操作数指令中只有一个操作数,因此寻址特征部分就不需要REG字段,被用作辅助操作码
三、与AX或AL有关的指令编码格式
- 这种编码格式用于隐含指定AX/AL作为一个操作数的双操作数指令
- 采用这种编码格式的指令,一个操作数隐含指定,另一个操作数可以是立即数或存储单元
- 立即数:即编码中应有1~2字节的立即数
- 存储单元:只能使用直接寻址方式,位移量由disp字段给出
四、其他指令编码格式
- 格式简单,如标志位操作指令、堆栈操作指令等
- 如CLC清进位标志,只有一个字节的操作码
- 在有些单字节指令的编码中,将该字节划出部分位作为REG字段,例如PUSH指令,若压入堆栈的是通用寄存器,则编码的后三位表示REG(因为堆栈以字长为单位,所以就是8种情况)
- 若压栈的是段寄存器则编码格式为000REG110,REG占两位,表示四个不同的段寄存器
第四章 汇编语言程序格式
4.1 汇编语言语句种类及其格式
一、指令语句
- 又叫可执行语句
- 一般格式为:
- 标号:指令助记符 操作数(之间用,隔开);注释
- 一条指令语句最多可以包含4个字段
- 标号字段
- 可选字段
- 后面必须有:
- 是一条指令的符号地址,代表了该指令的第一个字节存放地址
- 一般放在一个程序段或子程序入口处
- 标号字段
二、伪指令语句
- 又叫命令语句
- 符号名 伪指令符 操作数(之间用,隔开);注释
- 符号名字段
- 为可选项
- 可以是常量名、变量名、过程名、结构名和记录名
- 可以作为其他语句的操作数,此时表示一个常量或存储器地址
三、标识符
- 标号或符号名
- 字符的个数为1~31个
- 第一个字符必须是字母、问号、@或下划线四种之一
- 其他字符可以是以上四种或数字
- 不能使用系统保留字
4.2汇编语言数据
- 十六进制数 如果常数的第一个数字为字母则要在前面加0
- 常数的使用:
- 作源操作数
- 作位移量
- 在伪指令中使用
- 变量
- 变量名就是存放数据的存储单元地址
- 变量名 +DB/DW/DD/DQ/DT+表达式1,表达式2
- 赋值方式:
- DATA1 DB 32,30H
- DA-BYTE DB ?,?,?
- 对于DB伪指令,字符串为用引号括起来的不超过255个字符。给每一个字符分配一个字节单元。字符串按从左到右,将字符的ASCII编码值以地址递增的排列顺序依次存放 例如:STRING1 DB ‘ABCDEF’
- 注意:两个字符的存放顺序是前一个字符放在高地址,后一字符放低地址单元。
- 变量名 DB/DW/DD 表达式1 DUP(表达式2)
- 其中:表达式1是重复的次数,表达式2是重复的内容。
- 例如:DATA_A DB 10H DUP(?) 分配16个字节单元
- DATA_B DB 20H DUP(‘AB’) 分配20H*2=40H个字节,其内容为重复字符串‘AB’
- DUP还可以嵌套使用,即表达式2又可以是一个带DUP的表达式。
- 例如:DATA_C DB 10H DUP(4 DUP(2),7)重复10H个数字序列“2,2,2,2,7”,共占用10H*5=50H个字节。
- 变量的使用
- 在指令语句中直接引用变量名就是对其存储单元的内容进行存取
- 当变量出现在变址(基址)寻址或基址变址寻址的操作数中时表示取用该变量的偏移量。
3.在伪指令里表示取变量地址的偏移量- 若是DD:取变量段基值和偏移量。前两个字节存偏移量,后两个字节存段基值
- 标号
- 标号写在一条指令的前面,它就是该指令在内存的存放地址的符号表示,也就是指令地址的别名。
- 每个标号具有三属性
- (1)段属性(SEG)
- 它表示该标号所代表的地址在哪个逻辑段中,即段基值。
- (2)偏移量属性(OFFSET)
- 它表示该标号所代表的地址在段内与段起点间的字节数,即地址的偏移量。
- (3)距离属性(也叫类型属性)
- 它表示该标号可以被段内还是段间的指令调用。
- NEAR(近):
- 该标号只能作段内转移,也就是说只能是与该标号所指指令同在一个逻辑段的转移指令和调用指令才能使用它。
- FAR(远):
- 该标号可以被非本段的转移和调用指令使用。
- 标号的距离属性可以有两种方法来指定:
- a.隐含方式
- 当标号加在指令语句前面时,它隐含为NEAR属性
- b.用LABEL伪指令给标号指定距离属性
- a.隐含方式
4.3符号定义语句
一、等值语句
- 语句格式:符号名 EQU 表达式
- 功能:用符号名来表示EQU右边的表达式。后面的程序中一旦出现该符号名,汇编程序将把它替换成该表达式。
- 1.常数或数值表达式
- 2.地址表达式
- 3.变量、寄存器名或指令助记符
- 注意:在同一源程序中,同一符号不能用EQU定义多次。
二、等号语句
- 格式:符号名=表达式
- 等号语句与等值语句具有相同的作用。但等号语句可以对一个符号进行多次定义。
- 等号语句不能为助记符定义别名
- 注意:等值语句与等号语句都不会为符号分配存储单元。因此所定义的符号没有段、偏移量和类型等属性。
4.4表达式与运算符
- 表达式是指令或伪指令语句操作数的常见形式。它由常数、变量、标号等通过操作运算符连接而成。
- 注意:任何表达式的值在程序被汇编的过程中进行计算确定,而不是到程序运行时才计算。
一、算术运算符
- +、—、*、 / 、MOD、SHL、SHR、[ ]
- 1.运算符“+”和“-”也可作单目运算符,表示数的正负。
- 2.使用“+”、“-”、“*”、和“/”运算符时,参加运算
的数和运算结果都是整数。 - 3.“/”运算为取商的整数部分,而“MOD”运算取除法运
算的余数。 -
- “SHR ”和“SHL ”为逻辑移位运算符
- 5.下标运算符“[ ]”具有相加的作用
- 表达式1 [表达式2]
- 作用:将表达式1与表达式2的值相加后形成一个
存储器操作数的地址。
二、逻辑运算符
- 逻辑运算符有NOT、AND、OR和XOR等四个,它们执行的都是按位逻辑运算。
三、关系运算符
- 关系运算符包括:EQ(等于)、NE(不等于)、LT(小于)、 LE(小于等于)、GT(大于)、 GE(大于等于)
- 关系运算符用来比较两个表达式的大小。关系运算符比较的两个表达式必须同为常数或同一逻辑段中的变量。
- 如果是常量的比较,则按无符号数进行比较;如果是变量的比较,则比较它们的偏移量的大小。
- 关系运算的结果只能是“真”(全1)或“假”(全0)
四、数值返回运算符
- SEG运算符
作用:取变量或标号所在段的段基值。 - OFFSET运算符
作用:取变量或标号在段内的偏移量。 - TYPE运算符
作用:取变量或标号的类型属性,并用数字形式表示。对变量来说就是取它的字节长度。
- 变量
BYTE 1
WORD 2
DWORD 4
QWORD 8
TWORD 10 - 标号
NEAR -1
FAR -2
- LENGTH运算符
- 该运算符用于取变量的长度。
- 如果变量是用重复数据操作符DUP说明的,则LENGTH运算取外层DUP给定的值。
- 如果没有用DUP说明,则LENGTH运算返回值总是1。
- SIZE运算符
- 该运算符只能作用于变量,SIZE取值等于LENGTH和TYPE两个运算符返回值的乘积。
五、属性修改运算符
- PTR运算符
- 使用格式: 类型 PTR 地址表达式
- 作用: 将地址表达式所指定的标号、变量或用其它形式表示的存储器地址的类型属性修改为 “类型”所指的值。
- 类型可以是BYTE、WORD、DWORD、NEAR和FAR。
这种修改是临时的,只在含有该运算符的语句内有效。
- HIGH/LOW运算符
- 这两个运算符用来将表达式的值分离出高字节和低字节
- 如果表达式为一个常量,则将其分离成高8位和低8位;如果表达式是一个地址(段基值或偏移量)时,则分离出它的高字节和低字节
- 注意:HIGH/LOW运算符不能用来分离一个变量、寄存器或存储器单元的高字节与低字节。
- THIS运算符
- THIS运算符一般与等值运算符EQU连用,用来定义一个变量或标号的类型属性。所定义的变量或标号的段基值和偏移量与紧跟其后的变量或标号相同。
4.5程序的段结构
一、段定义伪指令
- 格式:段名 SEGMENT [定位类型] [组合类型] [‘类别名']
-
本段语句序列
-
段名 ENDS
- 1.段名
- 2.定位类型
- 定位类型用于决定段的起始边界,即第一个可存放数据
的位置(不是段基址)。它可以有4种取值 - PAGE: 表示该段从一个页面的边界开始
- PARA:表示该段从一个小节的边界开始
- 16字节为一小节
- WORD:表示该段从一个偶数字节地址开始,即段起始单元地址的最后一位二进制数一定是0。
- BYTE:表示该段起始单元地址可以是任一地址值。
- 注意:定位类型为PAGE和PARA时,段起始地址与段基址相同。定位类型为WORD和BYTE时,段起始地址与段基址可能不同。
- 定位类型用于决定段的起始边界,即第一个可存放数据
- 3.组合类型
- 若未指定组合类型,表示本段与其它段无连接关系。在装入内存时,本段有自己的物理段,因此有自己的段基址
- PUBLIC:在满足定位类型的前提下,将与该段同名的段邻接在一起,形成一个新的逻辑段,共用一个段基址。段内的所有偏移量调整为相对于新逻辑段的段基址。
- COMMON: 产生一个覆盖段。在多个模块连接时,把该段与其它也用COMMON说明的同名段置成相同的段基址,这样可达到共享同一存储区。共享存储区的长度由同名段中最大的段确定。
- STACK:把所有同名段连接成一个连续段,且系统自动对SS段寄存器初始化为该连续段的段基址。并初始化堆栈指针SP。
- 用户程序中应至少有一个段用STACK说明,否则需要用户程序自己初始化SS和SP。
- AT表达式:表示本段可定位在表达式所指示的小节边界上。表达式的值也就是段基值。
- MEMORY:表示本段在存储器中应定位在所有其它段之后的最高地址上。如果有多个用MEMORY说明的段,则只处理第一个用MEMORY说明的段。其余的被视为COMMON
- 4.类别名
- 类别名为某一个段或几个相同类型段设定的类型名称。系统在进行连接处理时,把类别名相同的段存放在相邻的存储区,但段的划分与使用仍按原来的设定。
- 类别名必须用单引号引起来。所用字符串可任意选定,但它不能使用程序中的标号、变量名或其它定义的符号。
二、段寻址伪指令
- 一般格式 :
ASSUME 段寄存器名:段名,段寄存器名:段名,...... - 其中段寄存器名为CS,DS,ES和SS四个之一,段名是用SEGMENT/ENDS伪指令定义的段名。
- 在一个代码段中可以有几条ASSUME伪指令,对于前面的设置,可以用ASSUME改变原来的设置。
三、段寄存器的装入
- DS和ES的装入
- 在程序中,使用数据传送语句来实现对DS和ES的装入。
- SS的装入
- 在段定义伪指令的组合类型项中,使用STACK参数,并在段寻址伪指令ASSUME语句中把该段与SS段寄存器关联。
- 如果在段定义伪指令的组合类型中,未使用STACK参数,或者是在程序中要调换到另一个堆栈,这时,可以使用类似于DS和ES的装入方法
- CS的装入
- CS和IP的初始值就不能用可执行语句来装入
- (1)由系统软件按照结束伪指令指定的地址装入初始的CS和IP
任何一个源程序都必须以END伪指令来结束。
其格式为: END 起始地址 - (2)在程序运行期间,当执行某些指令时,CPU自动修改CS和IP,使它们指向新的代码段。
4.6 过程定义伪指令(PROC/ENDP)
- 过程定义伪指令格式如下:
- 过程名 PROC [NEAR/FAR]
- ......
- RET
- ......
- 过程名 ENDP
- 过程名是子程序的名称,它被用作过程调用指令CALL的目的操作数。它类同一个标号的作用。
- 每一个过程中必须包含有返回指令RET,其作用是控制CPU从子程序中返回到调用该过程的主程序。
4.7 当前位置计数器$与定位伪指令ORG(Origin)
- 汇编程序在汇编源程序时,每遇到一个逻辑段,就要为其设置一个位置计数器,它用来记录该逻辑段中定义的每一个数据或每一条指令在逻辑段中的相对位置。
- 在源程序中,使用符号$来表示位置计数器的当前值。因此,$被称为当前计数器。它位于不同的位置具有不同的值。
- 定位伪指令ORG--用来改变位置计数器的值。
- 格式: ORG 数值表达式
- 作用:将数值表达式的值赋给当前位置计数器$ 。ORG语句为其后的数据或指令设置起始偏移量。
4.8 标题伪指令TITLE
- 语句格式: TITLE 标题名
- 作用:给所在程序指定一个标题。以便在列表文件的每一页的第一行都显示这个标题。其中标题是用户任意选用的字符串,字符个数不能超过60。
4.9 从程序返回操作系统的方法
- 一、使用程序段前缀PSP(Program Segment Prefix)实现返回
- 为了使程序执行完后,正确返回DOS,需要做以下三个操作:
-
- 将用户程序编制成一个过程,类型为FAR;
-
- 将PSP的起始逻辑地址压栈,即将INT 20H指令的地址压栈;
-
- 在用户程序结尾处,使用一条RET指令。执行该指令将使保存在堆栈中的PSP的起始地址弹出到CS和IP中。
- 二、使用DOS系统功能调用实现返回
- 执行DOS功能调用4CH,也可以控制用户程序结束,并返回DOS操作系统。
- 在程序结束时,使用两条指令:
- MOV AH,4CH
- INT 21H