微型计算机课后答案(第四章)
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
微型计算机课后答案(第四章)
(四)习题四解答
1.什么是汇编语言?它和机器语言及高级语言有何区别?
答:计算机程序设计语言分为三个层次:机器语言,汇编语言和高级语言。
机器语言是用0和1的二进制串表示机器指令代码的语言。
不同的CPU,机器语言是不同的。
由于机器语言指令很难记,程序员用机器语言只在计算机诞生的早期出现过。
汇编语言用一些助记符来代替机器语言指令代码,与机器语言指令代码是一一对应的,因此也是面向机器的。
助记符是帮助人们记忆的符号,方便程序员进行编程。
汇编语言程序设计一般用于对硬件的控制,编程效率较低,但设计出的程序工作效率较高。
高级语言接近自然语言,容易学习,编程效率较高。
2.汇编语言程序一般包括了哪些段?如何定义这些段?
答:8086汇编源程序中可以定义四种段,即:数据段、附加段、堆栈段和代码段。
每种段都可以定义一个或多个。
其中数据段、附加段用来定义数据、分配存储单元,堆栈段专门用于保存参数、断点等信息,代码段则用来存放指令。
当程序需要设置一个段的时候,就必须首先使用段定义伪指令。
它的格式为
段名SEGMENT [定位类型][组合类型][‘类别名’]
(语句)…;程序和数据
段名ENDS
每个段都以SEGMENT伪指令开始,以ENDS伪指令结束。
3.什么是伪指令?它和指令有何区别?
答:伪指令语句是用于指示汇编程序如何汇编源程序,例如源程序中的伪指令语句告诉汇编程序:该源程序如何分段,有哪些逻辑段在程序段中哪些是当前段,它们分别由哪个段寄存器指向;定义了哪些数据,存储单元是如何分配的等等。
伪指令语句除定义的具体数据要生成目标代码外,其他均没有对应的目标代码。
伪指令语句的这些命令功能是由汇编程序在汇编源程序时,通过执行一段程序来完成的,而不是在运行目标程序时实现的。
伪指令是对汇编起某种控制作用的特殊命令,其格式与通常的操作指令一样,并可加在汇编程序的任何地方,但它们并不产生机器指令。
4.判断以下说法是否正确,如有错,请说明原因并改正。
(1)伪指令在汇编过程中不会产生二进制代码。
(2)宏和过程的相同之处是都可用于简化源程序书写、精简目标代码。
(3)在计算机中,高级语言通常需要转换为汇编语言后才能执行。
(4)汇编语言程序上机一般包括编辑、汇编、链接和调试几个步骤。
答:(1)正确。
(2)错误。
宏不能精简目标代码。
(3)错误。
高级语言程序经编译或解释后直接转换为目标代码。
(4)正确。
5.若数据段中有定义
NUM1 EQU 23H
NUM2 DW 0
则指令MOV NUM2,NUM1 的源、目操作数的寻址方式以及指令执行后NUM2+1单元的内容分别是什么?
答:指令MOV NUM2,NUM1的源操作数使用立即数寻址,目的操作数使用直接寻址。
指令执行后NUM2+1单元的内容是0。
6.设DS=6000H,BX=8432H,SS=5000H,SP=3258H,内存69632H~69635H单元的内容依次是00H、11H、22H、33H。
4字节指令CALL DWORD PTR [BX+1200H] 本身位于2000H:3250H处的双字单元中。
当8086执行该指令后转移至子程序入口时,CS、IP、SS、SP各寄存器以及栈顶2个字单元的内容分别是多少?
答:执行结果为CS=3322H,IP=1100H,SS=5000H,SP=3254H,栈顶的两个字即断点地址,为2000H:3254H。
7.已知某数据段从物理地址03000H处开始,定义如下:
DSEG SEGMENT
ORG 2000H
A1 DD 2 DUP(7,1,?)
A2 DB 10 DUP(0,4,3 DUP(2),5)
CNT EQU 20H
A3 DW 100 DUP(?)
DSEG ENDS
请分别用分析运算符SEG、OFFSET、LENGTH、SIZE、TYPE求出
A1、A2、A3的段基址、偏移量、类型及它们的LENGTH、SIZE。
答:(SEG A1)=0300H,(OFFSET A1)=2000H,(TYPE A1)=4,
(LENGTH A1)=2,(SIZE A1)=2×4=8;
(SEG A2)=0300H,(OFFSET A2)=2018H,(TYPE A2)=1,
(LENGTH A2)=10,(SIZE A2)=10×1=60;
(SEG A3)=0300H,(OFFSET A3)=2054H,(TYPE A3)=2,
(LENGTH A3)=100,(SIZE A3)=100×2=200
8.阅读下面的程序,回答问题
DA TA SEGMENT
BUF DB '1234'
N=$-BUF
BCD DB N DUP(?)
DA TA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DA TA
START:MOV AX,DA TA
MOV DS,AX
LEA SI,BUF
MOV CX,N
LEA DI,BCD+N-1
LOOP1:MOV AL,[SI]
SUB AL,30H
MOV [DI],AL
INC SI
DEC DI
DEC CX
JNE LOOP1
MOV AH,4CH
INT 21H
CODE ENDS
END START
(1)画出内存分配图。
(2)说明程序功能,程序执行后,从BCD开始的N个字节单元中的内容是什么?
(3)找出一条指令代替指令“SUB AL,30H”,使程序功能不变。
(4)如果将代码段中的指令LEA DI,BCD+N-1改成LEA DI,BCD;DEC DI改成INC DI,其它指令不变,程序执行后,从BCD开始的N个字节单元中的内容是什么?
(5)取消数据段的BCD存储区,将处理后的数据放回原处,应如何修改程序?
答:(1)
变量值EA
BUF→31H 0
32H 1
33H 2
34H 3
BCD→-- 4
-- 5
-- 6
- 7
(2)程序功能是将从BUF开始的连续4个字符'1234'转变为4个对应的数值,按逆序存放到以变量BCD为首地址的存储单元中。
程序执行后,从BCD开始的N个字节单元中的内容是4 3 2 1。
(3)用指令“AND AL,0FH”代替指令“SUB AL,30H”,程序功能不变。
(4)如果将代码段中的指令LEA DI,BCD+N-1改成LEA DI,BCD;DEC DI改成INC DI,其它指令不变,程序执行后,从BCD开始的N个字节单元中的内容是1 2 3 4。
(5)取消数据段的BCD存储区,将经处理后的数据放回原处,修改程序如下
DATA SEGMENT
BUF DB '1234'
N=$-BUF
DATA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA
START:MOV AX,DATA
MOV DS,AX
LEA SI,BUF
MOV CX,N
下面的程序段中有2LOOP1:MOV AL,[SI]
SUB AL,30H MOV [SI],AL
INC SI DEC CX JNE LOOP1 MOV AH,4CH INT 21H
CODE ENDS
END START
9. 条转移指令,计算它们的相对位移量并填在空缺的机器代码处。
1000:001B F3A6 REPZ CMPSB 1000:001D 75 01 JNZ 0020 1000:001F CB SAME : R ET 1000:0020 41 FOUND :INC CX
1000:0021 890E0600 MOV [0006],CX
1000:0025
EB F8
JMP
001F
答:两处空缺的机器码分别为01H 、0F8H 。
简析:
JNZ 指令采用相对寻址方式,本题程序中JNZ 的目标地址是同一段中偏移量为0020H 处,当前IP=001FH ,故有:相对偏移量=目标地址-当前IP 值=01H 。
JMP 指令有多种寻址方式,本题程序中的JMP 为段内直接跳转,也采用相对寻址方式。
因当前IP=0027H ,目标地址为001FH ,因此有:相对偏移量=目标地址-当前IP 值=0F8H (-8的补码)。
10. 阅读下面的程序,填空。
从BUF 开始的11个单元中存放着11个整数,找出这11个数中正数并且是偶数的个数存入R 中。
DA TA SEGMENT BUF DB –2,5,-3,6,100,0,-20,-9,8,-110,21 N= ① R DW ? DA TA ENDS
CODE SEGMENT ② BEGIN :MOV AX ,DA TA ③
LEA BX ,BUF
MOV CX ,N
④
LOPA : CMP [BX],BYTE PTR 0 ⑤
TEST [BX],BYTE PTR 1
⑥
变量
值 EA BUF → 31H 0 32H 1 33H 2 34H 3 BCD →
1 4
2 5
3 6 4
7
INC AX
NEXT :INC BX
DEC CX
⑦
MOV R,AX
MOV AH,4CH
INT 21H
CODE ENDS
END ⑧
答:
①$-BUF
②ASSUME CS:CODE,DS:DA TA
③MOV DS,AX
④MOV AX,0
⑤JLE NEXT
⑥JNZ NEXT
⑦JNZ LOPA
⑧BEGIN
11.读下面程序,在其中的空处添上适当内容。
该程序完成了什么功能?程序运行后,变量RS的值是多少?
DA TA SEGMENT
BUF DB -13,24,5,-62,77,20,-7,145,0
CNT DB $ -BUF
RS DB 0
DA TA ENDS
STACK SEGMENT PARA STACK‘STACK’
DB 256 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME DS:DA TA,SS:STACK,CS:CODE
START PROC FAR
PUSH DS
MOV AX,0
PUSH AX
MOV AX,DA TA
MOV DS,AX
LEA BX,BUF
MOV CH,0
MOV CL,
LP:MOV AL,[BX]
TEST AL,80H
JE CONT
INC RS
CONT:INC BX
LOOP LP
RET
START ENDP
CODE ENDS
END START
答:程序空处可填CNT,字节变量RS的最后结果是04H。
该程序实现的功能是:统计数据段中以BUF为首址的带符号字节数据表中负数的个数,CNT为表中所有数据的个数,即表的长度。
需要注意的是:十进制数据“145”在以二进制带符号字节数据形式存放时相当于“-111”。
12.已知在BUF的起始处保存有N个字符的ASCII码,编写汇编语言程序实现,将这组字符串传送到缓冲区BUFR中,并且使字符串的顺序与原来的顺序相反。
答:要传送的字符串有30个。
N=30
STACK SEGMENT STACK 'STACK'
DW 100H DUP(?)
TOP LABEL WORD
STACK ENDS
DA TA SEGMENT
ASC1 DB 'abcdefghijklmnopqrstuvwxyz1234'
ASC2 DB 30 DUP(?)
DA TA ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DA TA,ES:DA TA,SS:STACK
START:
MOV AX, DA TA
MOV DS, AX
MOV ES, AX
MOV AX, STACK
MOV SS, AX
LEA SP, TOP
MOV CX, N
LEA SI, ASC1
ADD SI, CX
LEA DI, ASC2
L1: DEC SI
MOV AL, [SI]
MOV [DI], AL
INC DI
LOOP L1
MOV AH, 4CH ;返回DOS
MOV AL, 0
INT 21H
CODE ENDS
END START
13.编写一个完整的源程序,将数据35、-27、-13、6、-47、52、9、-3中的正数放入以BUFFER为首址的数据缓冲区中。
答:一种可能的程序如下实现:
DATA SEGMENT
BLOCK DB 35,-27,-13,6,-47,52,9,-3
COUNT EQU $-BLOCK
BUFFER DB COUNT DUP(?)
DATA ENDS
STACK SEGMENT PARA STACK‘STACK’
DW 40 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,ES:DATA,SS:STACK
BEGIN:MOV AX,DATA
MOV DS,AX
MOV ES,AX ;需用STOS串操作指令
MOV CX,COUNT
LEA SI,BLOCK ;源数据区指针
LEA DI,BUFFER ;正数存放区指针
CLD ;自动增量
AGAIN:LODSB ;取源数据,并修改SI
TEST AL,80H ;取符号位,不影响AL
JS GO ;符号位=1,是负数,不存
STOSB ;存正数并修改DI
GO:LOOP AGAIN
MOV AH,4CH ;退出循环,返回DOS
INT 21H
CODE ENDS
END BEGIN
14.已知有一个长100个字的数据块,存放在以3DA0H:1000H开始的存储区域内。
试编写一个完整的汇编语言程序,将该数据块复制到以3DA0H:1008H开始的存储区内。
答:一种可能的程序如下实现:
DATA SEGMENT AT 3DA0H
ORG 1000H
BLOCK DW 104 DUP(?)
DATA ENDS
SSEG SEGMENT PARA STACK‘SSEG’
DB 100 DUP(?)
SSEG ENDS
CODE SEGMENT
ASSUME CS:CODE,SS:SSEG,DS:DATA,ES:DATA
MAIN PROC FAR
PUSH DS
MOV AX,0
PUSH AX
MOV AX,SEG BLOCK
MOV DS,AX
MOV ES,AX
MOV CX,200 ;重复次数
LEA SI,BLOCK
ADD SI,199 ;SI=10C7H
MOV DI,SI
ADD DI,8 ;DI=10CFH
STD ;自动减量
REP MOVSB
RET
MAIN ENDP
CODE ENDS
END MAIN
简析:
由题意可知,源数据区(占用地址3DA0:1000H~3DA0:10C7H,共200个字节)与目标数据区(占用地址3DA0:1008H~3DA0:10CFH,共200个字节)是重叠的。
若从首址开始增量传送(D F=0),将破坏1008H以后的源数据,所以必须从末址向首址减量传送(D F=1)。
数据段初始化时,有以下几点需注意:段基址规定为3DA0H,故应在段定义伪指令SEGMENT后加上A T语句;源数据区首址的偏移量规定为1000H,故应使用ORG 语句指明;对源、目标数据区进行定义时,应注意目标数据区首址的偏移量是1008H。
如果定义为:
ORG 1000H
SOUR DW 100 DUP(?);源数据区
DEST DW 100 DUP(?);目标数据区
则目标数据区首址的偏移量实际上是10C8H,不合题意。
可将它们统一定义为足够长度(至少104字或208字节)的变量,如参考程序所示。
指针初始化时,可以将SI、DI分别置为10C7H、10CFH,且CX=200,即进行字节的传送,使用MOVSB;亦可将SI、DI分别置为10C6H、10CEH,且CX=100,即进行字的传送,相应使用MOVSW。
15.编写一个在某项比赛中计算每一位选手最终得分的程序。
计分方法如下:
①10名评委,在0~10的整数范围内给选手打分。
②10个得分中,除去一个最高分(如有同样两个以上最高分也只除一个),除去一个最低分(如有同样两个以上最低分也只除一个),剩下的8个得分取平均值为该选手的最终得分。
答:一种可能的程序如下实现:
DA TA SEGMENT
SCORE DB 7,8,9,8,10,10,9,8,7,10
N=$-SCORE
A VERAGE D
B ?
MAX DB ?
MIN DB ?
DA TA ENDS
CODE SEGMENT 'CODE'
ASSUME CS:CODE,DS:DA TA
START: MOV AX,DA TA
MOV DS,AX
MOV DL,SCORE
MOV MAX,DL
MOV MIN,DL
MOV CX,N-1
MOV BX,1
CYCLE: MOV AL,SCORE[BX]
ADD DL,AL
CMP AL,MAX
JLE CMPMIN
MOV MAX,AL
CMPMIN: CMP AL,MIN
JGE NEXT
MOV MIN,AL
NEXT: INC BX
LOOP CYCLE
SUB DL,MAX
SUB DL,MIN
MOV CL,3
SAR DL,CL
MOV A VERAGE,DL
MOV AH,4CH
INT 21H
CODE ENDS
END START
16.有一个长度不超过100字节的字符串,以回车符结尾。
编程统计其中非空格的字符个数,并将统计结果以自拟格式显示在CRT上。
答:一种可能的程序如下实现:
DATA SEGMENT
STR DB ‘It’’s a fine day, isn’’t it?’,0DH,‘$’
;依题意以0DH为结束符。
加上“$”便于显示整个字符串
COUNT EQU $-STR-2 ;串长中不包括结束符和“$”符号
NUM DB 0 ;置统计结果初值为0
STR1 DB ‘The number of non-space charactors is’,‘$’
DATA ENDS
STACK SEGMENT PARA STACK‘STACK’
DB 100 DUP(?)
STACK ENDS
CODE SEGMENT
ASSUME CS:CODE,SS:STACK,DS:DATA,ES:DATA START:MOV AX,DATA
MOV DS,AX
MOV ES,AX ;有SCAS指令,需用ES
LEA DI,STR
CLD
MOV AL,20H ;关键字符(空格)
MOV CX,COUNT
NEXT:SCASB
JE SKIP ;是空格,跳过下一句
INC NUM ;非空格字符,NUM加1 SKIP:LOOP NEXT
LEA DX,STR ;显示原字符串
MOV AH,09H
INT 21H
MOV DL,0AH ;显示换行符,以便显示另一字串
MOV AH,2
INT 21H
LEA DX,STR1 ;显示另一个字符串
MOV AH,9
INT 21H
;将16进制的统计结果转换为十进制数,再转换为两个ASCII码输出MOV AL,NUM
MOV AH,0 ;AX中为待转换16进制数
MOV BL,10
DIV BL ;AX / BL
;商(十位)在AL中,余数(个位)在AH中,均为未组合BCD码
PUSH AX ;入栈保护
OR AL,30H ;将十位数转换为ASCII码
MOV DL,AL ;送CRT显示
MOV AH,2
INT 21H
POP AX ;恢复除法运算的结果
ADD AH,30H ;将个位数转换为ASCII码
MOV DL,AH ;显示
MOV AH,2
INT 21H
MOV AH,4CH ;完成,返回DOS
INT 21H
CODE ENDS
END START
简析:
本题的关键在于统计结果的显示。
统计完成后,结果单元中是一个16进制数。
为符合一般习惯,应在CRT上显示十进制数,因此首先用除法将十位、个位分离开,再将其分别转换为ASCII码输出。
由于除数是10,故相除之后得到的商(十位数)和余数(个位数)必在0~9范围内,即未组合BCD码,所以很容易转换为ASCII码。
编程时注意:DIV指令执行后结果在AX中,而DOS功能调用必须用AH为调用号,故应保护AX的内容。
另外,原题已告知字串的结束符是0DH,故亦可通过检索结束符(0DH)的方式控制循环。
另外请注意:数据段中定义的STR串中出现的单引号前必须用另一个单引号转义,如“’s”应为“’’s”。
17.数据段中有1个由小写英文字母组成的字符串,编程将各小写字母转换成对应的大写字母,并存放起来。
答:一种可能的程序如下实现:
DSEG SEGMENT
STR1 DB ‘djdwpneasmv’,‘$’
COUNT EQU $-STR1-1
CHAR DB 0AH,0DH
STR2 DB COUNT DUP(?),‘$’
DSEG ENDS
SSEG SEGMENT PARA STACK‘SSEG’
DW 100 DUP(?)
SSEG ENDS
CSEG SEGMENT
ASSUME CS:CSEG,SS:SSEG,DS:DSEG,ES:DSEG
TRAN PROC FAR
PUSH DS
SUB AX,AX
PUSH AX
MOV AX,DSEG
MOV DS,AX
MOV ES,AX ;有STOS指令,需用ES
LEA DX,STR1 ;显示小写字母串
MOV AH,9
INT 21H
CLD ;自动增量
LEA SI,STR1 ;SI指向小写字母串
LEA DI,STR2 ;DI指向结果存放处
MOV CX,COUNT;转换次数
NEXT:LODSB ;取1个小写字母至AL中
SUB AL,‘a’;转换为大写字母
ADD AL,‘A’
STOSB ;存放
LOOP NEXT
MOV DX,OFFSET CHAR ;换行显示大写字母串
MOV AH,9
INT 21H
RET
TRAN ENDP
CSEG ENDS
END TRAN
18.从内存单元BUF开始的缓冲区中有7个8位无符号数,依次为13H、0D8H、92H、2AH、66H、0E0H、3FH。
编程找出它们的中间值并放入RES单元,且将结果以“(RES) = ?”的格式显示在屏幕上。
答:一种可能的程序如下实现:
DATA SEGMENT
BUF DB 13H,0D8H,92H,2AH,66H,0E0H,3FH
RES DB ?;中间数的存放单元
STR DB ‘(RES)=’
STR1 DB ?,?,‘$’;结果字符串
DATA ENDS
SSEG SEGMENT PARA STACK‘SSEG’
DB 100 DUP(?)
SSEG ENDS
CODE SEGMENT
ASSUME CS:CODE,SS:SSEG,DS:DATA,ES:DATA
MAIN PROC FAR ;主程序
PUSH DS
XOR AX,AX
PUSH AX
MOV AX,DATA
MOV DS,AX
MOV ES,AX ;有STOS指令,需用ES
MOV CX,6 ;外循环次数,比6次
AGN:MOV SI,OFFSET BUF
MOV DI,SI+1 ;SI、DI指向相邻2数
MOV DX,6 ;内循环次数,比6次
AGN1:MOV AL,[SI]
CMP AL,[DI] ;两个无符号数相比较
JB UNCH ;小于则转,不互换
EXCH:XCHG AL,[ DI ] ;前1单元较大,则互换
MOV [ SI ],AL ;大数放在后面
UNCH:INC SI ;修改指针,指向下一个数
INC DI
DEC DX
JNZ AGN1 ;未处理完,继续内循环
LOOP AGN ;外循环
DONE:MOV AL,[SI-3] ;排序完成,取中间数
MOV RES,AL
AND AL,0F0H ;分离高半字节
MOV CL,4
SHR AL,CL
CALL BATR ;调子程序,将AL值转换为ASCII码
LEA DI,STR1 ;DI指向结果单元
CLD
STOSB ;存放转换结果
MOV AL,RES
AND AL,0FH ;分离并转换低半字节
CALL BATR
STOSB
LEA DX,STR ;显示整个字符串
MOV AH,09H
INT 21H
RET
MAIN ENDP ;主程序MAIN结束
;子程序BATR,实现16进制数到ASCII码的转换
BATR PROC FAR
CMP AL,10 ;入口参数为AL
JB NUM ;是数字,则转NUM
ADD AL,’A’-10-’0’;字母
NUM:ADD AL,’0’
RET
BATR ENDP ;子程序结束
CODE ENDS
END MAIN
简析:
本题的基本思路是:先把7个无符号数按大小排序,排序完成之后取位于中间的一个数即为中间值。
然后将该16进制数转换为两个对应的ASCII码,再与要求的格式字符一起输出送显即可。
数据排序可以是从大到小、或从小到大排列,本参考程序完成从小到大排序,由一个双重循环结构实现。
内循环完成一个数与其它数之间的一一比较,并使每次比较所得的小数置于低地址单元。
外循环实现所有数之间的两两相较。
共7个数据,故内、外循环中的比较次数均为6次。
编程时需注意:无符号数比较大小应使用JA、JB、JAE、JBE指令,本题完成从小到大的排列,故用JB控制转移到UNCH;若要从大到小排列,则用JA代替JB即可。
对两个循环体进行初始化时,需仔细考虑指针和循环控制寄存器的初值。
在数据段的定义中,分别定义STR、STR1两个变量名字,是为了便于在STR1处存放转换结果;显
示时使DX直接指向STR,以STR1末尾的“$”为结束符。
中间值找出之后,应把高、低半字节相分离,并分别转换为各所对应的ASCII码。