汇编语言课后习题答案 王爽主编.docx
《汇编语言课后习题答案 王爽主编.docx》由会员分享,可在线阅读,更多相关《汇编语言课后习题答案 王爽主编.docx(106页珍藏版)》请在冰点文库上搜索。
汇编语言课后习题答案王爽主编
检测点9.2
补全编程,利用jcxz指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。
assumecs:
code
codesegment
start:
movax,2000h
movds,ax
movbx,0
s:
movch,0
movcl,[bx]
jcxzok;当cx=0时,CS:
IP指向OK
incbx
jmpshorts
ok:
movdx,bx
movax,4c00h
int21h
codeends
endstart
检测点9.3
补全编程,利用loop指令,实现在内存2000H段中查找第一个值为0的字节,找到后,将它的偏移地址存储在dx中。
assumecs:
code
codesegment
start:
movax,2000h
movds,ax
movbx,0
s:
movcl,[bx]
movch,0
inccx
incbx
loops
ok:
decbx
movdx,bx
movax,4c00h
int21h
codeends
endstart
书P101,执行loops时,首先要将(cx)减1。
“loop标号”相当于
deccx
if((cx)≠0)jmpshort标号
检测点10.1
补全程序,实现从内存1000:
0000处开始执行指令。
assumecs:
code
stacksegment
db16dup(0)
stackends
codesegment
start:
movax,stack
movss,ax
movsp,16
movax,1000h
pushax
movax,0
pushax
retf
codeends
endstart
执行reft指令时,相当于进行:
popip
popcs
根据栈先进后出原则,应先将段地址cs入栈,再将偏移地址ip入栈。
检测点10.3
下面的程序执行后,ax中的数值为多少?
内存地址机器码汇编指令执行后情况
1000:
0b80000movax,0ax=0,ip指向1000:
3
1000:
39a09000010callfarptrspopcs,popip,ip指向1000:
9
1000:
840incax
1000:
958s:
popaxax=8h
addax,axax=10h
popbxbx=1000h
addax,bxax=1010h
用debug进行跟踪确认,“callfarptrs”是先将该指令后的第一个字节段地址cs=1000h入栈,再将偏移地址ip=8h入栈,最后转到标号处执行指令。
出栈时,根据栈先进后出的原则,先出的为ip=8h,后出的为cs=1000h
检测点10.4
下面的程序执行后,ax中的数值为多少?
内存地址机器码汇编指令执行后情况
1000:
0b80600movax,6ax=6,ip指向1000:
3
1000:
3ffd0callaxpopip,ip指向1000:
6
1000:
540incax
1000:
658movbp,spbp=sp=fffeh
addax,[bp]ax=[6+ds:
(fffeh)]=6+5=0bh
用debug进行跟踪确认,“callax(16位reg)”是先将该指令后的第一个字节偏移地址ip入栈,再转到偏移地址为ax(16位reg)处执行指令。
检测点10.5
(1)下面的程序执行后,ax中的数值为多少?
assumecs:
code
stacksegment
dw8dup(0)
stackends
codesegment
start:
movax,stack
movss,ax
movsp,16
movds,ax
movax,0
callwordptrds:
[0eh]
incax
incax
incax
movax,4c00h
int21h
codeends
endstart
推算:
执行callwordptrds:
[0eh]指令时,先cs入栈,再ip=11入栈,最后ip转移到(ds:
[0eh])。
(ds:
[0eh])=11h,执行incax……最终ax=3
题中特别关照别用debug跟踪,跟踪结果不一定正确,但还是忍不住去试试,看是什么结果。
根据单步跟踪发现,执行callwordptrds:
[0eh]指令时,显示ds:
[0eh]=065D。
ds:
0000~ds:
0010不是已设置成stack数据段了嘛,不是应该全都是0的嘛。
于是进行了更详细的单步跟踪,发现初始数据段中数据确实为0,但执行完movss,ax;movsp,16这两条指令后,数据段中数据发生改变。
这是为什么呢?
中断呗~~~~
检测点10.5
(2)下面的程序执行后,ax和bx中的数值为多少?
assumecs:
codesg
stacksegment
dw8dup(0)
stackends
codesgsegment
start:
movax,stack
movss,ax
movsp,10h
movwordptrss:
[0],offsets;(ss:
[0])=1ah
movss:
[2],cs;(ss:
[2])=cs
calldwordptrss:
[0];cs入栈,ip=19h入栈,转到cs:
1ah处执行指令
;(ss:
[4])=cs,(ss:
[6])=ip
nop
s:
movax,offsets;ax=1ah
subax,ss:
[0ch];ax=1ah-(ss:
[0ch])=1ah-19h=1
movbx,cs;bx=cs=0c5bh
subbx,ss:
[0eh];bx=cs-cs=0
movax,4c00h
int21h
codesgends
endstart
C:
\DOCUME~1\ADMINI~1>debugjc10-5.exe
-u
0C5B:
0000B85A0CMOVAX,0C5A
0C5B:
00038ED0MOVSS,AX
0C5B:
0005BC1000MOVSP,0010
0C5B:
000836SS:
0C5B:
0009C70600001A00MOVWORDPTR[0000],001A
0C5B:
000F36SS:
0C5B:
00108C0E0200MOV[0002],CS
0C5B:
001436SS:
0C5B:
0015FF1E0000CALLFAR[0000]
0C5B:
001990NOP
0C5B:
001AB81A00MOVAX,001A
0C5B:
001D36SS:
0C5B:
001E2B060C00SUBAX,[000C]
-u
0C5B:
00228CCBMOVBX,CS
0C5B:
002436SS:
0C5B:
00252B1E0E00SUBBX,[000E]
0C5B:
0029B8004CMOVAX,4C00
课程设计一
将实验7中的Poweridea公司的数据按照图所示的格式在屏幕上显示现来
tablesegment
db'1975','1976','1977','1978','1979','1980','1981','1982','1983'
db'1984','1985','1986','1987','1988','1989','1990','1991','1992'
db'1993','1994','1995'
dd16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
dd345980,590827,803530,1183000,1843000,2795000,3753000,4649000,5937000
dw3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
dw11542,14430,15257,17800
dw5,3,42,104,85,210,123,111,105,125,140,136,153,211,199,209,224,239
dw260,304,333
tableends
datasegment
db32dup(0)
dataends
codesegment
start:
movax,data
movds,ax
movax,table
moves,ax
movbx,0
movsi,0
movdi,0
movcx,21
movdh,2
movdl,30
g:
pushcx
pushdx
movax,es:
[bx]
mov[si],ax
movax,es:
[bx].2
mov[si].2,ax;年份入ds:
si
addsi,6
movax,es:
[bx].84
movdx,es:
[bx].86
calldtoc2;收入转成十进制字符入ds:
si
addsi,10
movax,es:
[di].168
movdx,0
calldtoc2;人员数转成十进制字符入ds:
si
addsi,6
movax,es:
[di].210
movdx,0
calldtoc2;人均收入转成十进制字符入ds:
si
movsi,0;设置ds:
si指向需显示字符首地址
b:
movcx,29
c:
pushcx
movcl,[si]
jcxzf;(ds:
si)=0转到f执行
d:
incsi
popcx
loopc
incsi
moval,0
mov[si],al;设置结尾符0
movsi,0;设置ds:
si指向需显示字符首地址
popdx
movcl,2
callshow_str
addbx,4;dword数据指向下一数据单元
adddi,2;word数据指向下一数据单元
adddh,1;指向显存下一行
popcx
loopg
movax,4c00h
int21h
f:
moval,20h
mov[si],al;(ds:
si)=0的数据改成空格
jmpd
;名称:
dtoc2
;功能:
将dword型数据转变为表示十进制的字符串,字符串以0为结尾符。
;参数:
(ax)=dword型数据的低16位;
;(dx)=dword型数据的高16位;
;ds:
si指向字符串首地址。
;返回:
无。
dtoc2:
pushax
pushbx
pushcx
pushdx
pushsi
pushdi
movdi,0
d20:
movcx,10;除数为10
calldivdw
addcx,30h;余数+30h,转为字符
pushcx;字符入栈
incdi;记录字符个数
movcx,ax
jcxzd21;低位商=0时,转到d21检测高位商
jmpd20
d21:
movcx,dx
jcxzd22;高低位商全=0时,转到d22执行
jmpd20
d22:
movcx,di
d23:
popax;字符出栈
mov[si],al
incsi;ds:
si指向下一单元
loopd23
moval,0
mov[si],al;设置结尾符0
popdi
popsi
popdx
popcx
popbx
popax
ret
;名称:
divdw
;功能:
进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型。
;参数:
(ax)=dword型数据的低16位;
;(dx)=dword型数据的高16位;
;(cx)=除数。
;返回:
(dx)=结果的高16位;
;(ax)=结果的低16位;
;(cx)=余数。
divdw:
pushsi
pushbx
pushax
movax,dx
movdx,0
divcx;被除数的高位/cx
movsi,ax
popax
divcx;(被除数高位的商+低位)/cx
movcx,dx;余数入cx
movdx,si;高位的商入dx
popbx
popsi
ret
;名称:
show_str
;功能:
在指定的位置,用指定的颜色,显示一个用0结束的字符串。
;参数:
(dh)=行号(取值范围0~24);
;(dl)=列号(取值范围0~79);
;(cl)=颜色;
;ds:
si指向字符串的首地址。
;返回:
无。
show_str:
pushax
pushbx
pushes
pushsi
movax,0b800h
moves,ax
movax,160
muldh
movbx,ax;bx=160*dh
movax,2
muldl;ax=dl*2
addbx,ax;movbx,(160*dh+dl*2)设置es:
bx指向显存首地址
moval,cl;把颜色cl赋值al
movcl,0
show0:
movch,[si]
jcxzshow1;(ds:
si)=0时,转到show1执行
moves:
[bx],ch
moves:
[bx].1,al
incsi;ds:
si指向下一个字符地址
addbx,2;es:
bx指向下一个显存地址
jmpshow0
show1:
popsi
popes
popbx
popax
ret
codeends
endstart
检测点11.1
写出下面每条指令执行后,ZF、PF、SF、等标志位的值。
subal,alal=0hZF=1PF=1SF=0
moval,1al=1hZF=1PF=1SF=0
pushaxax=1hZF=1PF=1SF=0
popbxbx=1hZF=1PF=1SF=0
addal,blal=2hZF=0PF=0SF=0
addal,10al=12hZF=0PF=1SF=0
mulalax=144hZF=0PF=1SF=0
检测点涉及的相关内容:
ZF是flag的第6位,零标志位,记录指令执行后结果是否为0,结果为0时,ZF=1
PF是flag的第2位,奇偶标志位,记录指令执行后结果二进制中1的个数是否为偶数,结果为偶数时,PF=1
SF是flag的第7位,符号标志位,记录有符号运算结果是否为负数,结果为负数时,SF=1
add、sub、mul、div、inc、or、and等运算指令影响标志寄存器
mov、push、pop等传送指令对标志寄存器没影响。
检测点11.2
写出下面每条指令执行后,ZF、PF、SF、CF、OF等标志位的值。
alCFOFSFZFPF
subal,al0h/00000000b00011
moval,10h10h/00100000b00011
addal,90ha0h/10100000b00101
moval,80h80h/10000000b00101
addal,80h0h/00000000b11011
moval,0fch0fch/11111100b11011
addal,05h1h/00000001b10000
moval,7dh7dh/11111101b10000
addal,0bh88h/10001000b01101
检测点涉及的相关内容:
ZF是flag的第6位,零标志位,记录指令执行后结果是否为0,结果为0时,ZF=1
PF是flag的第2位,奇偶标志位,记录指令执行后结果二进制数中1的个数是否为偶数,结果为偶数时,PF=1
SF是flag的第7位,符号标志位,记录有符号运算结果是否为负数,结果为负数时,SF=1
CF是flag的第0位,进位标志位,记录无符号运算结果是否有进/借位,结果有进/借位时,SF=1
OF是flag的第11位,溢出标志位,记录有符号运算结果是否溢出,结果溢出时,OF=1
add、sub、mul、div、inc、or、and等运算指令影响flag
mov、push、pop等传送指令对flag没影响
检测点11.3
(1)补全下面的程序,统计F000:
0处32个字节中,大小在[32,128]的数据个数。
movax,0f000h
movds,ax
movbx,0;ds:
bx指向第一个字节
movdx,0;初始化累加器
movcx,32
s:
moval,[bx]
cmpal,32;和32进行比较
jbs0;如果低于al转到s0,继续循环
cmpal,128;和128进行比较
jas0;如果高于al转到s0,继续循环
incdx
s0:
incbx
loops
[32,128]是闭区间,包括两端点的值
(32,128)是开区间,不包括两端点的值
检测点11.3
(2)补全下面的程序,统计F000:
0处32个字节中,大小在(32,128)的数据个数。
movax,0f000h
movds,ax
movbx,0;ds:
bx指向第一个字节
movdx,0;初始化累加器
movcx,32
s:
moval,[bx]
cmpal,32;和32进行比较
jnas0;如果不高于al转到s0,继续循环
cmpal,128;和128进行比较
jnbs0;如果不低于al转到s0,继续循环
incdx
s0:
incbx
loops
[32,128]是闭区间,包括两端点的值
(32,128)是开区间,不包括两端点的值
检测点11.4
下面指令执行后,(ax)=45h
movax,0
pushax
popf
movax,0fff0h
addax,0010h
pushf
popax
andal,11000101B
andah,00001000B
推算过程:
popf后,标志寄存器中,本章节介绍的那些标志位都为0(但是此时标志寄存器并不是所有位置都为0,这个不用关心,没学过的位置用*先代替),向下进行,那么pushf将计算后的当时状态的标志寄存器入栈,然后pop给ax,这是ax是寄存器的值(这个值中包含了我们的*号),接下来就是对那些没有学过的标志位的屏蔽操作,这就是最后两条指令的意义所在,将不确定的位置都归0,那么只剩下我们能够确定的位置了,所以,结果就可以推理出来了。
movax,0
pushax
popf
movax,0fff0h
addax,0010h
pushf
popax0000ofdfiftfsfzf0af0pf0cf
000000**010*0101
ax=flag=000000**010*0101b
andal,11000101Bal=01000101b=45h
andah,00001000Bah=00000000b=0h
C:
\DOCUME~1\SNUSER>debug
-a
0BF9:
0100movax,0
0BF9:
0103pushax
0BF9:
0104popf
0BF9:
0105movax,fff0
0BF9:
0108addax,10
0BF9:
010Bpushf
0BF9:
010Cpopax
0BF9:
010Dandal,c5
0BF9:
010Fandah,8
0BF9:
0112
-r
AX=0000BX=0000CX=0000DX=0000SP=FFEEBP=0000SI=0000DI=0000
DS=0BF9ES=0BF9SS=0BF9CS=0BF9IP=0100NVUPEIPLNZNAPONC
0BF9:
0100B80000MOVAX,0000
-t
AX=0000BX=0000CX=0000DX=0000SP=FFEEBP=0000SI=0000DI=0000
DS=0BF9ES=0BF9SS=0BF9CS=0BF9IP=0103NVUPEIPLNZNAPONC
0BF9:
010350PUSHAX
-t
AX=0000BX=0000CX=0000DX=0000SP=FFECBP=0000SI=0000DI=0000
DS=0BF9ES=0BF9SS=0BF9CS=0BF9IP=0104NVUPEIPLNZNAPONC
0BF9:
01049DPOPF
-t
AX=0000BX=0000CX=0000DX=0000SP=FFEEBP=0000SI=0000DI=0000
DS=0BF9ES=0BF9SS=0BF9CS=0BF9IP=0105NVUPDIPLNZNAPONC
0BF9:
0105B8F0FFMOVAX,FFF0
-t
AX=FFF0BX=0000CX=0000DX=0000SP=FFEEBP=0000SI=0000DI=0000
DS=0BF9ES=0BF9SS=0BF9CS=0BF9IP=0108NVUPDIPLNZNAPONC
0BF9:
0108051000ADDAX,0010
-t
AX=0000BX=0000CX=0000DX=0000SP=FFEEBP=0000SI=0000DI=0000
DS=0BF9ES=0BF9SS=0BF9CS=0BF9IP=010BNVUPDIPLZRNAPECY
0BF9:
010B9CPUSHF