您好,欢迎来电子发烧友网! ,新用户?[免费注册]

当前位置:电子发烧友网 > 图书频道 > 电子 > 《微计算机原理》 > 第4章 汇编语言程序设计

第1节 编语言源程序的格式

 


  程序设计首先遇到的问题似是使用何种语言与机器对话,其次再把人们为解决某问题的解题步骤(即程序)输入机器内,最后启动机器执行,获得结果。
  用机器语言(即机器码)直接编程序(目标程序),不要翻译,计算机可直接执行。这样程序最直接,执行速度最快,但编程序难,修改难。汇编语言是用指令的助记符、符号地址、标号等书写的语言,用这种语言编写的程序称为汇编语言程序,源程序不能由机器直接执行,要翻译成机器语言组成的目标程序,然后执行目标程序。
  把汇编语言源程序翻译成机器语言目标程序的过程叫做汇编,完成汇编任务的程序叫做汇编程序。汇编程序除了能把缘程序翻译成目标程序外,还能对源程序进行语法检查,并指出错误(如非法格式,未定义符号等)。能按用户要求自动分配存储区(程序区、数据区、堆栈区),自动把各种进制数转换成二进制数,以及计算表达式值等。
  用8086汇编语言编写的源程序要由Intel公司提供的ASM86汇编程序翻译成目标程序,然后机器才能执行。所以,源程序的书写格式和要求,应符合ASM86的语法规定。

   
