80×86汇编语言程序设计

目录 第一章 基础知识 1.1汇编语言的特点 1.2计算机中数据表示的特点 【BCD码表示法(Binary Coded Decimal)】 【定点数】 —原码表示法— —反码表示法— —补码表示法— 浮点数 1.3 ​​​​​​计算机的数据存储 寄存器 存储器 数据在主存中的存储方式​编辑 第二章8086宏汇编的源程序组成 2.1 源程序的分段结构 2

目录

第一章   基础知识

1.1汇编语言的特点

1.2计算机中数据表示的特点

【BCD码表示法(Binary Coded Decimal)】

【定点数】

—原码表示法—

—反码表示法—

—补码表示法—

浮点数

1.3 ​​​​​​计算机的数据存储

寄存器

存储器

 数据在主存中的存储方式​编辑

第二章8086宏汇编的源程序组成

2.1 源程序的分段结构

2.2汇编语言的语句结构

2.2.2操作项

2.2.3操作数项

2.2.4 注释项

2.3 常用伪指令

2.3.1处理器选择伪指令(略)

2.3.2段定义及源程序结束伪指令

源程序结束伪指令

3.3.3变量定义与存储空间分配伪指令

2.3.4替代符定义伪指令

2.3.5 段内偏移地址伪指令

2.3.6 过程定义与宏定义伪指令

第三章  8086指令系统

3.2寻址方式

寄存器寻址方式

立即寻址方式

存储器寻址方式

直接寻址方式

寄存器间接寻址方式

寄存器相对寻址方式

基址变址寻址方式


第一章   基础知识

1.1汇编语言的特点


  • 1、计算机的程序设计语言-简称计算机语言-是人们用来给计算机描述操作任务的工具;
  • 2、机器语言是机器指令的集合;汇编语言的主体是汇编指令。机器语言和汇编语言都属于计算机语言中的低级语言,其余均为高级语言。
  • 3、最初的计算机语言是直接用二进制代码来表述的,也就是机器语言;为了便于掌握和使用,人们将机器语言符号化,产生了汇编语言。然而,计算机不能直接理解汇编语言的符号系统,需要一个转换工具即汇编程序。
  • 4、汇编语言编程时,必须准确的指出数据存放的地方——某个寄存器、某个存储单元或某个I/O端口,必须直接控制相关设备完成相应的输入/输出。
  • 1.2计算机中数据表示的特点


  • 1、几种常用的数制的规定标志是:
  • B:代表二进制

    D:代表十进制

    O:代表八进制

    H:代表十六进制

  • 2、字符在计算机中二进制编码称为字符代码,目前计算机中普遍使用的字符代码是ASCII码(美国信息交换准代码)。
  • 3、基本字符集是各类应用中主要使用的字符集,由ASCII字符集的前128个字组成,编码范围是 0000 0000—0111 1111;

      基本字符集的ASCII码的最高位都为0,因此称ASCII码为7位编码(最高位上的0被忽略)。

     4、扩展字符集由ASCII字符集的后128个字符组成,包含一些图形符号和制表符号等,编码范         围是 1000 0000—1111 1111,一般较少使用。

       一个字符的ASCII码在存储器中存放时,需要占用存储器的一个字节。

     5、数值数据是计算机中用于各种算术运算的数据,数值数据在计算机中的表示方法有BCD码       表示法、定点数表示法和浮点数表示法三种。

【BCD码表示法(Binary Coded Decimal)】

BCD码采用4为二进制编码表示1为二进制数,分有权码与无权码两类。计算机中使用的是一种有权BCD码—8421码,运算结果为正数时也可以用8421码表示。

BCD码是十进制数,当两个8421码相加时:

如果和等于或小于 1001(即十进制数9),则不需要修正;

如果相加之和在 1010 到1111(即十六进制数 0AH~0FH)之间,则需加 6 (0110)进行修正。

这样做的原因是,机器按二进制相加,所以 4 位二进制数相加时,是按“逢十六进一”的原则进行运算的,而实质上是 2 个十进制数相加,应该按“逢十进一”的原则相加,16 与10相差 6,所以当和超过 9或有进位时,都要加 6 进行修正

8421码虽然可用于十进制数的运算,但由于其数据表示效率低(4位二进制数只能表示一位十进制数),且运算效率也很低(需要对结果进行调整),所以在实际应用中很少使用。

