汇编语言王爽第二版课后答案.docx
《汇编语言王爽第二版课后答案.docx》由会员分享,可在线阅读,更多相关《汇编语言王爽第二版课后答案.docx(35页珍藏版)》请在冰豆网上搜索。
汇编语言王爽第二版课后答案
第一章基础知识
检测点1.1(第8页)
⑴13
(2)1024,0,1023
(3)8192,1024
(4)2A30,2A20,2A10
(5)64,1,16,4
(6)1,1,2,2,4
⑺512,256
(8)二进制
注意:
1.第4题中的符号'A'指求籍运算(如:
2A30指2的
30次方)
第二章寄存器(CPU工作原理)
检测点2.1(第18页)
(1)写出每条汇编指令执行后相关寄存器中的值。
第一空:
F4A3H
第二空:
31A3H
第三空:
3123H
第四空:
6246H
第五空:
826CH
第六空:
6246H
第七空:
826CH
第八空:
04D8H
第九空:
0482H
第十空:
6C82H
第^一空:
D882H
第十二空:
D888H
第十三空:
D810H
第十四空:
6246H
⑵只能使用目前学过的汇编指令,最多使用4条
指令,编程计算2的4次方。
解答如下:
movax,2
addax,ax
addax,ax
addax,ax
检测点2.2(第23页)
(1)00010H,1000FH
⑵1001H,2000H
第2题说明:
因为段的起始地址要为16的倍数。
所以当段地址小于1001H或大于2000H时CPU^K无法寻到。
检测点2.3(第33页)
答:
CPU修改了4次IP的值。
情况如下:
第1次:
执行完movax,bx后
第2次:
执行完subax,ax后
第3次:
读入jmpax后
第4次:
执行完jmpax后
最后IP的值为0
实验1查看CPU和存,用机器指令和汇编指令编程(第33页)
1.预备知识:
Debug的使用
<此部分略>
2.实验任务(第43页)
(1)
<此部分略>
⑵
<此部分略>
⑶
通过DEBUC^的D命令查看到主板的生产日期[以月、日、年,分隔符为'/'的格式]存储在存ffff:
0005〜ffff:
000C(共8个字节单元中)处。
此
生产日期不能被改变,因为其具有’只读’属性。
⑷
通过向存中的显存写入数据,使计算机根据写入的数据进行ASCII转换,并将转换后且可打印的字符输出到屏幕上。
点i:
关于显存的详细讨论不在此题围>
第三章寄存器(存访问)
检测点3.1(第52页)
(1)(题目:
略)
第一空:
2662H
第二空:
E626H
第三空:
E626H
第四空:
2662H
第五空:
D6E6H
第六空:
FD48H
第七空:
2C14H
第八空:
0000H
第九空:
00E6H
第十空:
0000H
第^一空:
0026H第十二空:
000CH
提示:
此题可在DEBU映利用E命令在本机上按照题目中所给出的存单元及其数据进行相应地修改,然后再用A命令进行写入(题目中所给出的)相应的汇编指令,最后再进行T命令进行逐步执行,以查看相应结果。
⑵
1.指令序列如下:
movax,6622h
jmp0ff0:
0100
movax,2000h
movds,ax
movax,[0008]
movax,[0002]
2.写出CPU执行每条指令后,CSIP和相关寄存器中的数值。
ax=5BEA
ax=5CCA
bx=30F0
bx=6029
sp=FE220FE5CCA
sp=FC220FC6029
sp=FE6029
sp=100H5CCA
sp=FE220FE30F0
sp=FC220FC2E39
说明:
此题可能因机子软、硬件环境不同而导致答案不一致!
指令序列
寄存器
CS
IP
DS
AX
BX
初始值
■
2000H
0000
1000H
0
0
movax,6622h
2000H
0003
1000H
6622H
0000
[jmp0ff0:
0100
1000H
0000
1000H
6622H
0000
movax,2000h
1000H
0003
1000H
2000H
0000
movds,ax
1000H
0005
2000H
2000H
0000
movax,[0008]
1000H
0008
2000H
C389H
10000
movax,[0002]
1000H
000B
2000H
EA66H
0000
3.再次体会:
数据和程序有区别吗?
如何确定存中的信息哪些是数据,哪些是程序?
答:
(略)
检测点3.2(第66页)
(1)
movax,2000H
movss,ax
movsp,10H
⑵
movax,1000H
movss,ax
movsp,0H
实验2用机器指令和汇编指令编程(第70页)
1.预备知识:
Debug的使用
<此部分略>
2.实验任务
(1)使用Debug,将下面的程序段写入存,逐条执行,根据指令执行后的实际运行情况填空。
从第一空开始依次如下:
(2)仔细观察图3.19的实验过程,然后分析:
为什么2000:
0~2000:
f中的容会发生改变?
答:
因为用T指令进行调试时,会产生中断。
而为了保护现场,CPU则先将标志寄存器进栈、再把1前CS的值进栈,最后将IP的值进栈。
<关于中断的详细容的讨论不在此题围>
第五章[BX]和loop指令
实验4[BX]和loop的使用(第113页)
(1)编程,向存0:
200~0:
23F依次传送数据0~63(3FH)。
程序如下:
assumecs:
codesg
codesgsegment
movax,0020h
movds,ax
movbx,0
movdl,0
movcx,40h
s:
mov[bx],dl
incdl
incbx
loops
movax,4c00h
codesgends
end
⑵编程,向存0:
200~0:
23F依次传送数据
0~63(3FH),程序中只能使用9条指令,9条指令中包括“movax,4c00h”和“int21h”。
程序如下:
assumecs:
codesg
codesgsegment
movax,0020h
movds,ax
movbl,0
movcx,40h
s:
mov[bx],bl
incbl
loops
movax,4c00h
int21h
codesgends
end
(3)下面的程序的功能是将"movax,4c00h”之前的指令复制到存0:
200处,补全程序。
上机调试,跟踪运行结果。
assumecs:
code
codesegment
movax,code;code为所填写的数据
movds,ax
movax,0020h
movcx,18h;18h为所填写的数据
s:
moval,[bx]
moves:
[bx],al
incbx
loops
movax,4c00h
int21h
codeends
end
提示:
1.因为题目的要求是把代码段的指令当作数据,复
制到目的地址。
所以,源数据段ds和代码段cs相
同,通过movax,code/movds,ax('/'符号是指两条指令的分隔)来设置源数据段。
2.可以先假设要复制8位[1h~0ffh]数据(因为我们
肉眼就可以看出此程序的长度不可能大于0ffh个字节)的字节数(如:
10h),把程序补全,以便通过编译。
这时我们以准确的第一空所填容code与假想的第二空容10h将程序补充完整并将其编译、连接、运行,接着进行DEBUG在DEBUGS我们可用R命令查看CX的值,这时我们可以看到CX的值为
1D,由此我们可以算出该程序的长度[1Dh-5h]=18h,之所以减5是为了满足题目的要求(因为movax,4c00h/int21h这两条指令的长度等
于5)
第六章包含多个段的程序
检测点6.1(第119页)
⑴
assumecs:
codesg
codesgsegment
dw
0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
movds,ax
movbx,0
movcx,8
s:
movax,[bx]
movcs:
[bx],ax;此条指令为所填指
令
addbx,2
loops
movax,4c00h
int21h
codesgends
endstart
⑵
assumecs:
codesg
codesgsegment
dw
0123h,0456h,0789h,0abch,0defh,0fedh,0cb
ah,0987h
dw0,0,0,0,0
start:
movax,cs;cs为所填第一空
movss,ax
movsp,1ah;此条指令为所填第二空
movax,0
movds,ax
movbx,0
movcx,8
s:
push[bx]
popcs:
[bx];此条指令为所填第三
空
addbx,2
loops
movax,4c00h
int21h
codesgends
endstart
实验5编写、调试具有多个段的程序(第123
页)
⑴
1.保持不变
2.<考虑不同机子环境不同,答案无法统一>
3.X-2,X-1
(2)
1.保持不变
2.<考虑不同机子环境不同,答案无法统一>
3.X-2,X-1
4.(N/16+1)*16[说明:
N/16只取整数部分]
⑶
1.保持不变
2.<考虑不同机子环境不同,答案无法统一>
3.X+3,X+4
⑷
答:
第3个仍然可以正确执行。
因为如果把end指令后的标号start去掉后,编译器便会顺序执行程序。
换句话说:
当未给编译器预先的通知,要求其从哪开始执行程序时,编译器
就自动以’至上向下’的顺序进行编译执行源程序。
(5)完整程序如下:
assumecs:
code
asegment
db1,2,3,4,5,6,7,8
aends
bsegment
db1,2,3,4,5,6,7,8
bends
csegment
db0,0,0,0,0,0,0,0
cends
codesegment
start:
movax,a
moves,ax
movax,c
movds,ax
movbx,0
movcx,8
s1:
movax,es:
[bx]
add[bx],ax
addbx,2
loops1
movax,b
moves,ax
movds,ax
movbx,0
movcx,8
s2:
movax,es:
[bx]
add[bx],ax
addbx,2
loops2
movax,4c00h
int21h
codeends
endstart
(6)完整程序如下:
assumecs:
code
asegment
dw1,2,3,4,5,6,7,8
aends
bsegment
dw0,0,0,0,0,0,0,0
bends
codesegment
start:
movax,b
movsp,10h
movax,a
movds,ax
movbx,0
movcx,8
s:
push[bx]
addbx,2
loops
movax,4c00h
int21h
codeends
endstart
第七章更灵活的定位存地址的方法
实验6实践课程中的程序(第147页)
—
⑵编程:
完成问题中的程序。
问题7.9完整程序如下:
assumecs:
codesg,ss:
stacksg,ds:
datasg
stacksgsegment
dw0,0,0,0,0,0,0,0
stacksgends
db'1.display'
db'2.brows'
db'3.replace'
db'4.modify'
datasgends
codesgsegment
start:
movax,stacksg
movss,ax
movsp,16
movax,datasg
movds,ax
movbx,0
movcx,4
s:
;夕卜循环
pushcx
movsi,3
movcx,4
s0:
;循环
moval,[bx+si]
andal,11011111b
mov[bx+si],al
incsi
loops0
addbx,16
datasgsegment
popcx
dw11542,14430,45257,17800
loops
movax,4c00h
int21h
codesgends
endstart
第八章数据处理的两个基本问题
实验7寻址方式在结构化数据访问中的应用
(第160页)
完整程序如下:
assumecs:
codesg,ds:
data,es:
table
datasegment
db
'1975','1976','1977','1978','1979','198
0','1981','1982','1983'
db
'1984','1985','1986','1987','1988','198
9','1990','1991','1992'
db'1993','1994','1995'
;以上是表示21年的21个字符串
dd
16,22,382,1356,2390,8000,16000,24486,50
065,97479,140417,197514
dd
345980,590827,803530,1183000,1843000,27
59000,3753000,4649000,5937000
;以上是表示21年公司总收的21个
dword型数据
dw
3,7,9,13,28,38,130,220,476,778,1001,144
2,2258,2793,4037,5635,8226
;以上是表示21年公司雇员人数的
21个word型数据
dataends
tablesegment
db21dup('yearsummne?
?
')
tableends
codesgsegment
start:
movax,data
movds,ax
movax,table
moves,ax
movbx,0
movsi,0
movdi,0
movcx,21
s:
;进入循环
moval,[bx]
moves:
[di],al
moval,[bx+1]
moves:
[di+1],al
moval,[bx+2]
moves:
[di+2],al
moval,[bx+3]
moves:
[di+3],al
;以上8句的作用是存放年
份
movax,54h[bx];第
一个'年收入'的段基址为54H
movdx,56h[bx]
moves:
5h[di],ax
moves:
7h[di],dx
;以上4句的作用是存放公
司总收入
movax,0A8h[si];第
一个'人数'的段基址为0A8H
moves:
0Ah[di],ax
;以上2句是存放公司的人
数
movax,54h[bx]
divwordptrds:
0A8h[si]
moves:
0dh[di],ax
;以上3句是存放人均收入
addbx,4
addsi,2
adddi,16
;以上3句是为下一次循环
时存放数据做准备
;3个寄存器递增的速度决
定了所要存取的数据的位置的偏移地址
loops;跳到标号s处
movax,4c00h
int21h
codesgends
程序说明:
此程序虽然可以达到预期效果(读
者可以自行调试验证),但实现方法比较简单,读者有兴趣的话可以寻找一种更具结构化的设计方法来完成。
第九章转移指令的原理
检测点9.1(第170页)
⑴若要使jmp指令执行后,CS:
IP指向程序的第一条指令,在data中中应该定义哪些数据?
完整程序如下:
assumecs:
code,ds:
data
datasegment
db0,0,0
dataends
codesegment
start:
movax,data
movds,ax
movbx,0
jmpwordptr[bx+1];段间接转移
codeends
endstart
;解题理由:
为了使IP的值经跳转后变为0,
则需保证ds:
[bx+1]处的字型单元数据为0000H,
;所以定义3个字节型数据0就符合“应该”的要求
(2)补全程序,使jmp指令执行后,CS:
IP指向程序的第一条指令。
endstart
完整程序如下:
assumecs:
code,ds:
data
datasegment
dd12345678h
dataends
codesegment
start:
movax,data
movds,ax
movbx,0
mov[bx],bx;源操作数bx为所填
容
mov[bx+2],cs;源操作数cs为所填容
jmpdwordptrds:
[0]
codeends
endstart
⑶用Debug查看存,结果如下:
2000:
1000BE0006000000......
则此时,CPU^行指令:
movax,2000H
moves,ax
jmpdwordptres:
[1000H]
后,(CS)=?
(IP)=?
提示:
为了使本机环境[2000:
1000至
2000:
1005]中的数据与题目中所给出的数据
一致,可以通过编写程序来完成,完整程序如
下:
assumecs:
code
codesegment
start:
movax,2000h
movds,ax
movbx,1000h
movwordptr[bx].0,0BEH
movwordptr[bx].2,6h
movwordptr[bx].4,0
;运行完上6句则使
2000:
1000--2000:
1005中的数据依次
为:
BE,00,06,00,00,00
;以上6句则按题目中的数据进行初始
化,以便使运行环境符合题目要求
;movax,2000h
moves,ax
jmpdwordptres:
[1000h]
codeends
endstart
经上机调试得出:
CS=0006H,IP=00BEH
检测点9.2(第172页)
从标号s处开始所要填写的四条指令依次如下:
第一条指令:
movcl,[bx]
第二条指令:
movch,0
第三条指令:
jcxzok
第四条指令:
incbx
检测点9.3(第173页)
—
补全程序,利用loop指令,实现在存2000H段中查找第一个值为0的byte,找到后,将
它的偏移地址存储在dx中。
assumecs:
code
codesegment
start:
movax,2000h
movds,ax
movbx,0
s:
movcl,[bx]
movch,0
inccx;此条指令为题目要求补全的指令
incbx
loop
ok:
decbx
movdx,bx
movax,4c00h
int21h
codeends
endstart
解答提醒:
此题可用假设法来完成(比如设2000:
0000至2000:
0003的容依次为:
1E06000A)。
此题要注意loop指令的使用规则,同时要注意区别[存单元]与[存单元中的数据(或容)]的不同。
实验8分析一个奇怪的程序(第174页)
—
分析下面的程序,在运行前思考:
这个程序可
以正确返回吗?
运行后再思考:
为什么是这种结果?
通过这个程序加深对相关容的理解。
assumecs:
codesg
codesgsegment
movax,4c00h
int21h
start:
movax,0
s:
nop
nop
movdi,offsets
movsi,offsets2
movax,cs:
[si]
movcs:
[di],ax
s0:
jmpshorts
s1:
movax,0
int21h
movax,0
s2:
jmpshorts1
nop
实验9根据材料编程(第175页)
codesgends
endstart
程序可以正常返回。
详细分析:
在此题中较为深入地考察了’段直接短转移’[形如:
jmpshort标号]的概念。
我们知道程序中:
movdi,offsets
movsi,offsets2
movax,cs:
[si]
movcs:
[di],ax
四条指令的作用是将标号s2处的一条指令复
制到标号s处。
这时我们应该关心所复制的语句"jmpshorts1"对程序的影响:
我们知道在
段直接短转移指令所对应的机器码中,并不包
含转移的目的地址,而包含的是转移的位移量
(如对此概念还不太熟悉,请查看书中第167页的容)。
也就是说,在源程序的编译过程中,编译器遇到’段直接短转移’[形如:
jmpshort标号]时就会自动算出其要跳转的位移量,以便程序在执行’段直接短转移’的指令时就根据位移量进行(向前或向后)跳转。
通过调试中的U命令我们可以看到指令’s2:
jmpshort
s1'所对应的机器码是EBF6,F6h(-10d的补码)
就是跳转的位移量[此位移量也可由指令's2:
jmpshorts1'处的偏移地址18h减去指
令's2:
jmpshorts1'后一个字节的偏移地址
22h得出]。
这时我们就知道了其实复制到标号s处的指令所对应的机器码就是EBF6(刚好
取代两个nop所对应的机器码),它的作用就是将当前IP向前移动10个字节。
当程序执行标号s0处的指令后,程序便跳到标号s处接
着执行标号s处的指令。
s处的指令的作用是向前跳10字节,于是便跳到了代码中的第一条指令,继续执行后便实现了程序的正常返回。
[注意:
此程序不会也不可能执行标号s1处后
的指令。
]
assumecs:
code,ds:
data,ss:
stack
datasegment
db'welcometomasm!
';定义要显
示的字符串(共16字节)
db02h,24h,71h;定义三种颜色
属性
dataends
stacksegment
dw8dup(0)
sta