掌握汇编语言程序设计的格式,语句行的构成,熟练掌握几个常用的伪指令,能区分BIOS中断和DOS中断。能自己独立编写汇编程序。 

  §1 编语言源程序的格式

  §2 语句行的构成

  §3 伪指令(指示性语句)

  §4 BIOS中断和DOS中断

  §5 8086汇编语言程序设计

  §6 实数运算

  §7 汇编程序(MASM)

  §8 连接程序(LINK)


   汇编语言程序设计的格式,各种伪指令(指示性语句)汇编语言程序的几种结构。

   1、对初学者来说,按照顺序学习,并且掌握好该节的知识点,再接着下节的学习,学后要及时巩固。
   2、编写一些自己的小程序来掌握本章的知识。


   格式    语句行    伪指令   汇编    连接

    1、《微型计算机技术及应用》,戴梅萼等编著,第二版,清华大学出版社
    2、《微型计算机原理》,季维法等编著,第一版,电子科技大学出版社
    3、《微型计算机原理—常见题型解析及模拟题》,武自芳主编,西北工业大学出版社
    4、《80X86/80X87汇编语言程序设计》,洪志全等编著,电子科技大学出版社

 

  §4.1 编语言源程序的格式

  用助记符编写的程序,称为"汇编语言源程序",汇编语言源程序(文件扩展名ASM)需要翻译为机器指令表示的目标程序(文件扩展名OBJ),这一翻译过程称为"汇编",一般使用称为"汇编程序"的程序来进行翻译。典型的汇编程序如Microsoft MASM 5.0。 目标 程序不能被操作系统装入和执行,为了让操作系统装入和执行,必须把目标程序连接为操作系统下的可执行文件,如DOS、Windows下 的可执行文件扩展名为EXE或COM。连接过程一般使用连接程序Link.EXE来完成(如图4-1所示)。

  汇编语言指令与机器指令间有一一对应关系,可以充分发挥CPU的性能。

  另外,使用高级语言编写的源程序,必须通过"编译"、"连接"形成可执行文件(如图4-2所示)。

  为了用汇编程序(如MASM)把源程序翻译为机器码,用连接程序(如LINK)构造可执行文件(EXE或COM),源程序的编写必须

  满足一定的语法格式。

  汇编语言源程序的一种典型格式如下。

  该程序在屏幕上显示一字符串"This is a string"后回车换行。

  DATA SEGMENT PARA PUBLIC 'DATA'

  Message DB 'Hello,World!', 0DH, 0AH

  DB '$'

  DATA ENDS

  STACK SEGMENT STACK 'STACK'

  DW 100H DUP (0)

  STACK ENDS

  CODE SEGMENT PARA PUBLIC 'CODE'

  ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK

  ORG 100H

  MAIN PROC FAR START:MOV AX,DATA

  MOV DS,AX

  MOV ES,AX

  MOV DX,OFFSET Message

  MOV AH,09H

  INT 21H

  EXIT:MOV AX,4C00H

  INT 21H

  MAIN ENDP

  CODE ENDS

  END START

  编写该程序的过程如下:

  (1) 用任何ASCII码文本编辑程序,如QE.EXE,PE.EXE,WPS,EDIT等,录入该程序 。

  (2) 把录入内容存为一个文件,如TEST.ASM。(源程序文件)

  (3) 用汇编程序MASM.EXE把TEST.ASM翻译为目标文件TEST.OBJ。其操作如下:(↙表示按回车键)

  H:\961234>masm↙

  Microsoft (R) Macro Assembler Version 5.00

  Copyright (C) Microsoft Corp 1981-1985, 1987. All rights reserved.

  Source filename [.ASM]: test↙ ;输入源程序文件名(扩展名可省略)

  Object filename [test.OBJ]: ↙;缺省目标文件名为TEST.OBJ

  Source listing [NUL.LST]: ↙

  Cross-reference [NUL.CRF]: ↙

  51470 + 435154 Bytes symbol space free

  0 Warning Errors ;0个警告错误

  0 Severe Errors ;0个严重错误

  如果汇编程序能够翻译源程序,报告"0个警告错误"、"0个严重错误",同时,生成目标文件TEST.OBJ。

  (4) 用连接程序LINK.EXE把目标文件TEST.OBJ连接为可执行文件TEST.EXE。其过程为:

  H:961234>link↙

  Microsoft (R) Overlay Linker Version 3.60 Copyright (C) Microsoft Corp 1983-1987. All rights reserved.

  Object Modules [.OBJ]: test↙ 输入目标文件名(扩展名可省略)

  Run File [TEST.EXE]: ↙ 缺省可执行文件名为TEST.EXE

  List File [NUL.MAP]: ↙

  Libraries [.LIB]: ↙

  (5) 运行可执行文件TEST.EXE。

  H:961234>test↙

  屏幕上将显示一串字符 Hello,World! 。

  观察上述源程序,可以发现其结构特点:

  1、源程序是分段的,由若干段组成

  段的结构为:

  段名 SEGMENT 段属性

  语句行

  ┇

  语句行

  段名 ENDS

  例如

  程序中的段,按性质,可分为代码段、数据段、堆栈段。(附加段也是数据段)。段的数量原则上不受限制,段的顺序原则上可以任意,但一般把堆栈段和数据段放在代码段的前面。

  2、 语句行有两种类型

  (1) 指令性语句

  标号:助记符 操作数 ; 注释

  如,EXIT: MOV AX,4C00H

  汇编程序把指令性语句翻译为机器码,运行可执行文件(TEST.EXE)时,CPU将执行这些机器码。

  (2) 伪指令语句(指示性语句)

  名字 定义符 操作数 ;注释

  如:DATA SEGMENT PARA PUBLIC 'DATA'

  Message DB 'Hello,World!', 0DH, 0AH均是伪指令语句。

  伪指令语句用于告诉汇编程序(MASM)和连接程序(LINK),如何翻译源程序和连接目标程序。伪指令语句不产

  生机器码。

  两种语句行中,有些部分不可缺少,有些部分可以省略。 其中,分号后面的注释,仅供程序员阅读或交流,汇编

  程序(MASM)和连接程序(LINK)均不对注释作任何处理。

  3、 整个源程序以END语句结束

  END START

  END是一个伪指令,告诉汇编程序(MASM),需要翻译的语句到此为止,停止翻译。

  END后的START,是一个语句的标号,如START: MOV AX,DATA

  用于通知连接程序(LINK),TEST.EXE程序的第一条被执行指令的地址(称为"启动地址")。

  注:END决不是告诉TEST.EXE程序结束运行!。TEST.EXE程序由以下两条指令结束运行:

  MOV AX,4C00H

  INT 21H

  §4.2 语句行的构成

  本节概述

  语句行是由标记及分隔符按照一定的规则组织起来,标记是ASM 86源程序的最小的有意义的单位。

  教学目标

  1、标记的构成

  2、标示符的构成

  3、掌握关键字

  学习内容

  标记(Tokens)

  符号(Symbols)

  表达式(Expressions)

  语句(Statements)

  重点难点

  掌握标记和标示符的组成原则,关键字的使用。

  学习方法

  掌握标记和标示符的组成原则,关键字的使用。

  关键字

  标记  符号  保留字  操作数  运算符

  参考资料

  1、《微型计算机技术及应用》,戴梅萼等编著,第二版,清华大学出版社

  2、《微型计算机原理》,季维法等编著,第一版,电子科技大学出版社

  3、《微型计算机原理—常见题型解析及模拟题》,武自芳主编,西北工业大学出版社

  4、《80X86/80X87汇编语言程序设计》,洪志全等编著,电子科技大学出版社

  §4.2.1标记

  标记包含ASM 86的字符集、标识符、保留字、界符、常数、注释。

  1、ASM 86的字符集

  ASM 86中所使用的字符集仅是ASCII和EBCDIC字符集的子集。它由以下几部分呢组成:

  字母:包含有26个大写英文字母:A,B,C,D,…,X,Y,Z;26个小写英文字母:a,b,c,d,…,x,y,z。

  数字:阿拉伯数字10个:0,1,2,3,4,5,6,7,8,9。

  可打印的字符有:+,-,*,/,=,(,),[,],<,>,;,.,',,,-,:,?,@,$,,&

  非打印字符有:空格,制表符,回车和换行。

  若在源程序中包含任何不属于上列字符集中的字符,汇编程序就把它们作为空格处理。虽然字符&是字符集中的一个字符,但紧跟在回车换行之后的字符&是代表一个连续行,所以,汇编程序也把它当作空格来处理,当然,在字符串或注释中则除外。

  2、标识符(Identifiers)

  标识符是程序员自己建立起来的、有特定意义的字符序列,对汇编程序具有特定的符号意义。

  标识符用于标识地址值。标识符以字母开头、由数字、下划线构成,不超过31个字符。

  段名:标识段的起始地址。

  子程序名:标识子程序的起始地址。

  标号:标识指令的地址。

  变量:标识数据的地址。

  3、 保留字(Reserved Words)

  已有固定含义的符号。不能作为标识符。

  ASM 86中的保留子

  4、 界符(Delimiters)

  界符是一些特殊的字符,利用它们可以表明某个标记的结束,它本身也有一定的意义,这一点与分隔符不同,因为分隔符只表示标记的结束。若有了界符那就不一定需要分隔符。但是适当地使用一些分隔符,可使程序更容易理解。ASM 86中的界符有:

  , ; : . + - * / = ? - @ & $ ' ' < > ( ) [ ]

  主要是起分隔作用。

  如,指令"MOV AX,100"中的逗号,起分隔操作数的作用。

  5、 常数(Constants)

  在汇编时,已经确定的值,且在程序运行期间不会变化。

  (1) 数值常量

  数字常量又可用二进制、八进制、十进制、十六进制数来表示。二进制常量是以字母B结尾的由一串0和1组成的序列。二进制常量,00001111B等。

  八进制常量是以字母Q(或字母O)结尾的若干数字(0,1,2,3,4,5,6,7)组成的序列。如255Q,403O等。

  十进制常量是以字母D(也可略写)结尾的若干个数字(0,1,2,3,4,5,6,7,8,9)组成的序列。如123,或123D 。

  十六进制常量是以字母H结尾的若干字母或数字(0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F)组成的序列。如12FFH,0FFFFH。

  (2) 字符串常量

  字符串常量是由包含在单引号内的1至2个ASCII字符构成的。汇编程序把它们表示成一个字节序列,一个字节对应一个字符,把引号中的字符翻译成ASCII码。例如A等价于41H。在可以使用单字节立即数的地方,就可以使用单个字符组成的字符串常量;在可以使用字立即数的地方就可以使用两个字符组成的字符串常量。只有字初始化存储器时,才可以使用多于两个字符的字符串常量。

  如,'A', 'Hello'

  6、 注释(Comments)

  语句行中,分号后面的部分为注释,注释仅供程序员阅读或交流,汇编程序(MASM)和连接程序(LINK)均不对注释作任何处理。

  §4.2.2 符号(Symbols)

  在汇编语言源程序中,为了使程序更具有普遍性,也便于程序的修改,用户常用符号来代替存储单元、数据、表达式等。符号是一种标识符,它要符合标识符的组成规定。在实际使用中的符号可以分成五类:寄存器、变量、标号、数、其他符号。每个符号都具有一定的属性,以允许汇编程序使用它来代表所需的信息。

  1、 寄存器(Registers)

  寄存器代表一个操作数,寄存器的类型是隐含在寄存器名中。寄存器的类型可以确定寄存器是一个字节寄存器还是字寄存器(两个字节)。

  2、 变量(Variable)

  存放在存储单元的操作数是变量,因为它们的值是可以改变的。在程序中出现的存储单元地址的符号,即是他们的名字,通常是用存储器初始化命令定义的。

  变量是表示存储单元地址的符号,其值可以改变。 变量有三个属性:

  (1) 段地址值(Segment)。

  (2) 地址偏移量值(Offset)。

  (3) 类型(Type):字节(Byte)、字(Word)、双字(Double Word) 。

  3、标号(Label)

  标号是某条指令所存放单元的符号地址,它是转移指令或调用指令的目的操作数。对于汇编程序来说,标号与变量是类似的,都是存储单元的符号地址。只是标号对应的存储单元中存放的是指令,而变量所对应的存储单元中存放的是数据 。所以,标号也有三种属性:段值、偏移量、类型。

  标号的类型与变量不同,它的类型是NEAR或是FAR。NEAR类型是指转移到此标号所指的语句,或调用子程序或过程时,只需改变IP值,而不改变CS值。即转移指令或调用指令与此标号所指的语句或过程在同一程序段内。FAR类型是指转移到标号所指的语句或调用的子程序或过程,不仅要改变IP值,而且要改变CS值,即段交叉转移或调用。若没有对标号进行类型说明,就默认为NEAR类型。

  4、数

  在汇编语言源程序中的常数也常用符号的形式来表示,这样就更具有通用性和便于修改。

  5、其他符号

  除了上述符号以外,汇编语言中还常出现一些其他符号,常作为伪指令名字。例如:

  SEGMENT与ENDS(定义一个段)

  CODEMACRO与ENDM(定义一个宏指令)。

  §4.2.3 表达式(Expressions)

  汇编语言中的表达式由操作数和运算符组成,在汇编时,由汇编程序(MASM)计算,获得一个值。

  1、操作数

  可以是寄存器名、数字常数、字符串常量或是一个存储器操作数。

  (1)常量操作数

  数字操作数可以是常量或表示常量的标识符(符号)。常量操作数的允许范围是从-65535~+65535。

  常数操作数的值可以是负的,但常量绝对不能是负的。常量前加上负号(一个运算符),以表示一个负的操作数,不能把负号作为常量的一部分,负号本身是一个运算符。

  (2)存储器操作数

  存储器操作数通常是标识符,具体说。可分为标号和变量两种。标号是可执行的指令语句的符号地址,通常作为转移指令或调用的目标操作数。变量通常是指存放在一些存储单元的值,这些值在程序运行的过程中是可以改变的。作为存储器操作数的标号和变量都有三种属性:段值、偏移量、类型。

  2、运算符有

  (1)算术运算符

  算术运算符有:+(加)、-(减)、*(乘)、/(除)、MOD(除法取余数)。算术运算符总是应用与数字操作数,结果也是数字的。当算术运算符应用在存储器地址运算,就要注意这种运算是否有意义。例如在同一程序段内的两个存储器地址差(相减),是表示两个存储单元之间的数字距离,即它们地址偏移量之差,这是有意义的。对存储器地址操作数的另一个唯一有意义的算术运算是加或减一个数字量。但是两个存储器地址相乘积是没有意义的。

  (2)逻辑运算符

  逻辑运算符有AND、OR、NOT、XOR。逻辑运算的操作数只能是数字的,而且结果也是数字的。存储器地址操作数不能进行逻辑运算。

  这里要指出。AND。OR,NOT,XOR也是8086指令的助记符。但是,作为ASM 86的运算符是在程序编译时计算的,而作为指令助记符,,则在程序执行时计算的。

  (3)关系运算符

  关系运算符有EQ(等于)、NE(不等于)、LT(小于)、 GT(大于)、LE(小于或等于)、GE(大于或等于)。

  关系运算符的两个操作数,或者都是数字的,或者同是一段的存储器地址。结果始终是一个数字值。若关系是假,则结果为0;若关系是真,则结果是0FFFFH。

  (4)分析运算符

  分析运算符有SEG、OFFSET、TYPE、LENGTH、SIZE。分析运算符可以把存储器操作数分解为它的组成部分。

  (5)合成运算符

  合成运算符PTR、THIS。合成运算符可以由已存在的存储器操作数生成一个段值与偏移量相同,而类型不同的新的存储器操作数。

  §4.2.4 语句(Statements)

  一个汇编语言的源程序是由一条条语句组成的,而这些语句可分成两类:指令性语句和指示性语句。指令性语句,汇编程序把它们翻译成机器代码,这些代码命令8086执行某些操作。指示性语句(伪指令),汇编程序不能把它们翻译成机器代码,而是指示、引导汇编程序在汇编时做一些操作。

  1、指令性语句

  标号:助记符 操作数 ; 注释

  2、伪指令语句(指示性语句)

  名字 定义符 操作数 ;注释

  在指令性语句的标号后面跟有冒号(:),而在指示性语句的名字后面没有冒号,这就是这两种语句在格式上的主要区别。

  一个标号与一条指令的地址符号名相联系,标号可以作为JMP指令和CALL指令的目标操作数。指示性语句中的名字与指令的地址毫无关系,绝不能转向它。在指令性语句中的标号是任选的;而在指示性语句中的名字,可能是强制的、任选的或禁止的,这取决于实际命令。语句中的注释是为了便于程序阅读,它们总是可以任选的,为了便于识别,必须在注释之前加上分号(;)。

  所谓指令性语句,实际上就是在前面介绍过的8086指令。