【定点数】

—原码表示法—

原码是最直观的机器数表示法,它以0表示正号,以1表示负号,直接置于数的最左端(即最高位),而数字部分于其绝对值一致。

计算机中的主要数据表示方法有定点数表示法和浮点数表示法,定点数表示法也是浮点数表示法的基础。

所谓的定点数表示法,是指小数点被固定在数据中某个特定的位置上的数据表示法,如果把小数点固定在数据最低有效位的右边,称为定点整数;如果固定在最高有效位的左边,则定点数纯为小数,称为定点小数。

符号的表示是定点数表示必须要解决的问题,带符号的定点数有原码、补码、反码等几种编码表示法。

n位原码(包括符号位)的数据表示范围是

当n=8时,8位原码的数据范围是 -127~127;

当 n=16时,16为原码的数据范围是 -32767~32767。

—反码表示法—

正数的反码于其原码一致,负数的原码与其原符号位相同,数字按位取反。

—补码表示法—

,则X的补码定义为    (mod)

其中n为所形成的补码位数(包括符号位);

mod表示“模”运算,即“相除取余数”运算

  被称为“模数”,mod表示“除以 取余数”;

所形成的n位补码中,最高位为符号位,数字部分为n-1位,X的实际取值范围为

 

n=8时8位补码的数据表示范围是-128~127;

N=16时16位补码的数据表示范围是-32768~32767。

计算(减法)

计算(进位)

计算(溢出)

浮点数

定点数在计算机及多媒体数据处理中有着广泛的应用,但其缺点也很明显:一是表示数据的精度差;二是表示数据的范围小;因此不适合科学计算。

科学计算要求用有限的数据编码位,获得更大的数据表示范围和更高的是数据表示精度,这就需要采用浮点数表示形式。

浮点数的小数点可以出现在任意位置,一人浮点数可表示为(科学计数):(构成要素:指数e,基数R,有效数字m)

一个计算机系统中一般有两个指令集:定点指令集和浮点指令集。一般说CPU是一个定点指令处理器,负责执行定点指令,而浮点指令需要专门的浮点协处理器来执行。

浮点运算有两种实现方法:一是用定点指令编程模拟实现(软件),二是用浮点协处理器执行浮点指令来实现(硬件)。

浮点数的一般表示格式:

1.3 ​​​​​​计算机的数据存储

 计算机中可以用于存储数据的装置有:CPU内部存储器;计算机的存储器;I/O端口(即I/O设备接口中的一些寄存器)

寄存器

 8086CPU系统中,根据用途不同寄存器可分为三组:通用寄存器、专用寄存器和段寄存器。

 通用寄存器:

BP、SI、DI 三个寄存器为不能分解的16位寄存器。

AX: 累加器,使用频度高,用于算术、逻辑运算以及外设传送信息等

BX:基址寄存器,常用存放存储地址

CX:计数器,作为循环和串操作等指令中的隐含计数器

DX:数据寄存器,存放双字长数据的高16位,或存放外设端口地址

专用寄存器:(16位)

寄存器:

8086系统中一个汇编语言程序最多可以同时操作4个活跃的段,所以共设有4个段寄存器

