微机原理与接口技术-部分作业参考答案梳理
2、8086的总线接口单元由那几部分组成,有什么功能?
【答】8086的总线接口单元主要由下面几部分组成:
(1)段寄存器,4个段寄存器CS/DS/ES/SS,用于保存各段地址;为分段寻址定位段的位置。
(2)地址加法器,一个20位地址加法器,用于形成20位物理地址;将分段地址转换为物 理地址。
(3)指令指针寄存器,一个16位的指令指针寄存器IP,用于保存当前指令的偏移地址; 存储代码段内的偏移,与CS一起构成取指所需的程序计数器。
(4)存储器接口,用于内总线与外总线的连接;通过此接口进行取指和存取操作数。
(5)指令流字节队列,用于保存指令。
3、8086的执行单元由那几部分组成,有什么功能?
【答】8086的执行单元部件主要由下面几部分组成:控制器、算数逻辑单元、标志寄存器、通用寄存器组。
(1)控制器,从指令流顺序取指令、进行指令译码,完成指令的执行等。
(2)算数逻辑单元ALU,根据控制器完成8/16位二进制算数与逻辑运算。
(3)标志寄存器,使用9位,标志分两类。其中状态标志6位,存放算数逻辑单元ALU运算结果特征;控制标志3位,控制8086的3种特定操作。
(4)通用寄存器组,用于暂存数据或指针的寄存器阵列。
8、8086形成三总线时,为什么要对部分地址线进行锁存?什么信号控制锁存?
【答】 为了确保CPU对存储器和I/O端口的正常读/写操作,要求地址和数据同时出现在地址总线和数据总线上。而在8086CPU中AD0~AD15总线是地址/数据复用的,因此需在总线周期的前一部分传送出地址信息,并存于锁存器中,而用后一部分周期传送数据。8086CPU中是通过CPU送出的ALE高电平信号来控制锁存的。
12、在8086中,逻辑地址FFFFH:0001H、00A2H:37F0H和B800H:173FH的物理地址分别是多少?
【答】(1)FFFFH*16+0001H=FFFF0H+0001H=FFFF1H (物理地址=段地址*10H(=16)+偏移地址。)
(2)00A20+37F0=4210H
(3)B8000+173F=B973FH
15、8086工作在最小模式和最大模式的主要特点是什么?有何区别?
【答】最小模式接+5V,构成小规模的应用系统,只有8086一个微处理器,所有的总线 控制信号均为8086产生,系统中的总线控制逻辑电路,减少到最小; 不需总线控制器8288;适用于单一处理机系统。
最大模式接地,用于大型(中型)8086/8088系统中,系统总是包含有两个或多个微 处理器,其中一个主处理器就是8086或8088。其它的处理器称协处理器,协助主处理器工作,需要总线控制器来变换和组合控制信号, 需总线控制器8288; 适用于多处理机系统。
17、8086启动时有何特征,如何寻找8086系统的启动程序
【答】在8088/8086系统中,CPU启动后,处理器的标志寄存器、指令指针寄存器IP、段寄存器DS、SS、ES和指令队列都被清零,但是代码段寄存器CS被设置为FFFFH。因为IP=0000,而CS=FFFFH,所以,8088/8086将从地址FFFF0H开始执行指令。
通常,在安排内存区域时,将高地址区作为只读存储区,而且在FFFF0H单元开始的几个单 元中放入一条无条件转移指令,转到一个特定的程序中,这个程序往往实现系统初始化、 引导监控程序或者引导操作系统等功能,这样的程序叫做引导和装配程序。
第三章作业答案梳理
8086指令系统
3.5 设(IP)= 3D8F H,(CS)= 4050H,(SP)= 0F17C H,当执行CALL 2000:0094H后,试求出 IP、CS、SP、[SP]、[SP+1][SP+2] 和[SP+3]的内容?
【答】(IP)=0094H ,( CS)=2000H ,(SP)=F178H 参见P76页,CALL指令的(2)段间调用 的例子
[SP]=8FH , [SP+1]=3DH , [SP+2]=50H, [SP+3]=40H
3.7 分别用一条语句实现下述指明的功能
(1)栈顶内容弹出送字变量DI。 ( POP DI )
(2)双字变量AYD存放的地址指针送ES和SI。 ( LES SI ,AYD )
(3)不允许中断即关中断。 ( CLI )
(4)子程序返回调用程序。 ( RET )
(5)AX的内容加1,要求不影响CF。 ( INC AX )
(6)BX的内容加1,要求影响所有标志位。 ( ADD BX, 1 )
(7)若操作结果为零转向标号GOON。 ( JZ GOON )
3.8 8086/8088用什么途径来更新CS和IP的值?
【答】执行CALL、JMP、INT指令,可以改变CS和IP中的值,即改变程序走向。
3.9 字节扩展指令和字扩展指令用在什么场合?举例说明。
【答】需要对带符号数字节扩展为字时,要预先执行CBW指令。需要对带符号数字扩展为双字时,要预先执行CWD。
例:求-503/267=?,将商存1000H单元.
MOV AX,-503
MOV BX,267
CWD
IDIV
MOV [1000H],AX
HLT
3.12 8086状态标志寄存器中,作为控制用的标志位有( 3 )个,其中,不可用指令操作的是(DF、 IF、 TF)
3.13 设当前的SP=1000H,执行PUSHF指令后,SP=(0FFE H),若改为执行INT 20H指令后,则SP=( 0FFA H)。
【答】执行PUSHF指令后,SP=(0FFE H)。执行INT 20H指令后,则SP=( 0FFA H)。
3.14 设当前SS=2010H,SP=FE00H,BX=3457H,计算当前栈顶的地址为多少?当执行PUSH BX 指令后,栈顶地址和栈顶2个字节的内容分别是什么?
【答】当前栈顶指针(SP)=FE00H,物理地址=20100H+FE00H=2FF00H
当执行PUSH BX 指令后,栈顶指针(SP)=FE00-2=FDFEH,栈顶物理地址=2FEFEH,栈顶2个字节的内容分别57H,34H。
3.15 HLT指令用在什么场合?如CPU 在执行HLT 指令时遇到硬件中断并返回后,以下应执行哪条指令?
【答】HLT用在使CPU处于暂停状态而等待硬件中断的场合。
在执行HLT指令遇到硬件中断并返回后将执行HLT后面的一条指令。
3.16 为什么用増量指令或减量指令设计程序时,在这类指令后面不用进位标志作为判断依据?
【答】増量指令或减量指令不影响进位标志CF。
3.17 用普通运算指令执行BCD码运算时,为什么要进行十进制调整?具体讲,在进行BCD码的加、减、乘、除运算时,程序段的什么位置必须加上十进制调整指令?
【答】在BCD码中,采用4位二进制数对一个十进制数的编码,只允许0-9这10个数字出现,但CPU运算结果一般会超过此范围,因此要进行十进制调整。进行加、减法或乘法运算时,调整指令必须紧跟在算术指令后面,在进行除法运算时,调整指令放在除法指令之前。
3.18 中断指令执行时,堆栈的内容有什么变化?中断处理子程序的人口地址是怎样得到的?
【答】中断指令执行时,堆栈内容变化如下:标志寄存器被推入堆栈,且SP减2,然后CPU将主程序的下一条指令地址即断点地址推入堆栈,即段值CS推入堆栈且SP减2,偏移量推入堆栈,且SP减2。中断处理子程序的入口地址即中断向量,对应的中断类型号的4倍即为中断向量地址,在该地址处的4个字节内容,高地址单元两个字节为中断入口地址的段地址,低地址单元两个字节为中断入口地址的偏移地址。
3.19 中断返回指令IRET和普通子程序返回指令RET 在执行时,具体操作内容什么不同?
【答】IRET从堆栈中依次弹出断点处指令指针IP、代码段CS内容与标志寄存器的值,而RET从堆栈中依次弹出断点处指令指针IP值、代码段CS内容,不需要弹出标志寄存器的值。
3.20 将存放在0A00H单元和0A02H单元的两个无符号数相乘,结果存放在地址为0A04H开始的单元中。
【答】参考程序:
MOV AL,[0A00H]
MOV BL,[0A02H]
MUL BL
MOV [0A04H],AX ; MOV [0A06H],DX ;
3.21 编程序将AX中数,最高位保持不变,其余全部左移4位。
【答】参考程序:
MOV BX, AX
AND BX , 8000H
MOV CL, 4
SHL AX, CL
AND AX,7FFFH
OR AX, BX
3.22 将0400H单元中的数,低4位置零,高4位保持不变。
【答】参考程序:
MOV AL, [0400H]
AND AL, 0F0H
MOV [0400H], AL
3.23 将BX中的数,对高位字节求反,低位字节保持不变。
【答】参考程序:NOT BH 或者 XOR BX, FF00H
3.24 检测Bx中第13位(D13),为0时,把AL置0,为1时,把AL置1。
【答】参考程序:
TEST BX,0010 0000 0000 0000B
JZ ZERO
MOV AL,01H
HLT
ZERO: MOV AL,0
HLT
3.25 利用字串操作指令,将1000H~10FFH单元全部清零。
【答】参考程序:
CLD
MOV DI,1000H
MOV CX,100H
MOV AL,0
REP STOSB
3.26 从1000H开始,存放有200个字节,要查出字符#(ASCII码为23H), 把存放第一个#的单元地址送入BX中。
【答】参考程序:
CLD
MOV DI,1000H
MOV CX,200
MOV DX,CX
MOV AL,23H
REPNZ SCASB
JZ FOUND
JMP NOFOUND
FOUND: DEC DI ;上下对应
MOV BX,DI
NOFOUND: HLT
3.27 编程计算((X+Y)*10)+Z)/X,X、Y、Z都是16位无符号数,结果存在RESULT开始的单元。
【答】参考程序:
MOV AX,X
ADD AX,Y
MOV BX,0AH
MUL BX
ADD AX,Z
ADC DX,0H
MOV BX,X
DIV BX
MOV RESULT,AX
MOV RESULT+2,DX
HLT
3.28 用简单指令编程求-3/2=?,将商存DL,余数存DH单元。用TD调试后,写出DL,DH的内容。
【答】参考程序:
MOV AL,-3
CBW
MOV BL,2
IDIV BL
MOV DL,AL
MOV DH,AH
HLT
习题四 汇编语言程序设计
主要内容:汇编语言程序设计。主要介绍汇编语言程序的设计方法与编程原理,重点掌握算术运算程序、字符串处理程序、码制转换程序、子程序设计程序、常用DOS和BIOS功能调用程序、汇编语言常用伪指令。
4.1 分析执行下列指令序列后的结果:
1) MOV AX,1234H
MOV BX,00FFH
AND AX,BX
【答】(AX)=0034H
2) MOV AL,01010101B
AND AL,00011111B ;(AL)=00010101B
OR AL,11000000B ;(AL)=11010101B
XOR AL,00001111B ;(AL)=11011010B
NOT AL
【答】(AL)=00100101B
3) MOV DL,05H
MOV AX,0A00H
MOV DS,AX
MOV SI,0H
MOV CX,0FH
AGAIN: INC SI
CMP [SI],DL
LOOPNE AGAIN
HLT
本程序实现了什么功能?
【答】在以0A001H开始的15个单元中查找05H。
4) MOV AX,DSEGADDR
MOV DS, AX
MOV ES,AX
MOV SI, OFFSET B1ADDR
MOV DI,OFFSET B2ADDR
MOV CX,N
CLD
REP MOVSB
HLT
本程序实现了什么功能? N
【答】 将B1ADDR中N个字节数据传送到B2ADDR开始的 个存储单元 。
5) MOV AX, 0H
MOV DS,AX
MOV ES, AX
MOV AL,05H
MOV DI,0A000H
MOV CX,0FH
CLD
AGAIN: SCASB
LOOPNE AGAIN
HLT
本程序实现了什么功能?
【答】从地址0A000H开始的15个单元中查找字节型数据05H,用条件循环LOOPNZ,控制数据05H的查找。
4.2 阅读程序:
1). CLD
LEA DI,[0100H]
MOV CX, 0080H
XOR AX, AX
REP STOSW
本程序实现了什么功能?
【答】将DS中起始地址为0100H的128个字节单元清零。
2). MOV AL, 08H
SAL AL,01H ;(AL)=00010000H
MOV BL, AL
MOV CL ,02H
SAL AL,CL ;(AL)=01000000H
ADD AL,BL ;(AL)=01010000H
本程序实现了什么功能?
【答】 将AL中的内容乘以10。
4.3 试分析下列程序完成什么功能?
MOV DX,3F08H
MOV AH,0A2H
MOV CL,4
SHL DX,CL ;(DX)=F080H
MOV BL,AH
SHL BL,CL ;(BL)=20H
SHR BL,CL ;(BL)=02H
OR DL,BL ;(DL)=82H
【答】将DX中的低4位数据8H分离出来,将AH中的低4位数据2H分离出来,合并为82H存放在DL。
4.4 已知程序段如下:
MOV AX,1234H
MOV CL,4
ROL AX,CL
DEC AX
MOV CX,4
MUL CX
试问:(1)每条指令执行后,AX寄存器的内容是什么?(2)每条指令执行后,CF,SF及ZF的值分别是什么?(3)程序运行结束时,AX及DX寄存器的值为多少?
【答】 MOV AX,1234H ; (AX)=1234H, CF=SF=ZF=0
MOV CL,4
ROL AX,CL ; (AX)=2341H ,CF=1,SF=ZF=0
DEC AX ; (AX)=2340H, CF=1,SF=ZF=0
MOV CX,4 ; ;注意是十六进制乘法
MUL CX ;(AX)= 8D00H ,CF=ZF=0,SF=1,DX=0
4.5 试分析下列程序段:
ADD AX,BX
JNC L2
SUB AX,BX
JNC L3
JMP SHORTL5
如果AX、BX的内容给定如下:
AX BX
(1)14C6H 80DCH (程序转向 L2)
(2)B568H 54B7H (程序转向 SHORTL5 )
问该程序在上述情况下执行后,程序转向何处?
【答】 (1) 程序转向 L2。
(2) 程序转向 SHORTL5。
4.6 以下为某个数据段,试问各个变量分别占多少字节,该数据段共占多少字节?
DATA SEGMENT
VAR1 DW 9 ;2字节
VAR2 DD 10 DUP(?),2 ;44字节
VAR3 DB 2 DUP(?,10 DUP(?)) ;22字节
VAR4 DB ‘HOW ARE YOU' ;11字节
DATA ENDS
【答】该数据段共占79字节。
4.7 下列语句在存储器中分别为变量分配多少字节空间?并画出存储空间的分配图。
VAR1 DB 10,2 ;2字节
VAR2 DW 5DUP(?),0 ;12字节
VAR3 DB ‘HOW ARE YOU?',‘$' ;13字节
VAR4 DD -1,1,0 ; 12字节
Var1 |
Var2 |
Var3 |
Var4 |
10 |
? |
? 正序H |
FFH |
2 |
? |
U 才对O |
FFH |
|
? |
O W |
FFH |
|
? |
Y |
FFH |
|
? |
A |
01H |
|
? |
E R |
00H |
|
? |
R E |
00H |
|
? |
A |
00H |
|
? |
Y |
00H |
|
? |
W O |
00H |
|
0 |
O U |
00H |
|
0 |
H ? |
00H |
|
|
$ $ |
|
4.8 编写一段程序,比较两个5字节的字符串OLDS和NEWS,若相同,在RESULT置0,否则置0FFH。
【答】 参考程序:
OLDS DB 1,2,3,4,5
NEWS DB 1,2,3,4,5
RESULT DB ?
MOV SI,OFFSET OLDS
MOV DI,OFFSET NEWS
MOV CX,10
CLD
REP CMPSB
JNZ NOEQU ;串不相等转
MOV AL,0
JMP OUTPT
NOEQU: MOV AL,0FFH
OUTPT: MOV RESULT,AL
STOP: JMP STOP
4.9 编程求和Y=A1 + A2 + …. + A100 。其中Ai为字节变量。
【答】 参考程序:
DATA SEGMENT
TABLE DW 12,3,45,..
YAL DW ?
YAH DW ?
DATA ENDS
……….
MIAN PROC FAR
PUSH DS
MOV AX, 0
PUSH AX
MOV AX, DATA
MOV DS, AX
MOV DX,0
XOR AX, AX ;清AX
MOV BX, OFFSET TABLE
MOV CX, 4 ;100
CLC
LP: ADD AX, [BX] ;求和
JNC DON
INC DX
CLC
DON: INC BX
INC BX ;指向下一个数
LOOP LP ;未加完,继续
MOV YAL,AX ;存和
MOV YAH,DX
MAIN ENDP
CODE ENDS
END START
4.10 内存中以FIRST和SECOND开始的单元中分别存放着两个16位组合的十进制(BCD码)数,低位在前。编程序求这两个数的组合的十进制和,并存到以THIRD开始的单元。
【答】 参考程序:1325+9839=?
DATA SEGMENT
FIRST DB 05H,02H,03H,01H ;
SECOND DB 09H,03H, 08H,09H;
THIRD DB 20 DUP (?)
DATA ENDS
STACK SEGMENT
ST1 DB 100 DUP (‘SA’)
TOP1 EQU ST1 LENGTH ST1
STACK ENDS
CODE SEGMENT
ASUMME CS:CODE,DS:DATA,SS:STACK
MAIN PROC FAR
START: MOV AX, DAT ;初始化数据段
MOV DS, AX
MOV AX, STACK ;初始化堆栈段
MOV SS, AX
MOV AX, TOP1
MOV SP, AX
MOV CX, 4 ;计算4次
MOV BX, OFFSET DAT1 ;取数据地址
MOV SI , OFFSET DAT2 ;取数据地址
MOV DI , OFFSET SUM ;取结果地址
MOV AH, 00H ;将暂存标志的AH清0
DON1: MOV AL, [BX] ;取第一个数
SAHF ;将AH中的标志送标志寄存器
ADC AL, [DI] ;与第二个数带进位加
AAA ;十进制校正
LAHF ;将标志寄存器内容送AH
OR AL, 30H ;计算值拼成ASCII码
MOV [DI], AL ;存结果的ASCII码
INC BX ;指向第一个数的下一位
INC SI ;指向第二个数的下一位
INC DI ;指向结果单元的下一位
LOOP DON1 ;未计算完,继续
AND AH, 01H ;将最高位的进位标志送AH
OR AH, 30H ;最高位的进位位拼成ASCII码
MOV [DI], AH ;存结果的最高位
MOV AH, 02H ;调用DOS的02H功能显示
MOV CX, 05H ;显示数据的位数
DON2: MOV DL,[DI] ;显示数据送DL
INT 21H ;显示
DEC DI ;显示数据所在存储单元加一
LOOP DON2 ;未显示完,继续
MOV AH, 4CH ;返回DOS
INT 21H
RET
MAIN ENDP
CODE ENDS
END START
4.11 试编程序,统计由40000H开始的16K个单元中所存放的字符“A“的个数,并将结果存放在DX中。
【答】 参考程序
DATA SEGMENT
DATA1 DB 'DFASFAAAFDFAAFFFA'
COUNT EQU $-DATA1
DATA ENDS
STACK SEGMENT
STA DB 100 DUP (?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
BEGIN: MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV AX,TOP
MOV SP,AX
MOV CX,COUNT
MOV DX,0
LEA SI,DATA1
MOV BL,'A'
NEXT : CMP [SI],BL
JNZ OTHER
INC DX
OTHER: INC SI
LOOP NEXT
CODE ENDS
END BEGIN
4.12 统计数据块中正数与负数的个数,并将正数与负数分别送到两个缓冲区。
【答】 参考程序:
BLOCK DB -1,-3,5,6,-2,0,20,10
PLUS_D DB 8 DUP(?) ;正数缓冲区
MINUS_D DB 8 DUP(?) ;负数缓冲区
PLUS DB 0
MINUS DB 0
MOV SI,OFFSET BLOCK
MOV DI,OFFSET PLUS_D
MOV BX,OFFSET MINUS_D
MOV CX, 8 ;数据个数送CX
GOON: LODSB ;AL← [SI]
TEST AX, 80H
JNZ JMIUS ;为负数,转
INC PLUS ;正数个数加一
STOSB ;[DI] ←AL,传正数
JMP AGAIN
JMIUS: INC MINUS ;负数个数加一
XCHG BX, DI
STOSB ;送负数到缓冲区
XCHG BX, DI
AGAIN: DEC CX
JNZ GOON
4.13 编写一个子程序将AX中的十六进制数,转换成ASCII码, 存于ADR开始的四个单元中。
提示:1)、AX中的数从左到右,转换成ASCII码,用循环左移ROL和AND指令,把提出的一个十六进制数置BL中;
2)、0 ~ 9 的ASCII码:30 ~ 39H,A ~ F 的ASCII码:41H ~ 46H。
( 先把每个数加30H,判断是否为数字0 ~ 9?若是A ~ F,再加07H,得字母的ASCII码。)
【答】 参考程序:
DATA SEGMENT
ADR DB 4 DUP(?)
DATA ENDS
CODE SEGMENT
MAIN PROC FAR
ASSUME CS:CODE,DS:DATA
START: MOV AX,7EC3H ;假设ax中存放7ec3h
LEA SI,ADR
MOV DL,4
AGAIN:
MOV BX,AX
AND BX,000FH
ADD BL,30H
CMP BL,'9'
JG ADUST
JMP STORE
ADUST: ADD BL ,07H
STORE: MOV [SI],BL
INC SI
MOV CL,4
ROL AX,CL
DEC DL
JNZ AGAIN
MAIN ENDP
CODE ENDS
END START
4.14 编写一个子程序将AX中的2进制数,转换成10进制ASCII码, 存于ADR开始的五个单元中。
【答】参考程序:
BIN EQU 5555H;假设二进制数为5555H
DATA SEGMENT
ADR DB 4 DUP(?)
DATA ENDS
STACK SEGMENT
STA DB 100 DUP (?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START: MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV AX,TOP
MOV SP,AX
MOV AX,BIN
LEA BX,ADR
MOV CX,10000D
CALL BINTODEC
MOV CX,1000D
CALL BINTODEC
MOV CX,100D
CALL BINTODEC
MOV CX,10D
CALL BINTODEC
MOV CX,01D
CALL BINTODEC
MOV AX,04CH ;返回DOS
INT 21H
MAIN ENDP
;十进制转二进制,完成一位运算,十进制存于ax中,结果存于bx所指向的地址中
BINTODEC PROC NEAR
MOV DX,0
DIV CX
ADD AL,30H
MOV [BX],AL
MOV AX,DX
INC BX
RET
BINTODEC ENDP
CODE ENDS
END START
4.15 编写一个子程序,对AL中的数据进行偶校验,并将经过校验的结果放回AL中。
【答】参考程序:
JIAOYAN PROC FAR
MOV AL,1001110B
OR AL, AL
JNP NEXT
MOV AL,0
JMP DONE
NEXT: MOV AL,1
DONE: MOV AH,04CH
INT 21H
JIAOYAN ENDP
4.16 从2000H单元开始的区域,存放100个字节的字符串,其中有几个$符号(ASCII 码为24),找出第一个$符号,送AL中,地址送BX。
【答】参考程序:
SEARCH PROC FAR
MOV DI,2000H
MOV CX,100
MOV AL,24H
CLD
REPNZ SCASB
JNZ STOP
DEC DI
MOV BX,DI
MOV AL,[DI]
STOP: RET
SEARCH ENDP
4.17 用串操作指令实现:先将100H个数从2170H单元处搬到1000H单元处,然后从中检索等于AL中字符的单元,并将此单元换成空格字符。
【答】参考程序:
MOV AL,24H
MOV SI,2170H
MOV DI,1000H
MOV CX,100H
CLD
DO: REP MOVSB
MOV DI,1000H
MOV CX,100H
CLD
REPNZ SCASB
DEC DI
MOV [DI],20H
INC DI
CMP CX,0
JNZ DO
HLT
4.18 从60H个元素中寻找一个最大的值,并放到AL中,假设这60个元素放在DATA1开始的单元中。
【答】参考程序:
DATA SEGMENT
DATA1 DB 0,1,2,3,4,5,6,7,8,9 ;
DATA ENDS
STACK SEGMENT
STA DB 20 DUP (?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
START: MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV AX,TOP
MOV SP,AX
MOV CX,10
MOV AL,0
LEA BX,DATA1
AGAIN: CMP AL,[BX]
JGE NEXT ;大于等于转移
MOV AL,[BX]
NEXT : INC BX
LOOP AGAIN
MOV AH,4CH
INT 21H
CODE ENDS
END START
4.19 排序程序设计: 把表中元素按值的大小升序排列。要求显示排序前和排序后的数据。
【答】参考程序:
DATA SEGMENT
TAB DB '8095554'
N=$-TAB
OK DB 0DH,0AH,'OK!$'
DATA ENDS
STACK SEGMENT
STA DB 20 DUP(?)
TOP EQU LENGTH STA
STAC ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK
STAR: MOV AX,DATA
MOV DS,AX ;初始化数据段
MOV AX,STACK
MOV SS,AX
MOV AX,TOP
MOV SP,AX
CALL ARRAY
DO: MOV AH,4CH
INT 21H ;返回DOS
ARRAY PROC NEAR
PUSH AX
PUSH BX
PUSH CX
PUSH DX
MOV DL,N-1 ;置外循环次数
MOV DH,1 ;设有交换标志
XOR BX, BX
UPPER: OR DH,DH ;
JZ DISP ;无交换,已排好序,退出
MOV DH,0 ;无交换
MOV CX,N-1
SUB CX,BX ;CX=CX-I内循环次数
MOV SI,0 ;指向表首
INNER: MOV AL,TAB[SI] ;字符送AL
INC SI ;指向下个字符
CMP AL,TAB[SI] ;比较表中相邻字符
JBE DON ;小于
XCHG AL,TAB[SI] ;否则交换,大字符下
MOV TAB[SI-1],AL ;小字符上浮
MOV DH,1 ;有交换,DH=1
DON: LOOP INNER ;内循环结束?CX-1
INC BX ;一次内循环完成,加一
DEC DL ;外循环次数减一
CMP DL,0
JNZ UPPER ;外循环次数非零,继续
DISP: MOV DX,OFFSET TAB
MOV AH,09H
INT 21H ;显示排好序的字符
POP DX
POP CX
POP BX
POP AX
RET
ARRAY ENDP
CODE ENDS
END STAR
4.20 编写一段程序,接收从键盘输入的10个数,输入回车符表示结束,然后将这些数加密后存于BUFF缓冲区中。加密表为:输入数字: 0,1,2,3,4,5,6,7,8,9;密码数字:7,5,9,1,3,6,8,0,2,4。
【答】参考程序:
DATA SEGMENT
TABLE DB 7,5,9,1,3,6,8,0,2,4;密码表
BUFF DB 10 DUP(?) ,'$'存放转换数字的缓冲区
DATA ENDS
STACK SEGMENT
STA DB 20 DUP(?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT
MOV AX,STACK
MOV SS,AX
MOV DI , OFFSET BUFF
LEA BX , TABLE
MOV CX,0DH
RE1: MOV AH , 1 ;从键盘输入
INT 21H
CMP AL,0DH
JZ DONE
SUB AL,30H
XLAT
ADD AL,30H
MOV [DI] , AL
INC DI
LOOP RE1
DONE: MOV DX , OFFSET BUFF
MOV AH , 09H
INT 21H
MOV AH,4CH
INT 21H
CODE ENDS
4.21 编程序从键盘接收一个4位16进制数,转换为10进制数后,送显示。
【答】算法:先将输入的十六进制数保存到BX中,BX中的数范围在+32767~-32768之间,先检查BX中的符号位,以决定输出“+”还是“-”;若是负数,应先求补,得到原码后即可与正数作统一处理。转换方法为将被转换的二进制数先除;以10000,商即为万位数,再将余数除以1000,商为千位数,依此类推,求出百、十位数,剩的为个位数。最后,将各个数加上30H,即成为对应字符。
DATA SEGMENT
OUT_ASC_SUM db 6 dup(?),'$'
DATA ENDS
STACK SEGMENT
STA DB 20 DUP(?)
TOP EQU LENGTH STA
STACK ENDS
CODE SEGMENT
ASSUME CS :CODE,DS:DATA,SS:STACK
START: MOV AX,DATA
MOV DS,AX
MOV AX,STACK
MOV SS,AX
MOV AX,TOP
MOV SP,AX
MOV CX , 4 ;输入4次
MOV DX , CX ;转换4次
MOV BX , 0 ;用BX保存输入数
RE1: MOV AH , 1 ;从键盘输入
INT 21H
CALL ZH ;通过子程序转换
SHL BX , CL ;组合成十六进制数
ADD BL , AL
DEC DX
JNZ RE1 ;循环输入四个数
MOV AX,BX
MOV OUT_ASC_SUM , '+'
CMP AX , 0
JGE L4 ;不是负数,转移
NEG AX
MOV OUT_ASC_SUM , '-'
L4: CWD
MOV BX , 10000
DIV BX
ADD AL , 30H ;将万位转换为数字(商应在AX内,但因为商不大于9,所以有效部分在al内)
MOV OUT_ASC_SUM+1 , AL ;保存万位数字
MOV AX , DX ;将余数置入AX内,以便当作被除数
CWD
MOV BX , 1000
DIV BX
ADD AL , 30H
MOV OUT_ASC_SUM+2 , AL ;保存千位数字
MOV AX , DX ;将余数置入AX内,以便当作被除数
MOV BL , 100
DIV BL
ADD AL , 30H
MOV OUT_ASC_SUM+3 , AL ;保存百位数字
MOV AL , AH
CBW
MOV BL , 10
DIV BL
ADD AL , 30H
MOV OUT_ASC_SUM+4 , AL ;保存十位数字
ADD AH , 30H
MOV OUT_ASC_SUM+5 , AH ;保存个位数字
MOV DX , OFFSET OUT_ASC_SUM
MOV AH , 09H
INT 21H
MOV AH,4CH
INT 21H
ZH PROC
CMP AL , '9' ;将ASCII码转换为16进制
JBE A2 ;键入值≤’9’(’0’-‘9’)则减30H
CMP AL, 'a' ;键入值<’a’(‘A’-‘F’) 则减37H
JB A1
SUB AL , 20H ;值在’a’ -‘f’则先减20H,再减37H
A1: SUB AL , 7
A2: SUB AL , 30H
RET
ZH ENDP
CODE ENDS
END START
习题七 定时器/计数器8253
7.1 定时和计数有哪几种实现方法?各有什么特点?
【答】软件定时: 利用CPU执行某一指令需要一定机器周期的原理,在软件编程时循环执行一段指令,从而产生累积的定时。优点是不需要增加硬件。缺点是耗费CPU资源,故软件定时只适用于短时定时。而且,不同CPU的时钟频率不同,同一段软件延时程序在不同的机器上运行,可能结果不同,即兼容性不强。
硬件定时和计数:以硬件计数器构成,计数脉冲触发硬件计数器计数,如果计数脉冲的周期固定,则计数同时产生定时。优点是不占用CPU资源,定时精确,定时范围大。缺点是增加一些硬件开销。
7.2 试说明定时器/计数器芯片Intel 8253的内部结构。
【答】它由与CPU的接口、一个控制寄存器以及三个16位计数器所组成。每个计数器通过3个引腿和外部联系,1个为时钟输入端CLK,1个为门控信号输入端GATE,别1个为输出端OUT。
7.3 设8253计数器0—2和控制字的I/O地址依次为F8H~FBH,说明如下程序的作用。
MOV AL, 33H
OUT 0FBH,AL
MOV AL,80H
OUT 0F8H,AL
MOV AL,50H
OUT 0F8H,AL
【答】写入控制字后,输出端OUT即以高电平作为起始电平,门控信号GATE上升沿到来时,边沿触发器受到触发,下一个时钟脉冲时,输出端OUT变为低电平,并在计数到达0以前一直维持低电平,如果中间又来一个门控触发信号,按新的50H计数值作减1计数。
MOV AL,33H ;写控制字,定义计数器0为模式1,计数值为四位BCD码
OUT 0FBH,AL
MOV AL,80H ;写低位计数值80
OUT 0F8H,AL
MOV AL,50H ;写高位计数值50
OUT 0F8H,AL
7.4 8253每个计数通道与外设接口有哪些信号线,每个信号的用途是什么?
【答】 CLK 计数器的时钟输入
GATE 计数器的门脉冲控制输入
OUT 计数器的输出
7.5 定时 /计数器芯片Intel 8253占用几个端口地址?各个端口分别对应什么?
【答】4个端口地址:片内选址为00对应计数器0,片内选址为01对应计数器1,片内选址为10对应计数器2,片内选址为11对应控制寄存器。
7.6 填空:8253每个通道有 6 种工作方式可供选择。若设定某通道为方式0后,其输出引脚为 低 电平;当通道开始计数,信号端每来一个脉冲就减1;当 减到0,则输出引脚输出 高 电平,表示计数结束。8253的CLK0接1.5MHZ的时钟,欲使OUT0产生频率为300kHZ的方波信号,则8253的计数值应为__5__,应选用的工作方式是 3 。
n=1500000/300000=5
7.7 试按如下要求分别编写 8253的初始化程序,已知 8253的计数器0~ 2和控制字I/O地址依次为04H~07H。
(l)使计数器 1工作在方式0,仅用 8位二进制计数,计数初值为 128。
【答】 MOV AL,01010000B ;50H P174
OUT 07H,AL
MOV AL,128
OUT 05H,AL
(2)使计数器 0工作在方式 1,按 BCD码计数,计数值为 3000。
【答】 MOV AL,00110011B 33H
OUT 07H,AL
MOV AX,3000 ; H
OUT 04H,AL
MOV AL,AH
OUT 04H,AL
(3)使计数器2工 在方式 2,计数值为 02F0H。
【答】 MOV AL,10110100B
OUT 07H,AL
MOV AX,02F0H
OUT 06H,AL
MOV AL,AH
OUT 06H,AL
7.8 设一个8253的计数器0产生20ms的定时信号,试对它进行初始化编程。
【答】设外部时钟频率为f=2MHZ, n = 20ms*2M/1s = 40k
MOV AL,00110100B
OUT CONTROL,AL
MOV AX,40000
OUT PORT0,AL
MOV AL,AH
OUT PORT0,AL
7.9 让一个计数器3工作在单稳态方式,让它产生脉冲宽度为15ms(设输入频率为2MHz)。
【答】
MOV AL,11110010B
OUT CONTROL,AL
MOV AX,30000
OUT PORT3,AL
MOV AL,AH
OUT PORT3,AL
7.10 请把一个8253与8086CPU相连,地址为2FF0~2FF3H。
【答】8086 的IO/M和高位地址A19~A2经过译码器输出(IO/M=1,A19~A2=00101111111100时输出有效)连接8253的CS,低位地址A1、A0接8253的A1、A0, RD、WR接8253的RD、WR。AD7~AD0接8253的D7~D0。
7.11 某系统中 8253芯片的通道0~2和控制端口地址分别为330H~333H。定义通道0工作在方式2,CLK 0 =2MHz,要求输出OUT 0 为1kHz的速率波;定义通道l CLK l 输入外部计数事件,每计满100个向CPU发出中断请求。试写出8253通道0和通道1的初始化程序。
【答】 MOV DX,333H
MOV AL,00100101B
OUT DX,AL ;计数器0方式设置
MOV DX,330H
MOV AL,20H
OUT DX,AL ;计数器0分频系数为2000
MOV DX,333H
MOV AL,01010100B
OUT DX,AL ;计数器1方式设置
MOV DX,331H
MOV AL,100
OUT DX,AL ;计数器1的计数值为100
7.12 为了用8253测量一个事件的持续时间长短,一般都将事件的持续时间转换成一定的脉冲宽度,试设计测量此脉冲宽度时间的硬件电路和初始化编程。
【答】8253计数器0作为计数器,8255PC1作为计数器输出,8255PC0作为事件脉冲输入,通过查询事件脉冲控制计数器计数。内存字单元COUH和COUL存计数值,乘以CLK0的周期就是事件的长度。
COUH DW 0
COUL DW 0
MOV AL,10000001B
OUT 63H,AL ;8255方式设置
MOV 00010000B
OUT 43H,AL ;8253方式设置
L1: IN AL,62H ;查询事件脉冲是否到来
TEST AL,01H
JZ L1 ;事件脉冲未到,继续查询
MOV AL,0 ;事件脉冲到来,启动8253计数器0定时
OUT 40H,AL
L2: IN AL,62H ;查询事件脉冲是否结束
TEST AL,01H
JZ STOP ;事件脉冲结束
TEST AL,02H ;查询8253计数器0定时
JZ L2 ;8253计数器0定时未到,继续查询事件脉冲
INC COUH ;8253计数器0定时到,计数单元高位字加1
MOV AL,0 ;再启动8253计数器0定时
OUT 40H
JMP L2 ;继续查询事件脉冲
STOP: MOV AL,00000000B
OUT 43H,AL
;事件脉冲结束,锁存8253计数器0的当前计数器值
IN AL,40H ;读8253计数器0的当前计数低字节
MOV AH,AL
IN AL,40H ;读8253计数器0的当前计数高字节
XCHG AH,AL
NEG AX ;获得计数单元低位字
MOV COUL,AX
7.13 利用8253的记时功能,结合软件方法设计一个能记秒,分,小时的时钟。
【答】根据8253计数器2输入系统时钟为1.19MHz,分频输出为100Hz的连续脉冲,引发中断。
COU DB 0 ;0.01秒计数单元
SEC DB 0 ;秒计数单元
MIN DB 0 ;分计数单元
HOU DB 0 ;小时计数单元
INIT: MOV AX,0 ;设置计数中断的中断向量
MOV DS,AX
MOV [54H*4],OFFSET INT54
MOV [54H*4+2],SEG INT54
STI
MOV AL,10110100B
OUT 43H,AL ;8253计数器2方式设置
MOV AX,11900
OUT 42H,AL ;写计数值低位
MOV AL,AH
OUT 42H,AL ;写计数值高位
INT54: STI ;每0.01秒进入中断服务子程序
INC COU ; 0.01秒计数单元加1
CMP COU,100 ;判断是否到1秒
JNZ TORET
MOV COU,0
INC SEC
CMP SEC,60 ;判断是否到1分
JNE TORET
MOV SEC,0
INC MIN
CMP MIN,60 ;判断是否到1小时
JNE TORET
MOV MIN,0
INC HOU
CMP HOU,24 ;判断是否到1天
JNE TORET
MOV HOU,0
TORET: IRET
答案虽经梳理完善,但仍难免有错,仅供参考,请以课堂讲解为准