null第3章第3章第3章:汇编语言的特点第3章:汇编语言的特点汇编语言是一种以处理器指令系统为基础的低级程序
设计
领导形象设计圆作业设计ao工艺污水处理厂设计附属工程施工组织设计清扫机器人结构设计
语言,它采用助记符
表
关于同志近三年现实表现材料材料类招标技术评分表图表与交易pdf视力表打印pdf用图表说话 pdf
达指令操作码,采用标识符号表示指令操作数
利用汇编语言编写程序的主要优点是可以直接、有效地控制计算机硬件,因而容易创建代码序列短小、运行快速的可执行程序
在有些应用领域,汇编语言的作用是不容置疑和无可替代的
汇编程序设计的过程是与其他高级语言程序设计大致相同第3章:教学重点第3章:教学重点汇编语言源程序格式与开发
常量、变量和标号
汇编语言程序设计方法
顺序程序设计
分支程序设计
循环程序设计
子程序设计第3章:3.1 汇编语言源程序格式第3章:3.1 汇编语言源程序格式完整的汇编语言源程序由段组成。例如
一个汇编语言源程序可以包含若干个代码段、数据段、附加段或堆栈段,段与段之间的顺序可随意排列
需独立运行的程序必须包含一个代码段,并指示程序执行的起始点,一个程序只有一个起始点
所有的可执行性语句必须位于某一个代码段内,说明性语句可根据需要位于任一段内。
通常,程序还需要一个堆栈段。 源程序由语句序列构成第3章:汇编语言的语句格式第3章:汇编语言的语句格式⑴执行性语句——执行性语句用于表达处理器指令(也称为硬指令),汇编后对应一条指令代码。由处理器指令组成的代码序列是程序设计的主体。
标号: 硬指令助记符 操作数,操作数 ;注释
⑵说明性语句——说明性语句用于表达伪指令,指示源程序如何汇编、变量怎样定义、过程怎么设置等。
名字 伪指令助记符 参数,参数,…… ;注释例如第3章:硬指令与伪指令第3章:硬指令与伪指令硬指令(Instruction)——使CPU产生动作、并在程序执行时才处理的指令
硬指令就是第2章学习的处理器指令,与具体的处理器有关、与汇编程序无关。
伪指令(Directive)——不产生CPU动作、在程序执行前由汇编程序处理的说明性指令
伪指令与具体的处理器类型无关,但与汇编程序有关。不同版本的汇编程序支持不同的伪指令. 硬指令和伪指令采用易于记忆的符合表达,这就是助记符第3章:标号、名字与标识符第3章:标号、名字与标识符标号是反映硬指令位置(逻辑地址)和属性的标识符,后跟一个冒号分隔。 MOV AH, 01H
INT 21H ;键盘接受字符
CMP AL,‘a’
JB STOP
CMP AL,‘z’
JA STOP ;如果不是小写字母 结束程序
DEC AL
MOV DL,AL
MOV CX,3
DISP:MOV AH,02H
INT 21H
INC DL
LOOP DISP ;屏幕显示所输入小写字母的前导和后继字母
STOP:MOV AH,4CH
INT 21H ;结束程序第3章:标号、名字与标识符第3章:标号、名字与标识符
名字是反映伪指令位置(逻辑地址)和属性的标识符,后跟空格或制表符分隔,没有冒号
标识符(Identifier)一般最多由31个字母、数字及规定的特殊符号(如 _、$、?、@)组成,不能以数字开头。默认情况下,汇编程序不区别标识符中的字母大小写
一个源程序中,每个标识符的定义是唯一的,还不能是汇编语言采用的保留字。第3章:保留字第3章:保留字保留字(Reserved Word)是汇编程序已经利用的标识符(也称为关键字),主要有:
硬指令助记符——例如:MOV、ADD
伪指令助记符——例如:DB、DW
操作符——例如:OFFSET、PTR
寄存器名——例如:AX、CS
预定义符号——例如:@data 汇编语言大小写不敏感第3章:操作数和参数第3章:操作数和参数处理器指令的操作数可以是立即数、寄存器和存储单元
伪指令的参数可以是常数、变量名、表达式等,可以有多个,参数之间用逗号分隔
第3章:注释第3章:注释语句中由分号“;”开始的部分为注释内容,用以增加源程序的可读性
必要时,一个语句行也可以由分号开始作为阶段性注释
汇编程序在翻译源程序时将跳过该部分,不对它们做任何处理第3章:分隔符第3章:分隔符语句的4个组成部分要用分隔符分开
标号后用冒号,注释前用分号
操作数之间和参数之间使用逗号分隔
其他部分通常采用空格或制表符
多个空格和制表符的作用与一个相同
MASM支持续行符 “\” MOV DL,AL
MOV CX,3
DISP:MOV AH,02H
INT 21H
INC DL
LOOP DISP ;屏幕显示所输入小写字母的前导和后继字母第3章:例3.1 在屏幕上显示一段信息第3章:例3.1 在屏幕上显示一段信息 ;数据段(定义要显示的字符串)
string db ’Hello, Assembly !’,0dh,0ah,’$’
;代码段(显示字符串的程序)
mov dx,offset string
mov ah,9
int 21h Hello, Assembly !第3章:3.1.1 简化段定义格式第3章:3.1.1 简化段定义格式 .model small ;定义程序的存储模式(小型模式)
.stack ;定义堆栈段(默认是1KB空间)
.data ;定义数据段
…… ;数据定义
.code ;定义代码段
start: mov ax,data ;程序起始点
mov ds,ax ;设置DS指向用户定义的数据段 …… ;程序代码
mov ax,4c00h
int 21h ;程序结束点,返回DOS
…… ;子程序代码
end start ;汇编结束,同时指明程序起始点start第3章:第一个源程序文件hb1.asm第3章:第一个源程序文件hb1.asm;hb1.asm
.model small
.stack
.data
string db ’Hello, Assembly !’,0dh,0ah,’$’
.code
start: mov ax,data
mov ds,ax
mov dx,offset string
mov ah,9
int 21h
mov ax,4c00h
int 21h
end start第3章: 汇编语言程序的开发过程(附录B)第3章: 汇编语言程序的开发过程(附录B)开发过程1:源程序的编辑开发过程1:源程序的编辑源程序文件要以ASM为扩展名
源程序文件的形成(编辑)可以通过任何一个文本编辑器实现:
DOS中的全屏幕文本编辑器EDIT
其他程序开发工具中的编辑环境
Windows中的记事本Notepad
Edit hb1 . asm开发过程2:源程序的汇编(MASM 6.x)开发过程2:源程序的汇编(MASM 6.x)汇编是将源程序翻译成由机器代码组成的目标模块文件的过程
常用汇编程序是MASM .EXE:
MASM hb1 . asm
如果源程序中没有语法错误,MASM将自动生成一个目标模块文件(hb1.obj);否则MASM将给出相应的错误信息。这时应根据错误信息,重新编辑修改源程序后,再进行汇编开发过程2:源程序的汇编(MASM 5.x)开发过程2:源程序的汇编(MASM 5.x)MASM 5.x提供的汇编程序是MASM.EXE:
MASM hb1.asm;
如果利用分号“;”结尾命令,则汇编程序不再提示输入模块文件名、列表文件名等,直接采用默认的文件名。
默认采用源程序文件相同的主文件名,扩展名则是相应类型文件的扩展名,例如模块文件(.obj)和列表文件(.lst)等开发过程2:源程序的汇编(生成列表文件)开发过程2:源程序的汇编(生成列表文件)汇编过程中,可以通过参数选择生成列表文件(.LST)。列表文件是一种文本文件,含有源程序和目标代码,对我们学习汇编语言程序设计和发现错误很有用
汇编程序MASM.EXE可带其他参数,为了生成列表文件,各自的命令是:
MASM \l hb1 . asm;
该命令除产生模块文件hb1.obj(和可执行文件hb1.exe)外,还将生成列表文件hb1.lst开发过程3:目标模块的连接开发过程3:目标模块的连接连接程序能把一个或多个目标文件和库文件合成一个可执行程序(.EXE、.COM文件):
LINK hb1.obj;
如果没有严重错误,LINK将生成一个可执行文件(hb1.exe);否则将提示相应的错误信息。这时需要根据错误信息重新修改源程序文件后再汇编、链接,直到生成可执行文件开发过程4:可执行程序的调试开发过程4:可执行程序的调试经汇编、连接生成的可执行程序在操作系统下只要输入文件名就可以运行:
hb1
操作系统装载该文件进入主存,并开始运行
如果出现运行错误,可以从源程序开始排错,也可以利用调试程序帮助发现错误
采用DEBUG.EXE调试程序:
DEBUG hb1.exe第3章:1. 程序开始第3章:1. 程序开始为了指明程序开始执行的位置,需要使用一个标号(例题中采用了start标识符)
大多数程序需要数据段,程序的执行开始应是:
start:mov ax,data ;data表示数据段的段地址
mov ds,ax ;设置DS第3章:2. 程序终止第3章:2. 程序终止应用程序执行结束,应该将控制权交还操作系统
汇编语言程序设计中,有多种返回DOS的方法,但一般利用DOS功能调用的4CH子功能实现。
应用程序的终止代码就是:
mov ah,4ch
int 21h第3章:3. 汇编结束第3章:3. 汇编结束汇编结束表示汇编程序到此结束将源程序翻译成目标模块代码的过程
源程序的最后必须有一条END伪指令
END [标号]
可选的“标号”参数指定程序开始执行点,连接程序据此设置CS和IP值(例题中采用了start标识符) ————不要糊涂————
程序终止和汇编结束是两码事第3章:第一个源程序文件hb1.asm第3章:第一个源程序文件hb1.asm;hb1.asm
.model small
.stack
.data
string db ’Hello, Assembly !’,0dh,0ah,’$’
.code
start: mov ax,data
mov ds,ax
mov dx,offset string
mov ah,9
int 21h
mov ax,4c00h
int 21h
end start第3章:简化段定义的源程序格式第3章:简化段定义的源程序格式 .model small ;小型模式存储模式
.stack ; 1KB空间堆栈段
.data ;数据段
…… ;数据定义
.code ;代码段
start: mov ax,@data ;起始点
mov ds,ax ;设置DS
…… ;程序代码
mov ax,4c00h
int 21h ;结束点,返回DOS
…… ;子程序代码
end start ;汇编结束第3章:3.1.2 完整段定义格式第3章:3.1.2 完整段定义格式完整段定义利用SEGMENT和ENDS一对伪指令定义逻辑段
同时需要配合ASSUME伪指令指明逻辑段是代码段、堆栈段、数据段还是附加段
完整段定义的优势是可以指明逻辑段的定位、组合、类别等属性;而简化段定义只能采用系统默认的属性
完整段定义和简化段定义的实质是一致的.null data segment ;数据段
…… ;数据定义
data ends
code segment ;代码段
assume ds:data,cs:code
start: mov ax,@data ;起始点
mov ds,ax ;设置DS
…… ;程序代码
mov ax,4c00h
int 21h ;结束点,返回DOS
code ends ;程序结束
end start ;汇编结束完整段定义举例:第3章:3.1.3 可执行程序的结构第3章:3.1.3 可执行程序的结构DOS操作系统支持两种可执行程序结构
1. EXE程序
程序可以有多个代码段和多个数据段,程序长度可以超过64KB
通常生成EXE结构的可执行程序
2. COM程序
只有一个逻辑段,程序长度不超过64KB
需要满足一定条件才能生成COM结构的可执行程序(MASM 6.x需要采用TINY模式)第3章:3.2 常量、变量和标号 第3章:3.2 常量、变量和标号 汇编语言的数据可以简单分为常量和变量
常量可以作为硬指令的立即数或伪指令的参数,变量主要作为存储器操作数
汇编语言语句中的名字和标号具有逻辑地址和类型属性,主要用做地址操作数,也可以作为立即数和存储器操作数
本节将详细讨论语句中的参数和操作数、名字和标号,并引出相关的伪指令和操作符第3章:3.2.1 常量第3章:3.2.1 常量常量表示一个固定的数值,它又分成多种形式
常数
字符串
符合常量
数值表达式第3章:1. 常数第3章:1. 常数指由10、16、2和8进制形式表达的数值,各种进制的数据以后缀字母区分,默认不加后缀字母的是十进制数第3章:2. 字符串第3章:2. 字符串字符串常量是用单引号或双引号括起来的单个字符或多个字符
其数值是每个字符对应的ASCII码值
例如:
‘d’(等于64H)
‘AB’(等于4142H)
‘Hello, Assembly !’第3章:3. 符号常量第3章:3. 符号常量符号常量使用标识符表达一个数值
MASM提供等价机制,用来为常量定义符号名
符号定义伪指令有“等价EQU”和“等号=”:
符号名 EQU 数值表达式
符号名 EQU <字符串> ;MASM 5.x不支持
符号名 = 数值表达式
EQU用于数值等价时不能重复定义符号名,但“=”允许有重复赋值。例如:
X = 7 ;等效于:X qeu 7
X = X+5 ;“X EQU X+5”是错误的第3章:4. 数值表达式第3章:4. 数值表达式数值表达式一般是指由运算符连接的各种常量所构成的表达式
汇编程序在汇编过程中计算表达式,最终得到一个确定的数值,所以也是常量
表达式的数值在程序运行前的汇编阶段计算,所以组成表达式的各部分必须在汇编时就能确定
汇编语言支持多种运算符(表3.4)
我们经常使用的是加减乘除(+ - * / )
例如:
mov ax,3*4+5 ;等价于:mov ax,17第3章:3.2.2 变量 第3章:3.2.2 变量 变量实质上是指内存单元的数据,虽然内存单元地址不变,但其中存放的数据可以改变
变量需要事先定义才能使用
变量定义(Define)伪指令为变量申请固定长度为单位的存储空间,并可以同时将相应的存储单元初始化
定义后的变量可以利用变量名等方法引用其中的数据,即变量的数值第3章:1. 变量的定义 第3章:1. 变量的定义 变量定义的汇编语言格式为:
变量名 伪指令 初值表
变量名为用户自定义标识符,表示初值表首元素的逻辑地址,常称为符号地址。变量名也可以没有
初值表是用逗号分隔的参数,主要由常量、数值表达式或“?”组成。其中“?”表示未赋初值
多个存储单元如果初值相同,可以用复制操作符DUP进行定义:
重复次数 DUP(重复参数)
变量定义伪指令有DB、DW、DD等(表3.5)第3章:字节变量的定义DB(Define Byte)第3章:字节变量的定义DB(Define Byte)DB伪指令用于分配一个或多个字节单元,并可以将它们初始化为指定值
初值表中每个数据一定是字节量,存放一个8位数据:
可以是0~255的无符号数
或是-128~+127带符号数
也可以是字符串常数字节变量定义实例字节变量定义实例;数据段
X db 'a',-5
db 2 dup(100),?
Y db 'ABC'第3章:字节变量的应用第3章:字节变量的应用mov al,X
;此处X表示它的第1个数据,故AL←'a'
dec X+1
;对X为始的第2个数据减1,故成为-6
mov Y,al
;现在Y这个字符串成为 'aBC'
第3章:字变量的定义DW(Define Word)第3章:字变量的定义DW(Define Word)DW伪指令用于分配一个或多个字单元,并可以将它们初始化为指定值
初值表中每个数据是字量,一个字单元可用于存放任何16位数据:
一个段地址
一个偏移地址
两个字符
0~65535之间的无符号数
-32768~+32767之间的带符号数字变量定义实例字变量定义实例;数据段
count dw 8000h,?,'AB'
maxint equ 64h
number dw maxint
array dw maxint dup(0)第3章:双字变量的定义DD(Define Double word)第3章:双字变量的定义DD(Define Double word)DD伪指令用于分配一个或多个双字单元,并可以将它们初始化为指定值
初值表中每个数据是一个32位的双字量:
可以是有符号或无符号的32位整数
也可以用来表达16位段地址(高位字)和16位的偏移地址(低位字)的远指针
vardd DD 0,?,12345678h
farpoint DD 00400078h第3章:2. 变量的应用第3章:2. 变量的应用变量具有存储单元的逻辑地址
程序代码中
通过变量名引用其指向的首个数据
通过变量名加减位移量存取以首个数据为基地址的前后数据
例题3.2 变量的定义和应用第3章:例题3.2 变量的定义 第3章:例题3.2 变量的定义 bvar1 db 100,01100100b,64h,'d'
minint = 5
bvar2 db -1,minint,minint+5
db ?,2 dup(20h)
wvar1 dw 2010h,4*4
wvar2 dw ?
第3章:例题3.2 变量的定义(续)第3章:例题3.2 变量的定义(续)dvar dd 12347777h,87651111h,?
abc db ’a’,’b’,’c’,?
Maxint equ 0ah
string db ’ABCDEFGHIJ’
Array1 dw maxint dup(0)
array db 2dup(2,3,2 dup(4)) 第3章:3. 变量的定位第3章:3. 变量的定位汇编程序按照指令的先后顺序一个接着一个分配存储空间,按照段定义伪指令规定的边界定位属性确定每个逻辑段的起始位置(包括偏移地址)
定位伪指令ORG控制数据或代码所在的偏移地址
ORG 参数
ORG伪指令是将当前偏移地址指针指向参数表达的偏移地址。例如:
ORG 100h ;从100H处安排数据或程序
第3章:3.2.3 名字和标号的属性第3章:3.2.3 名字和标号的属性名字和标号是用户自定义的标识符。名字指向一条伪指令,标号指向一条硬指令。名字和标号一经使用便具有两类属性:
⑴ 逻辑地址——名字和标号对应存储单元的逻辑地址,含有段地址和偏移地址;
⑵ 类型——变量名的类型可以是BYTE(字节)、WORD(字)和DWORD(双字)等;标号、段名、子程序名的类型可以是NEAR(近)和FAR(远),分别表示段内或段间调用
汇编程序提供有关的操作符,以便获取这些属性值第3章:1. 地址操作符第3章:1. 地址操作符地址操作符取得名字或标号的段地址和偏移地址第3章:2. 类型操作符第3章:2. 类型操作符类型操作符对名字或标号的类型属性进行设置
类型名 PTR 名字/标号
其中可以是BYTE、WORD、DWORD(依次表示字节、字、双字)等,或者是NEAR、FAR(分别表示近、远),还可以是由结构、记录等定义的类型
对变量:
LENGTHOF操作符获知某变量名指向多少个数据项
SIZEOF操作符获知它共占用多少字节空间第3章:3.3 顺序程序设计第3章:3.3 顺序程序设计没有分支、循环等转移指令的程序,会按指令书写的前后顺利依次执行,这就是顺序程序
顺序结构是最基本的程序结构
完全采用顺序结构编写的程序并不多见第3章:第3章:顺序程序设计举例: DATA SEGMENT
STRING DB 'hello.how are you!','$'
ORG 100H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
BEGIN: MOV AX,DATA
MOV DS,AX
LEA DX,STRING
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN第3章:3.4 分支程序设计第3章:3.4 分支程序设计分支程序根据条件是真或假决定执行与否
判断的条件是各种指令,如CMP、TEST等执行后形成的状态标志
转移指令Jcc和JMP可以实现分支控制
分支结构有
单分支结构
双分支结构
多分支结构第3章:单分支结构 第3章:单分支结构 条件成立跳转,否则顺序执行分支语句体
注意选择正确的条件转移指令和转移目标地址实例:求绝对值第3章:计算AX中有符号数的绝对值第3章:计算AX中有符号数的绝对值 cmp ax,0
jge nonneg ;条件满足(AX≥0),转移
neg ax ;条件不满足,求补
nonneg: mov result,ax ;条件满足 ;不恰当的分支
cmp ax,0
jl yesneg ;条件满足(AX<0),转移
jmp nonneg
yesneg: neg ax ;条件不满足,求补
nonneg: mov result,ax ;条件满足第3章:双分支结构第3章:双分支结构条件成立跳转执行第2个分支语句体,否则顺序执行第1个分支语句体
注意第1个分支体后一定要有一个JMP指令跳到第2个分支体后实例:显示BX的最高位第3章:显示BX的最高位第3章:显示BX的最高位 shl bx,1 ;BX最高位移入CF标志
jc one ;CF=1,即最高位为1,转移
mov dl,30h
;CF=0,即最高位为0:DL←30H=‘0’
jmp two ;一定要跳过另一个分支体
one: mov dl,31h ;DL← 31H=‘1’
two: mov ah,2
int 21h ;显示可以用JNC替换JC第3章:显示BX的最高位(续)第3章:显示BX的最高位(续) shl bx,1 ;BX最高位移入CF标志
jnc one ;CF=0,即最高位为0,转移
mov dl,31h
;CF=1,即最高位为1:DL←31H=‘1’
jmp two ;一定要跳过另一个分支体
one: mov dl,30h ;DL← 30H=‘0’
two: mov ah,2
int 21h ;显示转换为单分支结构第3章:显示BX的最高位(另解)第3章:显示BX的最高位(另解) mov dl,’0’ ;DL←30H=‘0’
shl bx,1 ;BX最高位移入CF标志
jnc two ;CF=0,即最高位为0,转移
mov dl,’1’
;CF=1,即最高位为1:DL←31H=‘1’
two: mov ah,2
int 21h ;显示 编写分支程序,需留心分支的开始和结束第3章:显示BX的最高位(无分支)第3章:显示BX的最高位(无分支) mov dl,0
shl bx,1 ;BX最高位移入CF标志
adc dl,30h
;CF=0,DL←0+30h+0=30H=‘0’
;CF=1,DL←0+30h+1=31H=‘1’
two: mov ah,2
int 21h ;显示第3章:例题3.5 显示压缩BCD码第3章:例题3.5 显示压缩BCD码 ;数据段
BCD db 04h
;代码段
mov dl,BCD
test dl,0ffh ;如果BCD码为0,显示0
jz zero
test dl,0f0h ;如果BCD码高位为0,不显示0
jz one mov cl,4 ;处理高位
shr dl,cl
or dl,30h ;转换为ASCII码
mov ah,2 ;显示高位
int 21h
mov dl,BCD
and dl,0fh
one: or dl,30h ;处理低位
jmp two
zero: mov dl,’0’
two: mov ah,2
int 21h第3章:大小写字母转换第3章:大小写字母转换 ;如果DL是一个小写字母,则转换为大写
cmp dl,‘a’ ;小于小写字母a,不需要处理
jb disp
cmp dl,‘z’ ;大于小写字母z,也不需要处理
ja disp
sub dl,20h ;是小写字母,则转换为大写
disp: ……转换原理第3章:多分支结构第3章:多分支结构多分支结构是多个条件对应各自的分支语句体,哪个条件成立就转入相应分支体执行第3章:多分支结构第3章:多分支结构编程实现对键盘输入的小写字母用大写字母显示出来。
CODE SEGMENT
ASSUME CS:CODE
BEGIN:MOV AH,01H
INT 21H
CMP AL,‘a’
JB STOP
CMP AL,‘z’
JA STOP
SUB AL,20H
MOV DL,AL
MOV AH,02H
INT 21H
STOP:MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN 第3章:3.5 循环程序设计第3章:3.5 循环程序设计循环程序结构是满足一定条件的情况下,重复执行某段程序
循环结构的程序通常有3个部分:
循环初始部分——为开始循环准备必要的条件,如循环次数、循环体需要的数值等
循环体部分——指重复执行的程序部分,其中包括对循环条件等的修改程序段
循环控制部分——判断循环条件是否成立,决定是否继续循环第3章:循环控制第3章:循环控制循环结构程序的设计关键是循环控制部分
循环控制可以在进入循环之前进行,也可以在循环体后进行,于是形成两种结构:
“先判断、后循环”结构
“先循环、后判断”结构
循环结束的控制可以用循环次数,还可以用特定条件等,于是又有:
计数控制循环
条件控制循环图示第3章:先循环后判断的循环结构第3章:先循环后判断的循环结构第3章:3.5.1 计数控制循环 第3章:3.5.1 计数控制循环 计数控制循环利用循环次数作为控制条件
易于采用循环指令LOOP实现
初始化:将循环次数或最大循环次数置入CX
循环体
循环控制:用LOOP指令对CX减1、并判断是否为0第3章: 3.5.1 计数控制循环 第3章: 3.5.1 计数控制循环 CODE SEGMENT
ASSUME CS:CODE
BEGIN:MOV AH,01H
INT 21H
CMP AL,‘a’
JB STOP
CMP AL,‘z’
JA STOP
DEC AL
MOV DL,AL
MOV CX,3
DISP: MOV AH,02H
INT 21H
INC DL
LOOP DISP
STOP:MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN 编程实现从键盘接收一个小写字母,然后找出它的前导和后继字符,并按顺序输出这三个字符。第3章:3.5.2 条件控制循环第3章:3.5.2 条件控制循环条件控制循环需要利用特定条件判断循环是否结束
条件控制循环用条件转移指令判断循环条件
转移指令可以指定目的标号来改变程序的运行顺序,如果目的标号指向一个重复执行的语句体的开始或结束,便构成了循环控制结构第3章:显示以0结尾的字符串第3章:显示以0结尾的字符串 ;数据段
string db 'Let us have a try !',0
;代码段
mov bx,offset string
again: mov dl,[bx]
cmp dl,0
jz done ;为0结束
mov ah,2 ;不为0,显示
int 21h
inc bx ;指向下一个字符
jmp again
done: ……条件控制循环
先判断后循环第3章:3.5.3 串操作类指令 第3章:3.5.3 串操作类指令 8088的串操作类指令能对内存中一个连续区域的数据(如数组、字符串等)进行传送、比较等操作,指令有:
传送数据串:MOVS,STOS,LODS
检测数据串:CMPS,SCAS
重复前缀:REP,REPZ,REPNZ
串操作指令采用了特殊的寻址方式
利用循环程序也可以实现串操作指令的功能第3章:3.6 子程序设计 第3章:3.6 子程序设计 把功能相对独立的程序段单独编写和调试,作为一个相对独立的模块供程序使用,就形成子程序
子程序可以实现源程序的模块化,可简化源程序结构,可以提高编程效率
主程序(调用程序)需要利用CALL指令调用子程序(被调用程序)
子程序需要利用RET指令返回主程序第3章:3.6.1 过程定义和子程序编写第3章:3.6.1 过程定义和子程序编写汇编语言中,子程序要用一对过程伪指令PROC和ENDP声明,格式如下:
过程名 PROC [NEAR|FAR]
…… ;过程体
过程名 ENDP
可选的参数指定过程的调用属性。没有指定过程属性,则采用默认属性
NEAR属性(段内近调用)的过程只能被相同代码段的其他程序调用
FAR属性(段间远调用)的过程可以被相同或不同代码段的程序调用第3章:子程序编写注意事项第3章:子程序编写注意事项⑴子程序要利用过程定义伪指令声明
⑵子程序最后利用RET指令返回主程序,主程序执行CALL指令调用子程序
⑶子程序中对堆栈的压入和弹出操作要成对使用,保持堆栈的平衡
⑷子程序开始应该保护使用到的寄存器内容,子程序返回前相应进行恢复
⑸子程序应安排在代码段的主程序之外,最好放在主程序执行终止后的位置(返回DOS后、汇编结束END伪指令前),也可以放在主程序开始执行之前的位置第3章:例3.15 用显示器功能调用输出一个字符的子程序第3章:例3.15 用显示器功能调用输出一个字符的子程序 ;主程序
mov al,‘?’ ;主程序提供显示字符
call dpchar ;调用子程序
;子程序:显示AL中的字符
dpchar proc ;过程定义,过程名为dpchar
push ax ;顺序入栈,保护寄存器
push bx
mov bx,0
mov ah,0eh ;显示器0EH号输出一个字符功能
int 10h
pop bx ;逆序出栈,恢复寄存器
pop ax
ret ;子程序返回
dpchar endp ;过程结束第3章:例3.15源程序第3章:例3.15源程序;wjl315.asm
.model small
.stack
.code
start: mov ax,@data
mov ds,ax
mov al,‘?’ ;主程序提供显示字符
call dpchar ;调用子程序
mov ax,4c00h
int 21h主程序部分本程序不需要数据段第3章:例3.15源程序(续)第3章:例3.15源程序(续)dpchar proc ;过程定义,过程名为dpchar
push ax ;顺序入栈,保护寄存器
push bx
mov bx,0
mov ah,0eh ;显示器0EH号输出一个字符功能
int 10h
pop bx ;逆序出栈,恢复寄存器
pop ax
ret ;子程序返回
dpchar endp ;过程结束
end start子程序安排在主程序执行终止后的位置第3章:子程序编写注意事项(续)第3章:子程序编写注意事项(续)⑹子程序允许嵌套和递归
⑺子程序可以与主程序共用一个数据段,也可以使用不同的数据段(注意修改DS),还可以在子程序最后设置数据区(利用CS寻址)
⑻子程序的编写可以很灵活,例如具有多个出口(多个RET指令)和入口,但一定要保证堆栈操作的正确性
⑼处理好子程序与主程序间的参数传递问题
⑽提供必要的子程序说明信息第3章:3.7 宏(Macro)汇编第3章:3.7 宏(Macro)汇编宏是具有宏名的一段汇编语句序列
宏需要先定义,然后在程序中进行宏调用
由于形式上类似其他指令,所以常称其为宏指令
宏指令实际上是一段代码序列的缩写;在汇编时,汇编程序用对应的代码序列替代宏指令
因为是在汇编过程中实现的宏展开,所以常称为宏汇编第3章:1. 宏定义 第3章:1. 宏定义 宏定义由一对宏汇编伪指令MACRO和ENDM来完成,格式如下:
宏名 MACRO [形参表]
…… ;宏定义体
ENDM
其中宏名是符合语法的标识符,同一源程序中该名字定义唯一。宏定义体中不仅可以是硬指令序列,还可以是伪指令语句序列
可选的形参表给出了宏定义中用到的形式参数,每个形式参数之间用逗号分隔第3章:2. 宏调用第3章:2. 宏调用宏定义之后就可以使用它,即宏调用:
宏名 [实参表]
宏调用的格式同一般指令一样:在使用宏指令的位置写下宏名,后跟实体参数;如果有多个参数,应按形参顺序填入实参,也用逗号分隔
在汇编时,宏指令被汇编程序用对应的代码序列替代,这就是宏展开
宏展开的具体过程是:当汇编程序扫描源程序遇到已有定义的宏调用时,即用相应的宏定义体完全替代源程序的宏指令,同时用位置匹配的实参对形参进行取代第3章:宏的实例1第3章:宏的实例1dispchar macro char ;;宏定义
mov ah,2 ;;宏定义体
mov dl,char
int 21h
endm
…
…
dispchar ‘?’ ;宏调用(宏指令)
…
…
1 mov ah,2 ;宏展开
1 mov dl,’?’
1 int 21h第3章:宏的实例2第3章:宏的实例2dispmsg macro message ;;宏定义
mov ah,9 ;;宏定义体
lea dx,message
int 21h
endm
…
dispmsg string ;宏调用(宏指令)
…
1 mov ah,9 ;宏展开
1 lea dx,string
1 int 21h第3章:宏与子程序的比较第3章:宏与子程序的比较仅是源程序级的简化:宏调用在汇编时进行程序语句的展开,不需要返回;不减小目标程序,执行速度没有改变
通过形参、实参结合实现参数传递,简捷直观、灵活多变比较还是目标程序级的简化:子程序调用在执行时由CALL指令转向、RET指令返回;形成的目标代码较短,执行速度减慢
需要利用寄存器、存储单元或堆栈等传递参数宏子程序第3章:宏与子程序的比较结论第3章:宏与子程序的比较结论宏与子程序具有各自的特点,程序员应该根据具体问题选择使用那种方法
通常,当程序段较短或
要求
对教师党员的评价套管和固井爆破片与爆破装置仓库管理基本要求三甲医院都需要复审吗
较快执行时,应选用宏;当程序段较长或为减小目标代码时,要选用子程序比较
结论宏子程序第3章:教学要求第3章:教学要求掌握简化段定义源程序格式
掌握常量表达、变量定义及应用、变量和标号的属性及操作符
掌握汇编语言源程序的编辑、汇编、连接和调试的开发方法
掌握基本伪指令和操作符:
EQU/=;+-*/;DB/DW/DD、?/DUP;ORG/$、OFFSET/SEG/PTR;/CODE/END;PROC/ENDP第3章:教学要求(续)第3章:教学要求(续)掌握基本的顺序、分支、循环和子程序设计方法
熟悉常见程序设计问题:
多精度运算,查表(查代码、特定值等)、ASCII和BCD代码转换;数据范围判断(0~9、A~Z、a~z)、字母大小写转换;字符串传送、比较等操作、求最小最大值、数据求和、统计字符个数
作业:表3.1 存储模式表3.1 存储模式XLAT指令的功能XLAT指令的功能大小写字母的比较和转换大小写字母的比较和转换结论1:大小写字母的ASCII码值相差20H
结论2:大小写字母的ASCII码值仅D5位不同方法1(加减指令): “ADD DL,20H” “SUB DL,20H”
方法2(逻辑指令): “OR DL,20H” “AND DL,0DFH”大小写互换(异或指令): “XOR DL,20H”dpchar子程序的参数传递(例3.15)dpchar子程序的参数传递(例3.15) ;主程序
mov al,‘?’ ;主程序提供显示字符
call dpchar
;子程序:显示AL中的字符
dpchar proc
push ax
push bx
mov bx,0
mov ah,0eh
int 10h
pop bx
pop ax
ret
dpchar endp入口参数:寄存器AL,传数值
出口参数:无dpstri子程序的传递参数(例3.16)dpstri子程序的传递参数(例3.16);子程序dpstri:显示DS:SI指向的字符串
dpstri proc
push ax
dps1: mov al,[si]
inc si
cmp al,0
jz dps2
call dpchar
jmp dps1
dps2: pop ax
ret
dpstri endp入口参数:寄存器DS:SI,传地址
出口参数:无HTOASC子程序的参数传递HTOASC子程序的参数传递;子程序HTOASC:十六进制数转换为ASCII码
HTOASC proc
push bx
mov bx,offset ASCII
and al,0fh
xlat CS:ASCII
pop bx
ret
ASCII db 30h,31h,32h,33h,34h,35h,36h,37h,38h,39h
db 41h,42h,43h,44h,45h,46h
HTOASC endp入口参数:寄存器AL,传数值
出口参数:寄存器AL,传数值null DATA SEGMENT
STRING DB 'hello.how are you!','$'
ORG 100H
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
BEGIN: MOV AX,DATA
MOV DS,AX
LEA DX,STRING
MOV AH,09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
END BEGIN