学习 汇编语言程序设计 笔记
第一章 汇编语言的一般概念
1.1计算机程序设计语言可分为:
机器语言
机器能够识别的语言,把各种命令和数据用二进制直接表示
比较简单,但是人不好理解,它直接表示了计算机内部的基本操作,所以机器语言程序运行效率最高,但是不便于理解记忆
高级语言
更类似于自然语言,简单但是效率较低
汇编语言
在一些场合我们要使用效率高的语言来执行特殊操作,但又不希望使用机器语言
程序与机器语言程序相对应,效率也是相同的
与硬件密切相关
对于不同类型计算机来讲有不同的机器指令系统和汇编语言
对于一台计算机来说,机器语言的执行主要取决于计算机的CPU
1.2学习和使用汇编语言的目的:
1.可以根本上认识、理解计算机工作过程
2.在计算机系统中,某些功能必须用汇编语言程序实现
3.汇编语言效率高于高级语言程序
1.3进位计数制及其相互转换:
进位计数制:
进位计数制是利用固定的数字符号和统一的规则来计数的方法。
权:权是基数的幂,表示数码在不同位置上的数值
基数:每个数位上能使用不同数码的个数称为基数,例如十进制基数为10,二进制基数为2
数码:一组用来表示某种数制的符号。例如,十进制的数码是0~9;
权*对应位置数码=该位置数值大小
因为二进制不便于书写和阅读,因此书写时常使用8进制和16进制
为了区分不同进制表示,于是人们在数尾用一个字母表示相应进制:(注:未使用字母时,默认十进制)
>B ——二进制
>O ——八进制
>D ——十进制
>H ——十六进制
数制间转换:
1.十进制转二进制
(1)减权定位
从二进制数高位起,依次用待转换的十进制数与各位权值进行比较;如果够减,则该数位系数Ki=1,同时减去该位权值,余数作为下一次比较的值。
(2)除基取余法(也适用于其他数制)
将十进制数除以基数2,其余数为二进制数的最低位,再用其商除2,其余数为次低位,反复直到商为0
2.十进制小数转二进制数
(1)减权定位
(2)乘积取整法
用2乘十进制小数,可以得到积,将积的整数部分取出,再用2乘余下的小数部分,又得到一个积,再将积的整数部分取出,如此进行,直到积中的小数部分为零,或者达到所要求的精度为止。 然后把取出的整数部分按顺序排列起来,先取的整数作为二进制小数的高位有效位,后取的整数作为低位有效位。
3.二进制整数转换为十进制数
(1)按权相加法
(2)逐次乘基相加法
4.二进制小数转换为十进制数
(1)按权相加
从第一位开始依次乘2^-1、2^-2……最后相加
(2)逐次除基相加法
5.二进制与八进制和十六进制间的转换
三位二进制数对应一位八进制数,四位二进制数对应一位十六进制数
1.4带符号数的表示
用“+”或“-”表示正负的数叫真值
用“0”或“1”表示的数叫机器数(计算机中用这种表示)
带符号的机器数可以用原码、反码和补码三种不同的码值来表示。一般计算机用补码来表示。
(1)原码的表示
最高位表符号位,0为正,1为负
(2)补码的表示
(3)补码数的表示范围
当位数为8,最大为01111111(+127),最小为10000000(-128)
0的补码只有一个,000000000
(4)补码加减
1.5字符的表示
在计算机内部,各种字符都是按照一定的方式编写成二进制信息的,不用的计算机以及场合用的编码形式不同。目前最广泛的是ASCII码。
1.6基本逻辑运算
(1)与 ∧
(2)或∨
(3)非
(4)“异或”运算 ⨁
第二章 IBM-PC微机的功能结构
2.1IBM-PC微机的基本结构
一.微机的一般构成
一般计算机包括的五大部件:运算器、控制器、存储器、输入设备和输出设备。
微机将运算器和控制器集成在一个集成电路芯片上,称为中央处理器CPU。
系统采用总线结构,有较大的灵活性和扩展性。
系统总线由地址总线、数据总线和控制总线构成。(起控制和传输作用)
(1)中央处理器CPU
微计算机的中央处理器也叫微处理器,包括控制和运算器。
起分析从主存储器取来的各条指令的功能,控制计算机各部件完成指定功能的各项操作。
(2)主存储器
存放程序和数据,由若干存储单元构成。
存储单元多少表示存储器容量,每个存储单元有唯一编号标识,称为存储单元的地址;对其的存取也是通过地址访问的。
计算机存储信息的基本单位是一个二进制位,可存一个二进制数0、1。每8个组成一个字节;大多数计算机中存储器的组织都是以字节为基本单位,每个称为一个存储单元。
习惯上CPU+主存储器=主机
一般计算机中,除了主存储器还有辅存,由于其在计算机之外,因此也叫外存。
(3)输入输出设备及接口
将外部信息输入计算机
由于不同I/O设备之间的工作速度、工作原理以及所处理的信息格式等与主机相差很大,因此I/O设备要通过I/O接口与系统总线连接。
(4)系统总线
地址、数据、控制总线
二.Intel 8086/8088 CPU的功能结构
汇编语言程序由指令构成,指令是其基本单位。
CPU执行指令程序就是在重复执行:从存储器取指令、执行指令操作。这两个步骤执行方式又分为串行方式和指令流水线方式。
(1)串行方式
(2)指令流水线方式
流水线方式工作的计算机有较高的工作效率,可以有效充分利用各种硬件资源。
这种结构最先出现在Intel8086/8088CPU中,要实现该方式,CPU组成结构要划分为多个单元
执行单元EU:分析和执行指令
总线接口单元BIU:负责CPU与存储器、I/O的信息传送
这两个是独立又分工的独立部分,在一定程度上并行工作完成不同任务。
2.2Intel 8086/8088CPU寄存器结构及其用途
1. 8个通用寄存器、2个控制寄存器以及4个段地址寄存器
2.如下,H为高位、L为低位:
3.通用寄存器
(1)数据寄存器:包括AX、BX、CX、DX四个寄存器,用于存放操作数或运算结果。
e.g. MOV AX,BX
(2)指针寄存器:堆栈指针SP和基址指针BP
(3)变址寄存器:两个16位的变址寄存器,源地址寄存器SI和目的地址寄存器DI。
4.段寄存器
8086/8088CPU在使用存储器时,将其分为若干段,每段放不同的内容(程序代码、数据),每一段用一个段寄存器指名起始位置(段基址)。
代码段寄存器CS、数据段寄存器DS、堆栈段寄存器SS、附加段寄存器ES
5.指令指针IP
CPU从存储器取指令时,以CS作为代码段的基址指针,以IP内容为偏移量,共同形成指令存放地址
当CPU取出指令后,IP内容自动修改为指向下一条指令
IP的内容既不能用指令去读取,也不能用指令赋值。只能通过某些指令的执行而自动修改
6.标志寄存器
用来反映CPU运行时的某些状态。
2.3存储器的组织结构
###一.存储器的组成
1.由若干存储单元组成
2.每个单元放相同长度的二进制数
3.每个存储单元有唯一一个地址编号——地址
4.任何两个相邻字节单元就够成一个字单元
5.在定义一个地址时必须指出是字节或者字类型属性
###二.存储器的段结构
8086/8088CPU的存储结构特点:
将1MB的存储空间划分为若干个段,每个段最大长度为64KB、
每个段的基址必须是一个小节的首地址、
逻辑段在物理存储器中可以是邻接的、间隔的、部分重叠的和完全重叠的、
在任意时刻,一个程序只能访问4个当前段中的内容。
###三.逻辑地址与物理地址及对应关系
1.物理地址
2.逻辑地址
在程序设计中,为了便于程序的开发和对存储器进行动态管理,使用逻辑地址。包含段基值和偏移量两个部分
3.逻辑地址转换为物理地址
将逻辑地址的端基值左移4位,形成20位的段基址(低4位为0)然后与16为的偏移量相加,结果即为20位的物理地址
4.逻辑地址来源
2.4堆栈及其操作方法
堆栈是一个特定的存储区,访问该存储区一般需要按照专门的规则进行操作
堆栈的用途:主要用于暂存数据以及在过程调用或处理中断时保存断点信息
###一.堆栈的构造
分为专门堆栈存储器(按堆栈工作方式专门设计的)、软件堆栈(由设计人员在内存中划出。注:8086/8088采用该方式)
在堆栈中存取数据规则为“先进后出FILO”
###二.堆栈的组织
以8086/8088为例,数据在堆栈中以字(两字节)为单位存放,数据的低8位放在较低地址单元,高8位放在较高地址单元。
###三.堆栈操作
1.设置堆栈
主要是对堆栈寄存器SS和堆栈指针SP赋值
e.g STACK1 SEGMENT PARA STACK DB100 DUP (0) STACK1 ENDS
PARA STACK说明本段为堆栈段,在程序经汇编、连接并装入内存时,系统将自动为其分配一个存储区作为堆栈段。
2.进栈PUSH
把数据存入堆栈
e.g PUSH AX
3.出栈POP
出栈操作由POP指令或机器自动实现,它从堆栈顶部弹出一个字到通用寄存器、段寄存器或字存储单元
e.g POP AX
第三章 寻址方式与指令系统
3.1寻址方式
1.一条指令由操作码和操作数两部分组成
操作码:表示该指令应完成的具体操作,如加法、减法、乘法、移位等,在汇编语言中使用一定的符号表示,称为助记符。如ADD、PUSH、POP、MOV等
操作数:操作码的操作对象
2.寻址方式:寻找指令中所需操作数的各种方法,也就是提供指令中操作数的存放信息的方式
3.Intel 8086/8088各指令中提供操作数的方法有一下四种:
(1)立即数操作数——操作数在指令代码中提供
(2)寄存器操作数——操作数在CPU的通用寄存器或段寄存器中
(3)存储器操作数——操作数在内存的存储单元中
(4)I/O端口操作数—— 操作数在输入/输出接口的寄存器中
4.立即数寻址 操作数作为指令的一部分而直接写在指令中,这种操作数称为立即数,这种寻址方式也就称为立即数寻址方式。
5.存储器寻址 指令所要的操作数已存储在某寄存器中,或把目标操作数存入寄存器。把在指令中指出所使用寄存器(即:寄存器的助忆符)的寻址方式称为寄存器寻址方式。由于存取寄存器操作数完全在CPU内部进行,不需要总线周期,所以速度很快。
一个存储单元逻辑地址表示方式: 段基址: 偏移量 段基址由某个寄存器提供;偏移量表示了该存储单元与段起始地址之间的距离,也叫有效地址EA。
EA由位移量、基址、变址三种地址分量组合,再由CPU执行单元EU计算出来。
6.直接寻址 指令所要的操作数存放在内存中,在指令中直接给出该操作数的有效地址,这种寻址方式为直接寻址方式。在这种方式的指令中,有效地址EA只有位移量地址分量。
在汇编语言中,直接寻址方式用符号或常数来表示
1)用符号表示
MOV BX,VAR;表示将数据段中,偏移了VAR个字节距离的字单元内容送到寄存器BX中
2)用常数来表示
MOV AX,DS:[64H](不加方括号则表示将100送到AX中)表示从当前数据段开始,偏移100个字节的字单元内容送到AX中。不能写为MOV AX,64H,一定要带方括号
注意:立即寻址方式和直接寻址方式的书写格式的不同,直接寻址的地址要写在括号“[”,“]”内。在程序中,直接地址通常用内存变量名来表示,如:MOV BX, VARW,其中,VARW是内存字变量。
试比较下列指令中源操作数的寻址方式(VARW是内存字变量):MOV AX,1234H MOV AX, [1234H] ;前者是立即寻址,后者是直接寻址 MOV AX, VARW MOV AX, [VARW] ;两者是等效的,均为直接寻址
7.寄存器间接寻址方式:
操作数在寄存器中,操作数有效地址在SI、DI、BX、BP这四个寄存器之一中。在不使用段超越前缀的情况下,如果有效地址在SI、DI和BX中,则以DS段寄存器中的内容为段值。如果有效地址在BP中,则以SS段寄存器中的内容为段值。
8.寄存器相对寻址方式:
操作数在存储器中,操作数的有效地址是一个基址寄存器(BX、BP)或变址寄存器(SI、DI)的内容加上指令中给定的8位或16位位移量之和。
9.基址加变址寻址方式:
操作数在寄存器中,操作数的有效地址由:
基址寄存器之一的内容与变址寄存器之一的内容相加BX SI 即: EA = BP+ DI在一般情况下,如果BP之内容作为有效地址的一部分,则以SS之内容为段值,否则已DS为段值。
例如:MOV AX,[BX][DI] 如:(DS)=2100H,(BX)=0158H,(DI)=10A5H,则EA=0158 + 10A5 = 11FD 物理地址=21000 + 11FD = 221FDH 221FDH地址中的内容:1234H 执行该指令后AX = 1234H
10.相对基址加变址寻址方式:
操作数在存储器中,操作数的有效地址由于基址寄存器之一的内容与变址寄存器之一的内容及指令中给定的8位或16位位移量相加得到。
11.I/O端口寻址
在计算机系统,对I/O端口的寻址方式有存储器编址方法和I/O端口编址方法两种方法
存储器编址方法、I/O端口编址方法(8086/8088系统采用方式)
3.2指令系统
###1.一种计算机所能执行的各种类型的指令的集合称为该计算机的指令系统
Intel8086/8088CPU指令系统指令分为六大类:传送类指令、算术运算类指令、位操作类、串操作类、程序转移类、处理器控制类。
###2.从指令的格式划分,一般可以分为三种:
双操作数指令:OPR DEST SRC
单操作数指令:OPR DEST
无操作数指令:OPR
3.3指令编码
###1.汇编:
将汇编语言程序转换为机器语言程序的过程
###2.汇编程序:
在计算机中实现汇编过程的系统程序
###3.Intel8086/8088汇编指令的编码格式有四种基本格式:
双操作数指令编码格式
单操作数指令编码格式
与AX或AL有关的指令编码格式
其它指令编码格式
如标志位操作指令、堆栈操作指令等。这些指令的编码格式一般只有一个字节
第四章 汇编语言程序格式
4.1汇编语言语句种类及其格式
汇编语言的语句可以分为指令语句和伪指令语句
一、指令语句
每一条指令语句在汇编时都要产生一个可以供CPU执行的机器目标代码,又叫可执行语句。
一般格式为:标号:指令助记符,操作数,;注释(四个字段)
(1)标号:
这是指令语句中的可选字段。如果一条语句中定义标号,必须以“:”作为结束符。一个标号是一条指令的符号地址,它代表该指令的第一个字节地址。因此,一个程序段或子程序的入口处,通常设置一个标号。当程序需要转入该程序时,在转移指令或调用子程序指令中,可直接引用这个标号。e.g ADDR1:MOV AL ,100中的ADDR1。
(2)操作符(指令助记符):
指令操作符和伪指令符是语句中不可省略的主要成分。指令操作符就是指令的助记符,如 MOV、ADD、SHL 等,它表示该语句要求 CPU 完成的具体操作。伪指令符可以是数据定义伪指令、段定义伪指令、过程定义伪指令、程序连接伪指令等,它们是要求汇编程序在对源程序进行汇编时进行何种操作的命令。
(3)操作数及参数
指令语句的操作数是指令操作的对象。不同的指令,要求的操作数个数不同,可以是一个、两个或无操作数。伪指令语句参数的个数也因不同的伪指令而异,这些参数可以是一个常数、字符串,以及一些专用符号等,它们是伪指令语句命令的类型及命令格式等说明参数。有时伪指令的参数可以省略。如ADD和MOV需要两个。
(4)注释字段
这是一个任选字段。注释字段必须以分号“;”开始,它可对程序或指令加以注解,提高程序的可读性。当需要作较多的文字说明时,注释可以独占一行或多行,但每行第一个有效字符必须是分号。注释字段的内容不影响程序和指令的功能,它也不出现在机器目标代码中。
二、伪指令语句
又叫命令语句,伪指令本身并不产生对应的机器目标代码。它仅仅是告诉汇编程序对其后面的指令语句和伪指令语句的操作数应该如何处理。一条伪指令语句可以包含四个字段:
(1)符号名字段
该字段为可选项。根据伪指令的不同,符号名可以是常量名、变量名、过程名、结构名和记录名等等,符号名后面没有冒号“:”,这是与指令语句的重要区别!
(2)伪指令符字段
(3)操作数字段
(4)注释字段为可选项,该字段必须以分号开始。其作用与指令语句的注释字段相同
4.2汇编语言数据
1. 数据是指令和伪指令语句中操作数的基本组成部分。一个数据由数值和属性两部分构成
2 .在汇编语言中常用的数据形式有:常数、变量和标号
常数
在汇编期间其值已完全确定,并且在程序运行过程中,其值不会发生变化
可以用在以下几种情况
作指令语句的源操作数
在指令语句的直接寻址方式、变址(基址)寻址方式或基址变址寻址方式中作位移量
在数据定义伪指令中使用
变量
变量用来表示存放数据的存储单元,这些数据在程序运行期间可以被改变
程序中以变量名的形式来访问变量,因此,可以认为变量名就是存放数据的存储单元地址
变量被定义后有以下三个属性:
段属性
偏移属性
类型属性
标号
标号写在一条指令的前面,它就是该指令在内存的存放地址的符号表示,也就是指令地址的别名;标号主要用在程序中需要改变程序的执行顺序时,用来标记转移的目的地,即作转移指令的操作数
4.3 符号定义语句
在源程序设计中,使用符号定义语句可以将常数或表达式等内容用某个指定的符号来表示。
8086/8088汇编语言中有两种符号定义语句:
1.等值语句。语句格式:符号名 EQU 表达式
2.等号语句。语句格式:符号名=表达式
功能:与等值语句具有相同的作用。但等号语句可以对一个符号进行多次定义
4.4表达式与运算符
1.表达式:
定义:常数、符号、寄存器等通过运算符连接起来的式子。
对表达式的运算不是CPU完成的,而是在汇编时汇编程序运算的。
2.运算符:
可分为以下几类:
(1) 算术运算符
(2)逻辑运算符
(3)关系运算符
(4)数值返回符
(5) 修改属性符
(6)其他
(7)优先级
4.5程序的段结构
8086/8088在管理内存时,按照逻辑段进行划分, 不同的逻辑段可以用来存放不同目的的数据。在程序 中使用四个段寄存器CS,DS,ES和SS来访问它们。在源程序设计时,使用伪指令来定义和使用这些逻辑段。
一、段定义伪指令
伪指令SEGMENT和ENDS用于定义一个逻辑段。使用时必须配对,分别表示定义的开始与结束。
段定义伪指令语句各部分的作用如下:
1、段名
段名是由用户自己任意选定的,符合标识符定义规则的一个名称。
2、定位类型
定位类型用于决定段的起始边界,即第一个可存放数据的位置(不是段基址)。它可以有4种取值。
3、组合类型
组合类型说明符用来指定段与段之间的连接关系和定位。它有六种取值选择。
(1)若未指定组合类型,表示本段与其它段无连接关系。在装入内存时,本段有自己的物理段,因此有自己的段基址
(2 )PUBLIC:在满足定位类型的前提下,将与该段同名的段邻接在一起,形成一个新的逻辑段,共用一个段基址。段内的所有偏移量调整为相对于新逻辑段的段基址。
(3)COMMON:产生一个覆盖段。在多个模块连接时,把该段与其它也用COMMON说明的同名段置成相同的段基址,这样可达到共享同一存储区。共享存储区的长度由同名段中最大的段确定。
(4)STACK:把所有同名段连接成一个连续段,且系统自动对SS段寄存器初始化为该连续段的段基址。并初始化堆栈指针SP。用户程序中应至少有一个段用STACK说明,否则需要用户程序自己初始化SS和SP。
(5)AT表达式:表示本段可定位在表达式所指示的小节边界上。表达式的值也就是段基值。
(6)MEMORY:表示本段在存储器中应定位在所有其它段之后的最高地址上。如果有多个用MEMORY说明的段,则只处理第一个用MEMORY说明的段。其余的被视为COMMON
4.类别名
类别名为某一个段或几个相同类型段设定的类型名称。系统在进行连接处理时,把类别名相同的段存放在相邻的存储区,但段的划分与使用仍按原来的设定。
类别名必须用单引号引起来。所用字符串可任意选定,但它不能使用程序中的标号、变量名或其它定义的符号。
在定义一个段时,段名是必须有的项,而定位类型、组合类型和类别名三个参数是可选项。各个参数之间用空格分隔。各参数之间的顺序不能改变。
二、段寻址伪指令
段寻址伪指令ASSUME的作用是告诉汇编程序,在处理源程序时,定义的段与哪个寄存器关联。
三、段寄存器的装入
段寄存器的初值(段基值)装入需要用程序的方法来实现。四个段寄存器的装入方法略有不同。
1、DS和ES的装入
在程序中,使用数据传送语句来实现对DS和ES的装入。
2、SS的装入
SS的装入有两种方法
(1)在段定义伪指令的组合类型项中,使用STACK参数,并在段寻址伪指令ASSUME语句中把该段与SS段寄存器关联。
(2)如果在段定义伪指令的组合类型中,未使用STACK参数,或者是在程序中要调换到另一个堆栈,这时,可以使用类似于DS和ES的装入方法。
3、CS的装入
CPU在执行指令之前根据CS和IP的内容来从内存中提取指令,即必须在程序执行之前装入CS和IP的值。因此,CS和IP的初始值就不能用可执行语句来装入。
装入CS和IP一般有下面两种情况。
(1)由系统软件按照结束伪指令指定的地址装入初始的CS和IP任何一个源程序都必须以END伪指令来结束。
(2)在程序运行期间,当执行某些指令时,CPU自动修改CS和IP,使它们指向新的代码段。
4.6过程定义伪指令
在程序设计过程中,常常将具有一定功能的程序段 设计成一个子程序。在MASM宏汇编程序中,用过 程(PROCEDURE)来构造子程序
过程定义伪指令格式如下:
过程名 PROC [NEAR/FAR]
...... RET ......
过程名 ENDP
过程名是子程序的名称,它被用作过程调用指令CALL的目的操作数。它类同一个标号的作用。具有段、偏移量和距离三个属性。而距离属性使用NEAR和FAR来指定,若没有指 定,则隐含为NEAR。每一个过程中必须包含有返回指令RET,其作用是控制CPU从子程序中返回到调用该过程的主程序
4.7 当前位置计数器与定位伪指令ORG(Origin)
汇编程序在汇编源程序时,每遇到一个逻辑段,就要为其设置一个位置计数器,它用来记录该逻辑段中定义的每一个数据或每一条指令在逻辑段中的相对位置。
在源程序中,使用符号S来表示位置计数器的当前值。因此,S被称为当前计数器。它位于不同的位置具有不同的值。
位置计数器S在使用上完全类似变量的使用.
4.8编题伪指令TITLE
给所在程序指定一个标题。以便在列表文件的每一页的第一行都显示这个标题。其中标题是用户任意选用的字符串,字符个数不能超过60
4.9从程序返回操作系统的方法
为了使程序运行结束后,能够正确地返回到操作系统,需要在程序中加上一些必要的语句。一般有以下两种方法:
(1)使用程序段前缀PSP(Program Segment Prefix)实现返回
(2)使用DOS系统功能调用实现返回