第 五 章 高 级 汇 编 语 言 程 序 设 计
1封面
☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆☆
第 五 章 高 级 汇 编 语 言 程 序 设 计
2第五章高级汇编语言程序设计第五章 高级汇编语言程序设计
5.1 高级语言特性
5.2 宏结构程序设计
5.3 模块化程序设计
5.4 输入输出程序设计本章重点及习题分析第 五 章 高 级 汇 编 语 言 程 序 设 计
35.1 高级语言特性
5.1 高级语言特性通过引入一些伪指令,使汇编语言程序设计具有高级语言程序设计的特性,即可以采用类似高级语言的形式设计分支、循环和子程序结构,大大减轻了使用汇编语言编程的工作量。
5.1.1 条件控制伪指令
5.1.2 循环控制伪指令
5.1.3 过程声明和调用伪指令返回第五章第 五 章 高 级 汇 编 语 言 程 序 设 计
45.1.1 条件控制伪指令
5.1.1 条件控制伪指令
.IF/.ELSEIF/.ELSE/.ENDIF:类似高级语言的
IF/THIN,ELSE和 ENDIF的相应功能。汇编时展开,自动生成相应的比较和条件转移指令,实现分支结构。
.IF 条件表达式 ; 条件为真,执行分支体 1
分支体 1
[.ELSEIF 条件表达式 ; 前面 IF[及前面 ELSEIF]为假,
分支体 2 ] ; 当前条件为真,执行分支体 2
[.ELSE ; 前面 IF[及前面 ELSEIF]为假,
分支体 3 ] ; 执行分支体 3
.ENDIF ; 分支结束第 五 章 高 级 汇 编 语 言 程 序 设 计
5条件控制伪指令不考虑多层嵌套,有 4种基本格式
.IF 条件表达式 ; 条件表达式为真,执行分支体 ; 分支体,否则执行后面
.ENDIF ; 语句
.IF 条件表达式分支体 1
.ELSE
分支体 2
.ENDIF ; 分支体 1,2必做其一
1.
2.
第 五 章 高 级 汇 编 语 言 程 序 设 计
6条件控制伪指令
.IF 条件表达式分支体 1
.ELSEIF 条件表达式分支体 2 ; 分支体 1和分支体 2可能
.ENDIF ; 都不做
.IF 条件表达式 ; 条件为真,执行分支体 1
分支体 1
.ELSEIF 条件表达式; 前面 IF[及前面 ELSEIF],
分支体 2 ; 为假当前条件为真,执行分支体 2
.ELSE ; 前面 IF[及前面 ELSEIF]为假,
分支体 3 ; 执行分支体 3
.ENDIF ; 分支结束
3.
4.
第 五 章 高 级 汇 编 语 言 程 序 设 计
7条件表达式的三个问题三个问题:
1.关于条件表达式中的操作符
2.条件表达式举例
3.条件表达式中的有符号数和无符号数的规定第 五 章 高 级 汇 编 语 言 程 序 设 计
81.关于条件表达式中的操作符
1.关于条件表达式中的操作符
1)表 5.1列出的操作符用于伪指令的条件表达式,
第三章介绍的操作符用于数值表达式和地址表达式
(构成指令的操作数),两类操作符不可混淆。例如表示相等,条件表达式用,==”,数值表达式用,EQ”;
表示逻辑与,条件表达式用,&&”,数值表达式用 AND。
2)操作符可分为:比较、逻辑运算和测试三类,
其中测试又可分为:标志测试、位测试、寄存器测试、
存储单元测试( reg\mem)。
3)操作符中,单目操作符为!、标志测试、寄存器测试和存储单元测试,其他都是双目操作符。
4)操作符的优先级可用圆括号规定。
第 五 章 高 级 汇 编 语 言 程 序 设 计
92.条件表达式举例 /1
2.条件表达式举例
reg ;寄存器不为 0,条件为真;为 0,条件为假
.if al
dec al
.endif
mem ;存储器不为 0,条件为真;为 0,条件为假
.if byte ptr[bx]
dec al
.endif
carry? / overflow? …
位测试操作符使用格式:
数值表达式 & 位数如,AL & 5”,测试 AL寄存器的 D5。
第 五 章 高 级 汇 编 语 言 程 序 设 计
10/2
reg OP reg ; OP为表 5.1中任意双目操作符
ax==bx / al>=bl / al && bl
reg OP mem
reg OP 立即数
mem OP 立即数
单目操作符 ‘ ! ’,可以放在前述任意表达式前面,测试相反条件
! reg ;寄存器不为 0,条件为假;为 0,条件为真注释,1)条件控制伪指令不支持数值表达式,如
.if (x+1)<=5,,+”并不是有效的操作符。
2)前述基本表达式可用,&&”,,||”连接构成复杂表达式,如 (ax==bx)&&(cx>=dx)。
第 五 章 高 级 汇 编 语 言 程 序 设 计
113.条件表达式中的符号数 /1
3.条件表达式中比较的两个数据可能是无符号数,
也可能是有符号数,可分成以下情况:
数据为变量:用 DB,DW,DD等定义的变量一律作为无符号数,若需要进行有符号数比较,必须使用
SBYTE,SWORD,SDWORD定义。
数据为寄存器或存储单元:默认为无符号数,若需要进行有符号数比较,必须使用操作符 SBYTE PTR
或 SWORD PTR指明类型。
SBYTE PTR BX
SBYTE PTR [BX+SI+DISP]
Var db –1 var sbyte –1
.If al<sbyte ptr var,if al<var
…… ……X √
第 五 章 高 级 汇 编 语 言 程 序 设 计
12/2
若表达式中有一个数据为有符号数,则强制另一个数据也作为有符号数进行比较。
如,IF SWORD PTR BX >= AX,AX被强制作为有符号数看待。
(对变量不适用。若变量作为有符号数使用,
必须用 sbyte/sword/sdword定义)
第 五 章 高 级 汇 编 语 言 程 序 设 计
13条件控制伪指令 (end)
6)本节新增内容:
用于条件表达式的操作符
有符号数专用的变量定义伪指令
有符号数专用的类型说明操作符
★ 分析教材举例
★ 浏览汇编结果
★ 例题 5.1(实根判断)
回 5.1
第 五 章 高 级 汇 编 语 言 程 序 设 计
145.1.2循环控制伪指令
5.1.2循环控制伪指令
.WHILE和,ENDW,当型循环结构
.REPEAT和,UNTIL/.REPEAT和,UNTILCXZ:直到型
.BREAK:退出循环;,CONTINUE,转向循环体开始格式 1
.WHILE 条件表达式 ;表达式为真,执行循环体循环体 ;
.ENDW ;循环体结束第 五 章 高 级 汇 编 语 言 程 序 设 计
15循环控制伪指令格式 2
.REPEAT ;重复执行循环体循环体
.UNTIL 条件表达式 ;直到条件表达式为真格式 3
.REPEAT ;重复执行循环体循环体
.UNTILCXZ [条件表达式 ]; CX←CX -1,直到 CX=0;或条件表达式结果为真第 五 章 高 级 汇 编 语 言 程 序 设 计
16循环控制伪指令注 释:对,REPEAT/.UNTILCXZ(条件表达式)
1)不带表达式,结束循环的条件为 CX-1减到 0,
循环控制被汇编为 LOOP指令。
2)带条件表达式,结束循环的条件为 CX减到 0 或表达式为真,表达式只能比较寄存器与寄存器(存储单元、常数),以及存储单元与常数相等( ==)或不等
(! =),所以,汇编后的指令为 LOOPE或 LOOPNE。
* 分析教材举例
* 浏览汇编结果
* 例题 5.2:求数组前若干非负数之和 。
* 浏览例题 5.2汇编结果回 5.1
第 五 章 高 级 汇 编 语 言 程 序 设 计
175.1.3过程声明和调用伪指令
5.1.2 过程声明和过程调用伪指令利用堆栈传递参数为常用方式,但传统的编程方法容易出错。 MASM6.X扩充了 PROC伪指令的功能,并新增了几条伪指令,使调用子程序具有高级语言的特性。
按使用顺序介绍:
1.过程声明 PROTO
过程名 PROTO 语言类型,[参数名 ]:类型,……
注释,1)使用带参数的过程调用,必须定义语言类型,一般用 C或 STDCALL。 2)参数必须用逗号打头;
多个参数之间用逗号分割。 3)参数名可省略,类型不可省略。
例 5.3 CHECKSUMD PROTO C,V1:WORD,V2:WORD
第 五 章 高 级 汇 编 语 言 程 序 设 计
18过程定义格式
2.过程定义 PROC
过程名 PROC 语言类型 [USES 寄存器列表 ]
,形参 1:类型,形参 2:类型 …
[LOCAL 参数表 ]
……
过程名 ENDP
注释,1)语言类型与 USES 之间用空格分割。
2)寄存器列表:用空格分割的通用寄存器,决定保护现场和恢复现场。
3)参数用逗号打头,且用逗号分割;参数名为形参名,调用时被实参替换。
4)如果过程用到局部变量,用 LOCAL伪指令定义。
第 五 章 高 级 汇 编 语 言 程 序 设 计
19几个可选项的说明过程定义中其他几个可选项的说明:
1)调用距离:为 NEAR或 FAR,简化段定义格式中,由
.model语句选择的存储模式决定,small模式下,调用距离为 NEAR。可省略。
2)作用范围:为 PUBLIC,PRIVATE等,表示该过程是否对其他模块可见(可引用)。默认为 PUBLIC,表示该过程其他模块可见(可引用)。可省略。
3)起始参数:是一个可带参数的宏的名字。该宏决定过程的起始代码和结束代码,例如控制参数如何设置、如何保存寄存器等。 MASM调用的宏由用户自行定义。可省略。
第 五 章 高 级 汇 编 语 言 程 序 设 计
20过程定义举例例 5.3 过程定义
checksumd PROC c USES bx cx,countp,word
,arryp,word
mov bx,arryp
mov cx,countp
… …
ret
checksumd ENDP
语言类型 寄存器列表形参、形参类型第 五 章 高 级 汇 编 语 言 程 序 设 计
21过程调用
3.过程调用伪指令 INVOKE
INVOKE 过程名,实参 1,实参 2,… …
INVOKE checksumd,count,offset array
调用时:
①实参用逗号打头,且用逗号分隔。
②实参 1替换形参 1,实参 2替换形参 2。
* 例题 5.3源程序 (语言类型,C)
* 例题 5.3汇编结果
* 例题 5.3a源程序 (语言类型,STDCALL)
* 例题 5.3a汇编结果第 五 章 高 级 汇 编 语 言 程 序 设 计
22过程定义的说明 (end)
几点 说明:
①如果在过程中使用参数,必须指定语言类型。
②如果在,MODEL语句中和过程定义中都没有指定语言类型,会产生汇编错误。
③如果在,MODEL语句中指定了语言类型,则过程声明和过程定义中可以省略语言类型。
.MODEL SMALL,C ;指定了 C语言类型
④过程定义和过程声明必须一致。如编程过程中修改了一个,忘记修改另一个,则会造成错误。为避免此种情况发生,可以把全部过程定义放在代码段内开始的部分(,STARTUP之前),而省略过程声明。
返回第五章回 5.1
第 五 章 高 级 汇 编 语 言 程 序 设 计
235.2宏结构程序设计
5.2宏结构程序设计对常用的、具有独立功能的程序段,除了可定义为过程外,还可定义为宏结构或宏指令。宏指令提供了简化程序设计的另一种方法。
通常与宏指令配合使用的伪指令还有重复汇编和条件汇编。宏指令、重复汇编和条件汇编统称宏结构。
本节介绍宏指令的定义和调用,以及重复汇编和条件汇编。
5.2.1 宏汇编
5.2.2 重复汇编
5.2.3 条件汇编返回第五章第 五 章 高 级 汇 编 语 言 程 序 设 计
245.2.1 宏汇编 宏的定义和调用
5.2.1 宏汇编
1.宏的定义和调用、宏展开宏定义宏名 MACRO [形参 1,形参 2,…… ]
宏定义体;指令语句的组合
ENDM
宏调用宏名 [实参 1,实参 2,… … ]
例题 5.4a+5.4b
第 五 章 高 级 汇 编 语 言 程 序 设 计
25宏展开宏展开汇编时,用宏体取代宏调用,用实参取代形参,
称为宏展开。
宏展开时,实参替代形参按位置匹配的原则。
实参与形参的个数可以不等,参数替换时,多余的实参不于考虑;多余的形参以空格替代。
实参替代形参时,不进行类型检查,完全是字符串的替代,替代后是否合法有效,由汇编程序翻译时进行语法检查。
宏展开后 5.4B
第 五 章 高 级 汇 编 语 言 程 序 设 计
26宏的参数及宏操作符
2.宏的参数参数的形式灵活多变,可以是常数、变量、存储单元、指令操作码或它们的一部分,也可以是表达式,
使用灵活多变的参数,同一个宏定义甚至可以执行不同的操作。
几个宏操作符
&,替换操作符:用于将参数与其他字符分开。用在宏体中。如果参数紧接在其他字符之前或之后,
或者参数出现在带引号的字符串中,就必须使用该伪操作符第 五 章 高 级 汇 编 语 言 程 序 设 计
27宏操作符
<>:字符串传递操作符,用在宏调用的实参中。
在宏调用中,如果传递的字符串实参数含有逗号、空格等间隔符号,则必须用这对操作符,以保证字符串的完整
!,转义操作符,指示其后的一个字符作为一般字符,无特殊意义。如 !!/!&
%,表达式操作符,将后面跟的表达式的值作为实参,而不是将表达式本身作为参数。用在实参中。;;:宏注释符,用于表示在宏定义中的注释。采用这个符号的注释,在宏展开时不出现例题 5.5A,5.5B,5.6
“:REQ,:=默认值,可参考,宏汇编大全,
第 五 章 高 级 汇 编 语 言 程 序 设 计
28与宏有关的伪指令 1
3.与宏有关的伪指令
①局部标号伪指令
LOCAL 标号列表 ;当宏定义体内有标号,同一程序内多次调用,会造成标号的重复定义。
用 LOCAL说明的标号,第一次宏展开时,产生的标号为0000,第二次宏展开时产生的标号为0001,
(ffff)
注释,※ 只能在宏体内使用。
※ 只能紧接在宏定义语句之后使用。
第 五 章 高 级 汇 编 语 言 程 序 设 计
29与宏有关的伪指令 2
如宏定义,ABSOL MACRO OPRD
LOCAL NEXT
CMP OPRD,0
JGE NEXT
NEG OPRD
NEXT:
ENDM
宏调用 1,ABSOL WORD PTR [BX]
宏调用 2,ABSOL BX
第 五 章 高 级 汇 编 语 言 程 序 设 计
30与宏有关的伪指令 3
宏展开后的代码:
CMP WORD PTR[BX],0
JGE0000
NEG WORD PTR[BX]
0000:
CMP BX,0
JGE0001
NEG BX
0001:
第一个宏展开第二个宏展开第 五 章 高 级 汇 编 语 言 程 序 设 计
31与宏有关的伪指令 2
② 宏定义删除
PURGE 宏名表;在各类名字中,只有宏名可以和指令同名;当同名时,宏定义优先级最高。
③宏定义退出 (宏展开退出)
EXITM;对 EXITM后面的语句停止宏展开。
第 五 章 高 级 汇 编 语 言 程 序 设 计
32宏与子程序
4.宏与子程序相同点:简化源程序的设计和结构不同点:
※ 处理时间段不同。
※ 对目标程序的长度影响不同。
※ 对目标程序执行速度的影响不同。
※ 传递参数的方式不同;传递参数过程中如出现错误,错误的性质不同。 (宏:语法;子程序:逻辑)
通常,当程序段较短,要求较快执行时,用宏定义。
当程序段较长,或为减小目标代码长度,用子程序。
回 5.2
第 五 章 高 级 汇 编 语 言 程 序 设 计
335.2.2重复汇编
5.2.2重复汇编重复汇编 指在汇编过程中,重复展开一段(基本)
相同的语句。
如果程序中需要连续重复一段相同的语句或基本相同的语句,可以使用重复汇编伪指令,也就是让汇编程序代替程序员完成重复的工作。
重复汇编伪指令常在宏体内使用,但也可以在宏体外使用。重复汇编没有名字,不能被调用。
重复汇编伪指令有 3条,3条伪指令区别在于如何规定重复次数。
第 五 章 高 级 汇 编 语 言 程 序 设 计
34按参数值重复伪指令
1.按参数值重复伪指令
REPEAT 重复次数重复体
ENDM
例 5.8 定义 26个大写字母
char =?A?
Aztabel EQU THIS BYTE
REPEAT 26
DB char
char = char+1
ENDM
汇编结果:
DB char
char = char+1
DB char
char = char+1
……
DB char
char = char+1
第 五 章 高 级 汇 编 语 言 程 序 设 计
35按参数个数重复伪指令
1.按参数个数重复伪指令
FOR 形参,<实参表 >
重复体
ENDM
例 5.9a 保护常用寄存器
FOR regad,<AX,BX,CX,DX>
PUSH regad
ENDM
汇编结果:
PUSH AX
PUSH BX
PUSH CX
PUSH DX
形参:重复体中使用的参数注意:形参只有一个实参:汇编展开时使用的参数,用其替换重复体中出现的形参;按实参个数重复。
必须使用,<>”括起。
第 五 章 高 级 汇 编 语 言 程 序 设 计
36按参数字符个数重复伪指令
1.按参数 字符 个数重复伪指令
FORC 形参,字符串 ; FORC 形参,<字符串 >
重复体
ENDM
例 5.9b 恢复常用寄存器
FORC regad,dcba
POP &regad&x
ENDM
汇编结果:
POP DX
POP CX
POP BX
POP AX
回 5.2
第 五 章 高 级 汇 编 语 言 程 序 设 计
375.2.3 条件汇编
5.2.3 条件汇编条件汇编伪指令使汇编程序根据某种条件是否成立决定是否汇编某段语句序列条件汇编伪指令格式:
IFxx 表达式分支语句体 1
[ELSE
分支语句体 2]
ENDIF
伪指令中的,xx”为组成条件汇编伪指令的其他字符,
不同的,xx”,表达的条件不同。如,IF 表达式,,表达的条件为:如表达式的值不为 0,则条件满足;
,IFE 表达式,表达的条件为:如表达式的值为 0,则条件满足。(见教材表 5.3)
第 五 章 高 级 汇 编 语 言 程 序 设 计
38条件汇编伪指令( IF|IFE)中的表达式条件汇编伪指令( IF|IFE)中的表达式:
①运算符使用第三章介绍的关系运算符:
EQ,NE,GT,LT,GE,LE
注意,不同于条件控制伪指令(,IF)中使用的运算符。
②表达式用 0FFFFH(或任意非 0数)表示真,用 0表示假。
第 五 章 高 级 汇 编 语 言 程 序 设 计
39例 5.10
例 5.10:定义一个元素个数不超过 100个的数组。
PDATA MACRO NUM
IF NUM LT 100
DB NUM DUP(?)
ELSE
DB 100 DUP(?)
ENDIF
ENDM
宏调用,PDATA 12
宏展开,DB 12 DUP (? )
宏调用,PDATA 105
宏展开,DB 100 DUP (? )
第 五 章 高 级 汇 编 语 言 程 序 设 计
40例 5.11/1
例 5.11 编写宏 MAXNUM,计算 3个以内的数据中的最大值,
并将结果送入 AX寄存器,要求根据宏调用时的实参个数展开相应代码。
分析,1)至少应有一个参数,故第一个参数设为不可缺少;
2)宏指令应能够作到:根据实参情况产生不同的程序段,进行不同的处理。实参可分三种情况,A.只有一个参数
B.有两个参数
C.有三个参数显然,应使用条件汇编。
第 五 章 高 级 汇 编 语 言 程 序 设 计
41/2
MAXNUM MACRO WX:REQ,WY,WZ
LOCAL MAXNUM1,MAXNUM2
MOV AX,WX ;只有一个实参替换 WX
IFNB <WY> ;还有 WY时
CMP AX,WY
JGE MAXNUM1
MOV AX,WY
ENDIF
MAXNUM1:
IFNB <WZ> ;当有 WZ时,汇编本段
CMP AX,WZ
JGE MAXNUM2
MOV AX,WZ
ENDIF
MAXNUM2:
ENDM
第 五 章 高 级 汇 编 语 言 程 序 设 计
42/3
宏调用,汇编结果:
Maxnum bx;只有 1个参数
Mov ax,bx;只有 1个参数
Maxnum 3,4;有 2个参数
Mov ax,3
Cmp ax,4
Jge0000
Mov ax,4
0000:
第 五 章 高 级 汇 编 语 言 程 序 设 计
43/4
宏调用,汇编结果:
Maxnum n1,n2,n3;有 3个参数
mov ax,n1
cmp ax,n2
jge0000
mov ax,n2
0000:
cmp ax,n3
jge0001
mov ax,n3
0001:
注意区别条件控制伪指令 和条件汇编伪指令第 五 章 高 级 汇 编 语 言 程 序 设 计
44P149例题 /1
P149例题:用宏结构实现信息显示。
dstring MACRO string ;;定义字符串
db '&string&',0dh,0ah,'$'
ENDM
mainbegin MACRO dsseg ;;设置数据段地址
mov ax,dsseg
mov ds,ax
ENDM
dispmsg MACRO message;;显示,形参为偏移地址
mov dx,offset message
mov ah,09h
int 21h
ENDM
第 五 章 高 级 汇 编 语 言 程 序 设 计
45/2
mainend MACRO retnum ;;返回 DOS,可不带参数
ifb <retnum> ;;宏调用没有实参数
mov ah,4ch
else ;; 有参数
mov ax,4c00h+(retnum AND 0ffh)
endif
int 21h
ENDM
保证不破坏 AH的内容第 五 章 高 级 汇 编 语 言 程 序 设 计
46/3
.model small
.stack 256
.data
msg1 equ this byte
dstring <Hello,Everybody !!>
msg2 equ this byte
dstring <You see,I made it.>
.code
start:mainbegin @data ;建立 DS内容
dispmsg msg1 ;显示 msg1字符串
dispmsg msg2 ;显示 msg2字符串
mainend ;返回 DOS
end start
回 5.2 返回第五章第 五 章 高 级 汇 编 语 言 程 序 设 计
475.3 模块化程序设计
5.3 模块化程序设计开发大型或较复杂的程序时,往往需要结合使用其他方法,如源程序文件的包含、目标代码文件的连接、
子程序库的使用等等。
本节简单介绍以上三种方法。
5.3.1 源程序文件的包含
5.3.2 目标代码文件的连接
5.3.3 子程序库的使用返回第五章第 五 章 高 级 汇 编 语 言 程 序 设 计
485.3.1 源程序文件的包含
5.3.1 源程序文件的包含对大型源程序,可以分成几个源文件,待汇编时在用包含伪指令 INCLUDE将它们结合成一个文件进行汇编。
格式为,INCLUDE 文件名汇编时,汇编程序将指定的文件插在伪指令所在的位置,与其他部分同时汇编。
适用于:汇集常用的子程序为一个源文件 (.asm);
汇集常用的宏定义为一个宏库文件 (.mac);
汇集常用的常量定义和声明为一个包含文件 (.inc)。
当源程序需要使用上述文件中的某些内容时,不用重新编写,只要使用包含伪指令将文件包含即可。
第 五 章 高 级 汇 编 语 言 程 序 设 计
49例 5.12a
例 5.12a 利用源程序包含的方法实现将输入的数据按升序输出。
要求:最多输入 100个无符号字节数据;以十六进制形式输入;按照升序排序并显示。
源程序由三个单独的文件组成:
① 宏库文件 lt512a.mac(显示字符和字符串)
② 子程序文件 sub512a.asm(输入、排序)
③ 主程序文件 lt512a.asm(提供入口参数、处理出口参数、排序、显示)
第 五 章 高 级 汇 编 语 言 程 序 设 计
50宏库文件 lt512a.mac
1)宏库文件 lt512a.mac
dispcharmacro char ;显示 char字符
mov dl,char
mov ah,2
int 21h
endm
dispmsg macro message ;显示 message字符串
mov dx,offset message
mov ah,9
int 21h
endm
第 五 章 高 级 汇 编 语 言 程 序 设 计
51子程序文件 sub512a.asm
2)子程序文件 sub512a.asm
子程序源文件有 3个子程序
ALdisp ;显示 2位 16进制数子程序(例 4.10)
sorting ;排序子程序(例 4.8)
input ;键盘输入子程序 (后面分析)
还包含一个宏
convert ;;将 DX两位 ASCII码转换为两位 16进制数第 五 章 高 级 汇 编 语 言 程 序 设 计
52主程序文件 lt512a.asm
3)主程序文件 lt512a.asm
include lt421a.mac ;包含宏库文件,置于主程
.model /.stack /.data /,code等 序头部
dispmsg msg1 ;提示输入数据
mov bx,offset buf
call input ;数据输入
cmp cx,0
je start4 ;没有输入数据则退出
mov count,cx
..,;显示输入的数据
..,;数据排序
..,;显示经排序后的数据
start4:.exit 0
include sub421a.asm ;包含子程序文件
end
将三个文件分别编辑,主程序文件用两条包含伪指令将宏库文件和子程序文件包含(注意包含伪指令的位置),
然后汇编并连接主程序文件,即可得到可执行文件。
第 五 章 高 级 汇 编 语 言 程 序 设 计
53键盘输入子程序 /1
键盘输入子程序:;每次输入 1位或 2位十六进制数字;;空格或逗号确认输入;;退格键删除当前输入的数据;;回车表示所有数据输入结束。;入口参数,ds:bx=
存放数据的缓冲区;出口参数,cx=
数据个数转换和保存返回转换和保存错误处理
A
输入一个字符退格?
空格?
回车?
逗号?
有效?
A
A存入 DH DL
第 五 章 高 级 汇 编 语 言 程 序 设 计
54/2
input proc
push ax
push dx
xor cx,cx ;数据个数清 0
input01:xor dx,dx ;输入字符清 0
input02:mov ah,1 ;键盘输入一个字符
int 21h
第 五 章 高 级 汇 编 语 言 程 序 设 计
55/3
input10:cmp al,0dh
je input30 ;是回车,结束整个数据的输入
cmp al,’ ’
je input20
cmp al,’,’
je input20 ;是空格和逗号,确认输入了一个数据
cmp al,08h
je input17 ;是退格,丢弃本次输入的数据,出错第 五 章 高 级 汇 编 语 言 程 序 设 计
56/4
cmp al,’0’ ;有效数字判断(图 5.2b)
jb input17 ;小于 ’ 0’,不是有效数字,出错
cmp al,’f’
ja input17 ;大于 ’ f’,不是有效数字
cmp al,’a’
jb input11 ;检查是否再 ‘ a—F’之间
sub al,20h ;’a’~ ’ f’转换成大写 ’ A’~ ’ F’
jmp input12 ;有效数据处理
input11:cmp al,’F’
ja input17 ;字符小于 ’ a’、大于 ’ F’,出错
cmp al,’A’
jae input12 ;是 ’ A’~ ’ F’,有效字符
cmp al,’9’
ja input17 ;字符小于 ’ A’、大于 ’ 9’,出错
00 7Fh
0 9 A F a f
第 五 章 高 级 汇 编 语 言 程 序 设 计
57/5
input12:cmp dl,0;有效字符的处理
jne input13 ;dl≠0 (已经有一位数据)
mov dl,al;dl=0,输入了一个数据的高位,则 dl←al
jmp input02 ;转到字符输入
input13:cmp dh,0
jne input17;dl≠0,dh≠0 输入 3位数据,出错
mov dh,dl;dl≠0,dh= 0输入了一个数据的低位
mov dl,al ;dh←dl,dl←al
jmp input02 ;转到字符输入第 五 章 高 级 汇 编 语 言 程 序 设 计
58/6
input17:mov dl,7;输入错误处理 (07h,控制码:鸣镝 )
mov ah,2
int 21h
mov dl,'?'
mov ah,2
int 21h
jmp input01 ;转到输入一个数据第 五 章 高 级 汇 编 语 言 程 序 设 计
59/7;确认一个数据后,转换正确的输入数据(图 5.2c)
input20:convert
jmp input01 ;转到输入一个数据;收到回车符,最后一个数据输入结束,转此
input30:convert
pop dx
pop ax
ret ;返回,出口参数已设定
input endp
第 五 章 高 级 汇 编 语 言 程 序 设 计
60宏,convert macro/1;将 DX两位十六进制形式的 ASCII码转换为两位 16进制数( 8位二进制数):
convert macro
local input21,input22
local input24,input25
cmp dl,0
je input25 ;;dl=0,没有要转换的数据,退出第 五 章 高 级 汇 编 语 言 程 序 设 计
61/2
cmp dl,'9'
jbe input21
sub dl,7 ;;字符 A~ F,则减 7
input21:and dl,0fh ;;转换低位
cmp dh,0 ;;dh=0,没有高位数据
je input24
cmp dh,'9'
jbe input22
sub dh,7 ;;字符 A~ F,则减 7
input22:shl dh,1 ;;高位乘 16
shl dh,1
shl dh,1
shl dh,1 ;;转换高位
or dl,dh ;;合并高、低位第 五 章 高 级 汇 编 语 言 程 序 设 计
62/3(end)
input24:mov [bx],dl ;;存入缓冲区
inc bx
inc cx ;;数据个数加 1
input25:
endm
Back5.3
第 五 章 高 级 汇 编 语 言 程 序 设 计
635.3.2目标代码文件的连接
5.3.2 目标代码文件的连接将常用子程序写成一个或多个源文件,并对其进行汇编,得到一个个单独的 OBJ文件;对主程序也单独进行汇编得到 OBJ文件,最后利用连接程序把多个 OBJ文件连接,形成可执行文件。
用这种方法可缩短汇编时间,但宏结构文件、常量定义、声明文件等文件通常仍编辑成包含文件,因此这种方法往往和,源程序文件的包含,共同使用。
需要遵循的原则:
① 声明共用的变量、过程等
② 实现正确的段组合
③ 处理好参数传递问题第 五 章 高 级 汇 编 语 言 程 序 设 计
64/原则 1
原则 1
各个模块间公用的变量、过程等要说明
PUBLIC 标识符 [,标识符,..];定义标识符的模块使用
EXTERN 标识符,类型 [,标识符,类型,..];调用标识符的模块使用标识符是变量名、过程名等类型是 byte / word / dword(变量)或 near / far
(过程)
在一个源程序中,public/extern语句可以有多条
各模块间的 public/extern伪指令要互相配对,并且指明的类型互相一致第 五 章 高 级 汇 编 语 言 程 序 设 计
65/原则 2
原则 2
子程序文件必须定义在代码段中,也可以具有局部的数据变量
采用简化段定义格式,只要采用相同的存储模式,容易实现正确的近或远调用
完整段定义格式中,为了实现模块间的段内近调用
( near类型),各自定义的段名、类别必须相同,组合类型都是 public。实际的程序开发中,各个模块往往由不同的程序员完成,不易实现段同名及类别相同,所以索性定义成远调用( far类型)
定义数据段时,同样也要注意这个问题。当各个模块的数据段不同时,要正确设置数据段 DS寄存器的段基地址。
第 五 章 高 级 汇 编 语 言 程 序 设 计
66/原则 3
原则 3
少量参数可用寄存器或堆栈直接传送数据本身
大量数据可以安排在缓冲区,用寄存器或堆栈传送数据的存储地址
还可利用变量传递参数,但是要采用 public/extern声明为公共(全局)变量这些也是子程序间的参数传递方法
另外,更好的传递参数方法是用堆栈传递参数。
第 五 章 高 级 汇 编 语 言 程 序 设 计
67例 5.12b
例 5.12b 利用目标代码文件连接的方法,实现将输入的数据按升序输出。
宏定义并入主程序 lt512b.asm。
子程序文件 sub512b.asm,要加上段定义语句、声明语句等,但不需要起始点和结束点。
模块连接的操作步骤:
① 分别编辑生成各个文件
② 分别汇编各个文件
③ 连接各个目标文件,形成可执行文件第 五 章 高 级 汇 编 语 言 程 序 设 计
68例 5.12b主程序例 5.12b 主程序:
...;宏定义(也可以使用包含语句)
.code
public count ;定义(本模块的) count公用
extern ALdisp:near,sorting:near,input:far;声明其他模块中的子程序
.startup
...
.exit 0;去掉( lt512a.asm中的)包含语句
end
第 五 章 高 级 汇 编 语 言 程 序 设 计
69例 5.12b子程序 (end)
例 5.12b子程序
.model small ;定义同样的存储模式
extern count:word;在其他模块定义了字变量 count
.code ;子程序在代码段中
public aldisp,sorting,input;3个子程序是共用的
Aldisp proc ;仍然作为近调用
sorting proc ;仍然作为近调用
input proc far ;修改为远调用...
mov count,cx ;提供出口参数...
input endpend ;结束汇编
Back5.3
第 五 章 高 级 汇 编 语 言 程 序 设 计
705.3.3 子程序库的使用
5.3.3 子程序库的使用将子程序源文件生成 OBJ文件,然后和主程序连接,
由于被连接的每个 OBJ文件的全部代码都会成为可执行程序的一部分,在最后生成的可执行文件中,会包括无用的子程序,造成可执行程序庞大。为此,可使用子程序库。子程序库(,LIB文件)是子程序模块的集合,库文件中存放着各子程序的名称、目标代码以及有关的定位信息。执行连接程序时,只要指定所需要的库文件,连接程序将从库文件中摘取主程序调用的子程序,而未调用的子程序不会进入最后的可执行程序。
库文件由 MASM提供的 LIB.EXE程序管理。
第 五 章 高 级 汇 编 语 言 程 序 设 计
71例题 5.12c/1
例题 5.12c 利用子程序库的调入方法,实现将输入的数据按升序输出。
实现步骤:
1)编辑 4个文件:
① 主程序文件 lt512c.asm
② 子程序文件 sub512c1.asm(显示)
③ 子程序文件 sub512c2.asm(排序)
④ 子程序文件 sub512c3.asm(输入)
第 五 章 高 级 汇 编 语 言 程 序 设 计
72例题 5.12c/2
2)分别汇编,得到 4个目标模块( obj文件)
3)生成子程序库文件(或加入其它子程序库)
LIB 库文件名 + 子程序目标文件名
LIB sub512c.lib + sub512c1.obj + sub512c2.obj
+ sub512c3.obj
4)运行连接程序,link lt512c.obj
提示输入库文件时,输入 sub512c.lib
( 也可在主程序源文件中使用子程序库包含伪指令 includelib sub512c.lib 。 )
第 五 章 高 级 汇 编 语 言 程 序 设 计
73例题 5.12主程序例题 5.12主程序
.,;宏定义
.code
Extern ALdisp:near,sorting:near,input:near;声明其他模块中的子程序
.startup
...
call input
...
.exit 0
end
第 五 章 高 级 汇 编 语 言 程 序 设 计
74sub512c1.asm
sub512c1.asm
.model small
.code
public aldisp
Aldisp proc
...
Aldisp endp
end
第 五 章 高 级 汇 编 语 言 程 序 设 计
75sub512c2.asm
sub512c2.asm
.model small
.code
public sorting
sorting proc
...
sorting endp
end
第 五 章 高 级 汇 编 语 言 程 序 设 计
76sub512c3.asm(end)
sub512c3.asm
.model small
.code
public input
input proc
...
input endp
end
Back5.3 返回第五章第 五 章 高 级 汇 编 语 言 程 序 设 计
775.4输入输出程序设计
5.4 输入输出程序设计完成 CPU与外设端口之间数据传送的程序称为输入输出程序。
通常有 3种端口,数据口、状态口以及控制口,分别对应接口中的数据寄存器、状态寄存器以及控制寄存器。
每个端口有一个端口地址,CPU使用该地址访问接口中的相应寄存器,执行输入输出的指令为 IN指令和 OUT指令。
输入输出(数据交换)的方式分为两大类:程序控制输入输出方式和直接存储器存取方式( DMA方式)。
由于该部分内容是,微机原理和接口技术,的主要内容之一,本节只进行简单介绍。
返回第五章第 五 章 高 级 汇 编 语 言 程 序 设 计
78数据交换方式
1.无条件传送方式
2.查 询 传送方式
3.中 断 传送方式数据交换方式:
第 五 章 高 级 汇 编 语 言 程 序 设 计
791.无条件传送方式
1.无条件传送方式
CPU可以在任何时刻向端口写入数据和从端口读入数据,也就是说,CPU假设外设接口电路总是处于准备好的状态。采用无条件传送方式,只适用于简单外设(或定时关系以知的外设),如输出设备为数码显示电路,或输入设备为一组提供某种数据的开关,在这种情况下,
CPU执行输出或输入操作不需要任何先决条件。
无条件传送方式局限性比较大,对大部分外设不适用,因而采用较少。
第 五 章 高 级 汇 编 语 言 程 序 设 计
802.查询方式
2.查询方式
CPU在执行输入输出操作时,先查询外设的状态口,
当状态口表示外设已准备好时,CPU执行输入输出操作;
当状态口反映外设未准备好时,CPU继续查询状态口,直到外设准备好,再执行输入输出操作。
读入状态口准备好?
执行 IN或 OUT
N
Y
查询方式适用于大部分外设,但 CPU的利用率较低。
第 五 章 高 级 汇 编 语 言 程 序 设 计
813.中断传送方式
3.中断传送方式中断传送方式基于计算机的中断控制系统。当外设准备好传送数据时,向 CPU发出中断请求,如有关条件满足,则 CPU响应中断请求,执行相应中断服务程序,完成数据的输入或输出,然后继续执行原来的程序。
中断传送方式相对查询方式,可提高 CPU的利用率。
以上三种传送方式虽然各不相同,但有一点是相同的,即通过 CPU执行输入输出程序实现数据的传送,因而数据传输率低,要得到高数据传输速率,应采用直接存储器存取方式,即 DMA方式,用 DMA控制器控制数据的传输过程。
返回第五章回 5.4
第 五 章 高 级 汇 编 语 言 程 序 设 计
82本章重点及习题分析本章重点及习题分析
㈠本章重点
★ 条件控制伪指令
★ 循环控制伪指令
★ 带参数的过程定义、声明及调用伪指令
★ 宏结构的定义及宏调用
重复汇编伪指令
条件汇编伪指令第 五 章 高 级 汇 编 语 言 程 序 设 计
835.1
㈡ 习题分析
5.1条件表达式中逻辑与,&&”表示两者都为真,整个条件才为真,对于程序段:
.if (X==5)&&(AX!=BX)
INC AX
.endif
用转移指令实现上述分支结构,并比较汇编程序生成的代码序列。
cmp x,5 cmp x,005h
jnz n1 jne @c0001
cmp ax,bx cmp ax,bx
jz n1 je @c0001
inc ax inc ax
N1,…… @c0001:
第 五 章 高 级 汇 编 语 言 程 序 设 计
845.2
5.2条件表达式中逻辑或,||”表示两者之一为真,整个条件就为真,对于程序段:
.if (X==5)||(AX!=BX)
INC AX
.endif
用转移指令实现上述分支结构,并比较汇编程序生成的代码序列。
cmp x,5 cmp x,005h
jz n1 je @c0002
cmp ax,bx cmp ax,bx
jnz n1 je @c0001
jmp n2 @c0002,inc ax
N1,inc ax @c0001,……
N2,……
第 五 章 高 级 汇 编 语 言 程 序 设 计
855.3
5.3 对于程序段,while ax!=10
mov [bx],ax
inc bx
inc bx
inc ax
.endw
用处理器指令实现上述循环结构,并与汇编结果比较。
lop:cmp ax,10 jmp @c0001
jz next @c0002,mov [bx],ax
mov [bx],ax inc bx
inc bx inc bx
inc bx inc ax
inc ax @c0001,cmp ax,00ah
jmp short lop jne @c0002
next,…… ……
第 五 章 高 级 汇 编 语 言 程 序 设 计
865.4
5.4 对于程序段,repeat
mov [bx],ax
inc bx
inc bx
inc ax
.until ax=10
用处理器指令实现上述循环结构,并与汇编结果比较。
lop,mov [bx],ax @c0001,mov [bx],ax
inc bx inc bx
inc bx inc bx
inc ax inc ax
cmp ax,10 cmp ax,10
jnz lop jne @c0001
第 五 章 高 级 汇 编 语 言 程 序 设 计
875.5— 5.7
5.5 宏是如何定义、调用和展开的?
5.6 宏定义中的形参有和特点?是如何进行形参和实参结合的?
5.7 宏汇编、重复汇编与条件汇编有何异同?
都是伪指令,都是在汇编时处理。
宏汇编适用于多次使用的程序段;重复汇编适用于连续重复适用的语句;条件汇编适用于根据条件是否符合,最终程序应包含的语句。
第 五 章 高 级 汇 编 语 言 程 序 设 计
885.10,5.11
5.10 定义一个宏 logical,代表 4条逻辑运算指令:
And/or/xor/test。logical macro scode,sdest,ssorce
scode sdest,ssorceendm
宏调用,logical and,ax,bx
logical xor,al,80h
5.11 修改 logical,将 neg指令包括进去。
logical macro scode,sdest,ssorce
ifnb <ssorce>
scode sdest,ssorce
else
scode sdest
endif
endm
宏调用,logical neg,bx
logical neg,byte ptr[bx]
第 五 章 高 级 汇 编 语 言 程 序 设 计
895.12
5.12 编写一个宏指令 move doprnd,soprnd,实现任意寻址方式的字量源操作数送到目的操作数,包括存储单元到存储单元的传送功能。
move macro doprnd,soprnd
push ax
mov ax,soprnd
mov doprnd,ax
pop ax
endm
宏调用,move ax,cx
move [bx],[bx+si]