存储器

  1. 、计算机的内存包括主存(也称内存)和辅存(也称外存,如硬盘存储器)。CPU只能直接访问计算机的主存,所以,CPU执行程序和处理的数据都是存在主存中的。
  2. 、主存的容量是以存储单元的数量来计算的。大多数算计以1字节(8位二进制)大小来定义一个存储单元,即一个存储单元可以存放一个8位二进制数。长用的量级有:

  KB(2^{10}字节)、MB(2^{20}字节)、GB(2^{30}字节)、TB(2^{40}字节

 

  1. 、计算机对主存的每个存储单元(字节)从0开始编号,并以此编号来确定存储单元的位置。编号也称为存储单元的地址,读写数据都必须指出存储单元。
  2. 、地址是在CPU对主存做读写操作时,由CPU发出的,所以地址是在CPU中形成的。8086系统CPU要形成20位的主存地址,但是CPU内部的寄存器均为16位,为此8086系统对主存采用分段模式。
  3. 、分段模式下,一个段的最大内容被限制在64KB(2^{16}字节)因此,在一个段的范围内,只需16位地址就能准确指出每个存储单元,16位地址可以用16位寄存器来存放,但是,这个16位地址只是相对于一个段的内部来定义的,称为段内地址(或段内偏移),并不是20位主存实际地(也称主存物理地址),并不能直接用来访问主存。
  4. 、段内一个存储单元的物理地址是该存储单元的段内偏移地址与该段的段地址之和。8086系统的分段模式下,一个存储单元的地址要用段地址和段内偏移地址两部分表示,这样的地址也称为逻辑地址,是汇编语言所用的地址表示形式。
  5. 、8086系统规定,只有能被16整除的物理地址才能作为段地址。其二进制的表示为如下特征:

段地址的最低四位必为0,其中的X表示0或1,CPU中的段寄存器实际只存放了段地址的高16位,CPU中的地址加法器会在将逻辑地址转换成物理地址使,自动在16位段地址低位部分添加4个0,然后再与偏移地址相加。 

 数据在主存中的存储方式

I/O接口是I/O设备与计算机主机相连时的连接电路,CPU与I/O设备交换数据(输入/输出操作)都要经过I/O接口。

I/O接口中设置有三类寄存器:数据寄存器、控制寄存器、状态寄存器,这些寄存器统称为I/O端口,均为8位寄存器,端口地址长度为16位,可以为 2^{16} 个I/O端口编地址。

访问端口需要专门的指令,称为输入/输出指令即I/O指令。

  • 第二章8086宏汇编的源程序组成

2.1 源程序的分段结构

(1)、一个源程序包含三个段:代码段、数据段和堆栈段,其段地址分别存于寄存器CS、DS和SS中。

(2)、由于一个主存段最大只有64KB,所以在一个段的存储容量不够时,可以多定义一些段(定义多个数据段/代码段等),所以一个源程序可包含的段不受限制,但由于8086CPU只提供了4个段寄存器,所以一个源程序最多只能同时操作4个段,操作其他段是必需先将该段的地址存入某个寄存器。

2.2汇编语言的语句结构

(1)、汇编语句的一般结构为:

              [名字项]  操作项  [操作数项]   [; 注释项]  ([] 内为可选项)

汇编指令可分为三类:

   伪指令:

用于说明程序运行的处理平台,进行段定义、变量与常量定义、过程定义、源程序的开始与结束定义等。

伪指令语句是用来指示汇编程序如何进行源程序汇编的,而不是用来直接实现程序操作功能的。

   指令语句:

一条指令语句包含一条汇编语言指令,程序的操作功能是由指令语句来实现的。

   宏指令语句:

是宏汇编语言允许程序员自定义的一种特殊形式的指令,一条宏指令相当于一小段程序。

2.2.1 名字项

名字项就是一个符合特定规则的字符串,其最大长度不超过30个字符。

伪指令当中的名字项涉及如下:

指令语句中的名字项

指令语句中的名字项称为指令标号,使用时需要加上“:”,

使用格式为:“指令标号:”用于标记当前指令的位置。

  1. 、指令标号的三个属性:类型属性、段地址属性、偏移地址属性,有近(near)和远(far)两种。
  2. 、如果指令标号作为本段代码内某条指令的转移目标,就是near类型;作为其他代码段内转移指令的转移目标,即为far类型。

2.2.2操作项

用来描述一条语句的操作功能,是伪指令、指令或宏指令的助记符。操作项是一条必不可少的语句。

2.2.3操作数项

(1)、操作数项是用来描述一条语句的操作对象。根据语句功能的不同,数量不一,也可以没有操作数项。

(2)、具体的操作数项可以是常量、变量、寄存器、指令标号、过程名、段名或表达式,其内容可以是数据或地址。

(3)、表达式中只能包含已知量,不能出现程序运行过程中动态确定的量。

表达式中常用的运算符:

2.2.4 注释项

注释项必须以“;”号开始(英文状态下)

2.3 常用伪指令

2.3.1处理器选择伪指令(略)

2.3.2段定义及源程序结束伪指令

汇编语言采取分段结构,段定义伪指令用于对程序的各个段进行定义,一般格式为:

                          段名  SEGMENT  [定位类型]  [组合类型]  [‘类别’]

                          .......  ;  段的具体内容

                          段名   ENDS

源程序结束伪指令

源程序各段定义都结束后,必须用源程序结束伪指令来结束整个源程序,格式为:

                                                 END  [指令标号]  

(指令标号为程序入口指令-即运行时第一条要执行的指令-的标号,用以指出程序的入口,单模块或多模块中的主模块必须有指令指标)

SSEG  SEGMENT  STACK;堆栈段定义,采用了stack组合类型
.......  ;  在此定义堆栈段的内容
SSEG  ENDS ;堆栈段定义结束
DSEG  SEGMENT ;数据段定义
.......  ;  在此定义数据段的内容
DSEG  ENDS ;数据段定义结束
CSEG  SEGMENT ;代码段定义
ASSUME  CS: CSEG , SS : SSEG ;建立段寄存器与段之间的关系
START : MOV  AX , DSEG ; 程序入口指令(标号start),
                        ; 将数据段的段地址传给AX 寄存器
        MOV  DS , AX ;将数据段的段地址从AX 传到数据段寄存器DS
; 完成对DS的装载
         ......... ; 代码段的其它内容
      MOV  AH ,4CH 
;以下两条指令用于结束程序运行,返回操作系统命令状态
     INT  21H
CSEG  ENDS  ;代码段定义结束
EDN  START  ;源程序结束,同时用程序入口指令标号start指出程序入口

3.3.3变量定义与存储空间分配伪指令

这类伪指令主要用在堆栈段和数据段中,为堆栈分配存储空间,以及定义程序中需要的各种类型变量。格式:

                         [变量名]  类型定义操作符  数据项或表达式列表

“数据项或表达式项”是由多个数据项或表达式组成的序列,各项之间用“,”隔开。

数据段分析:

DSEG  SEGMENT    ;【(SEGMENT)段定义操作  (VAR1)变量名】
  VAR1  DB  46H   ;字类型单变量【(DB)定义字节类型】
  VAR2  DW  2A05H  ; 字节类型单变量【(DW)定义字类型】
  VAR3  DB  26*3 ,  -53 ,  00101001B  ;有3个元素的字节类型数组
  VAR4  DW  12H ,  0A186H  ;有2个元素的字类型数组
DSEG  ENDS    ;【(DSEG)段名    (ENDS)段结束操作】

变量名也称符号地址,可在源程序中直接使用。

数据段在主存中的映像:

字符变量

字符变量也是程序设计中常用的数据,分析:

CHAR1  DB  ‘B’   ;单字符变量,采用字符常量形式赋初值’b’
CHAR2  DB  52H     ;单字节变量,采用ASCII码形式赋初值52H
STR1  DB  ‘C’,‘o’,‘m’,‘p’,‘u’,‘t’,‘e’,‘r’
STE2  DB  ‘program’ ;str1和str2均为字符串,字符串本意上是字符数组

字符在计算机中是以ASCII码表示的,一个字符的SACII码占用主存的一个字节,所以,无论是单字符变量还是字符串,都必须按字节类型定义(DB)。

很多情况下,定义变量和数组时不需要赋初值,只是用“?”来分配存储空间

VAR5  DB  ?    ;为字节类型变量VAR5分配1个字节的存储空间
VAR6  DW  ?,?,?,?,?,?,?,?,?,?   ;为字类型数组VAR6分配10个元素的空间
VAR7  DB  50,?,35H,?,?    ;对VAR7某些元素赋初值,某些分配空间

元素较多且按一定规律重复时,我们使用特殊操作符-DUP来定义

重复次数   DUP(数据项或表达式项)

DUP操作符按指定的重复次数,对()内的数据项或表达式进行重复定义

ARR1  DB  100  DUP(?)  ;为字节类型数组ARR1分配100个元素的存储空间
ARR2  DW  50  DUP(0)  ;为字类型数组ARR2分配50个元素的存储空间,并清0
ARR3  DB  5  DUP(12H,86H)  ;定义具有10个元素的字节类型数组ARR3,并赋初值
ARR4  DB  65H,3  DUP(4AH,05H),30H ;定义具有8个元素的字节类型数组,并赋初值

分析:

定义一个大小为32个字的堆栈

SSEG  SEGMENT  STACK
   DW  32  DUP(?)  ;为堆栈分配32个字的存储空间
SSEG  ENDS

 一些属性的运算符可以与变量或标号组成特殊的属性表达式

 分析例题

DSEG  SEGMENT    ;【(SEGMENT)段定义操作  (VAR1)变量名】
  VAR1  DB  46H   ;字类型单变量【(DB)定义字节类型】
  VAR2  DW  2A05H  ; 字节类型单变量【(DW)定义字类型】
  VAR3  DB  26*3 ,  -53 ,  00101001B  ;有3个元素的字节类型数组
  VAR4  DW  12H ,  0A186H  ;有2个元素的字类型数组
DSEG  ENDS    

若有以下代码插入

OFFSET  VAR1   ;求取符号地址VAR1的段内偏移地址属性,结果为0
OFFSET  VAR2+1 ;求取地址表达式VAR2+1的偏移地址属性,结果为2
SEG  VAR3   ;求取符号地址VAR3的段地址属性值,同一段内定义的变量或数组,其段地址属性都是相同的
WORD  PTR  VAR3 ;对字节类型的VAR3重新指定为按字类型访问
BYTE  PTR  VAR4+2 ;将字类型的AVR4+2重新指定为按字节类型访问

2.3.4替代符定义伪指令

用EQU伪指令定义替代符 格式:

替代符  EQU  表达式

表达式中可包含:常量、以及定义过的其它符号(变量名、标号、替代符...)或汇编语言规定使用的一些符号

用“=”伪指令定义符号 格式:

替代符 = 表达式

“=”伪指令所起的作用于EQU伪指令相同,但“=”伪指令定义的替代符可在同一个源程序中重复定义。“=”伪指令对的替代符的有效范围从它被定义开始到下一次被定义为止。

2.3.5 段内偏移地址伪指令

段内偏移地址指针$

汇编程序给每个段设置里一个段内偏移地址指针($),用以跟踪汇编过程,动态指出段内下一个可分配的存储单元的偏移地址。

段内偏移地址指针设置伪指令 格式:

ORG  常量表达式

ORG伪指令将常量表达式的值作为段内偏移地址,直接赋予$指针

DSEG  SEGMENT
 DAT1  DB  14H  DUP(?)
 ORG  100H
 DAT2  DW  1375H,2468H
DSEG  ENDS

若没有ORG伪指令,DAT2应紧接着DAT1定义,其首地址应该为14H(段内偏移地址),ORG将$指针修改为了100H,因此DAT2是在段内偏移地址100H处定义的,首地址为100H。

2.3.6 过程定义与宏定义伪指令

过程定义宏指令也称子程序 格式:

过程名  PROC  [类型]

......  ; 过程的具体代码

过程名  ENDP

PROC 表示过程定义开始,ENDP 表示过程定义结束。过程的类型有近(NEAR)和远(FAR)两种。

NEAR  :指过程与其调用程序代码在同一个代码段内,为默认值

FAR   :则指过程与其调用程序不在同一代码段内

过程名具有三个属性:类型属性、段地址属性、偏移地址属性。

宏定义伪指令用于定义宏指令  格式:

宏指令名  MACRO  [形式参数表]

...... ;宏体

ENDM

宏体就是一段程序,这段程序的功能就是对应宏指令的功能

  • 第三章  8086指令系统

(为了方便梳理指令,我先把寻址方式放在前面)

3.2寻址方式

指令中描述操作数地址的方式,称为操作数的寻址方式,简称寻址方式。寻址方式是汇编语言程序设计的重要基础。

寄存器寻址方式

若操作数由寄存器提供,或操作结果要存入寄存器,则对应的操作数项就要指出所用的寄存器,操作数的这种方式就叫做寄存器寻址方式。

被加数和加数分别存于寄存器AL和BL中,写出加法指令:

ADD  AL,BL

操作功能是:AL   —— (AL)+(BL),若(AL)=25H ,(BL)=36H,则AL 寄存器的内容为25H + 36H = 5BH ,而BL 中的内容不变。

将BX寄存器中所存的数据传送给AX寄存器的指令:

MOV  AX ,BX

其操作功能是:AX   —— (BX) ,若执行前(AX)=1205H,(BX)=3600H,则执行指令后AX寄存器内容为3600H,BX寄存器内容不变。

立即寻址方式

若一个操作数项描述的是操作数本身(常量或表达式表示),而不是操作数的存放位置,则该操作数的寻址方式为立即寻址方式,表示该操作数的常量或表达式成为立即数。

将数据68传送给AL寄存器的指令:

MOV  AL,68      

其操作功能是:AL  —— 68

被加数存于寄存器DX中,加数为512,写加法指令

ADD  DX, 512

立即寻址方式描述的是一个常量,而不是一个存放数据的位置,所以,立即寻址方式不能用于目的数的操作。

存储器寻址方式

若操作数存于存储器中,则对应的操作数项就要描述出操作数的存放地址,操作数的这种寻址方式称为存储器寻址方式。

指令中的存储器地址都是逻辑地址,其中段地址由段寄存器提供,用段前缀(DS: , ES: , CS: , SS: )来指明所用的段寄存器,偏移地址(亦称有效地址)部分的表示形式有很多种。

直接寻址方式

如果在描述操作数的地址时直接表示出操作数的偏移地址,则该操作数的寻址方式就是直接寻址方式

将存于数据段内偏移地址为0010H处的一个字节数据传送给寄存器AL,写出指令:

MOV  AL , DS : [0010H]

DS:  为数据段前缀,用于指出地址由数据段寄存器DS提供,偏移地址0010H 必须置于方括号[]内。若设(DS)=2014H,则该存储单元的物理地址=20140H + 0010H =20150H,又设(20150H)=52H,(AL)=52H。

 MOV  AX ,DS : [2000H]

该指令的执行结果是将DS :[2000H] 单元的内容传送至AX寄存器中,其中高字节内容送至AH寄存器,低字节内容送至AL寄存器

寄存器间接寻址方式

若某个16为寄存器间接寻址的内容作为操作数的偏移地址,则该操作数的寻址方式称为存储器间接寻址方式。可用于寄存器间接寻址二的16位寄存器有SI、DI、BX、和BP,使用时必须置于方括号内。其中,使用SI、DI、BX时,段寄存器默认为DS,使用BP时,段寄存器默认为SS。

设(DS)=3010H ,(30220H)=0AH ,(30221H)=28H,则指令序列

MOV  SI , 0120H

MOV  DX , [SI]

执行后,(DX)=?

第一条指令,立即数0120H传送给SI寄存器,(SI)=0120H,

第二条指令源操作数采用了寄存器间接寻址方式,以SI寄存器的内容0120H为操作数的偏移地址,段寄存器默认为DS,所形成的物理地址为   30100H+0120H=30220H

由于目的操作数是16位寄存器DX,所以需要从地址30220H和30221H 的两个单元中读取一个字传送给DX。由题得出指令执行后(DX)=280H。

使用寄存器间接寻址方式需要注意:

  1. 、如果访问的不是默认段,必须要使用前缀来说明
  2. 、寄存器间接寻址方式只能描述操作数的地址,不能描述操作数的类型。源操作数没有立即数,没有类型属性。
  3. 两个操作数都没有明确的类型,在汇编语言指令中是不允许的,需要用PTR属性运算符指定操作数的访问类型。要注意:PTR运算符只能作用于地址表达式。

寄存器相对寻址方式

寄存器相对寻址方式下,操作数的偏移地址的产生方式为:

偏移地址=(16位寄存器)+D

指令中表现的形式是:[16位寄存器+D]或D[16位寄存器]

其中的16位寄存器只能使用:SI、DI、BX、BP;D称为位移量

当使用SI、DI、BX时段寄存器默认为DS;使用BP时,段寄存器默认为SS。

基址变址寻址方式

在16位寄存器SI、DI、BX、BP中,BX和BP也称为基址寄存器,SI和DI又称为变址寄存器(SI为源变址寄存器,DI为目标变址寄存器)。

在基址变址寻址方式下,操作数的偏移地址产生方式为:

偏移地址=(基址寄存器)+(变址寄存器)

在指令中表现的形式是:

[基址寄存器+变址寄存器]或[基址寄存器][变址寄存器]

其中基址寄存器用BX时,段寄存器默认为DS,而用BP时,段寄存器默认为SS。

篇一结束

知秋君
上一篇 2024-07-09 16:02
下一篇 2024-07-09 15:36

相关推荐