检测点1.1(第8页)
----------------------
(1) 13 (2) 1024,0,1023 (3) 8192,1024
(4) 2^30,2^20,2^10 (5) 64,1,16,4 (6) 1,1,2,2,4
(7) 512,256 (8) 二进制
注意:
1.第4题中的符号'^'指求幂运算(如: 2^30指2的30次方)
检测点2.1(第18页)
----------------------
(1)写出每条汇编指令执行后相关寄存器中的值。
第一空:F4A3H第二空:31A3H第三空:3123H第四空:6246H
第五空:826CH第六空:6246H第七空:826CH第八空:04D8H
第九空:0482H第十空:6C82H第十一空:D882H
第十二空:D888H第十三空:D810H第十四空:6246H
(2)只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。
解答如下:
mov ax,2
add ax,ax
add ax,ax
add ax,ax
检测点2.2(第23页)
----------------------
(1)00010H,1000FH
(2)1001H,2000H
第2题说明:
因为段的起始地址要为16的倍数。所以当段地址小于1001H或大于2000H时CPU都无法寻到。
检测点2.3(第33页)
----------------------
答:CPU修改了4次IP的值。
情况如下:
第1次:执行完mov ax,bx后
第2次:执行完sub ax,ax后
第3次:读入jmp ax后
第4次:执行完jmp ax后
最后IP的值为0
检测点3.1(第52页)
----------------------
(1)(题目:略)
第一空:2662H 第二空:E626H第三空:E626H第四空:2662H第五空:D6E6H
第六空:FD48H第七空:2C14H第八空:0000H第九空:00E6H第十空:0000H
第十一空:0026H第十二空:000CH
提示:此题可在DEBUG中利用E命令在本机上按照题目中所给出的内存单元及其数据进行相应地修改,然后再用A命令进行写入(题目中所给出的)相应的汇编指令,最后再进行T命令进行逐步执行,以查看相应结果。
(2)
1.指令序列如下:
mov ax,6622h
jmp 0ff0:0100
mov ax,2000h
mov ds,ax
mov ax,[0008]
mov ax,[0002]
2.写出CPU执行每条指令后,CS、IP和相关寄存器中的数值。
指令序列↓ 寄存器→ CS IP DS AX BX
初始值→ 2000H 0000 1000H 0 0
mov ax,6622h 2000H 0003 1000H 6622H 0000
jmp 0ff0:0100 1000H 0000 1000H 6622H 0000
mov ax,2000h 1000H 0003 1000H 2000H 0000
mov ds,ax 1000H 0005 2000H 2000H 0000
mov ax,[0008] 1000H 0008 2000H C389H 0000
mov ax,[0002] 1000H 000B 2000H EA66H 0000
3.再次体会:数据和程序有区别吗?如何确定内存中的信息哪些是数据,哪些是程序?
答:(略)
检测点3.2(第66页)
----------------------
(1)
mov ax,2000H
mov ss,ax
mov sp,10H
(2)
mov ax,1000H
mov ss,ax
mov sp,0H
检测点6.1(第119页)
-------------------
(1)
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
start: mov ax,0
mov ds,ax
mov bx,0
mov cx,8
s: mov ax,[bx]
mov cs:[bx],ax ;此条指令为所填指令
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
(2)
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0
start:
mov ax,cs ;cs为所填第一空
mov ss,ax
mov sp,1ah ;此条指令为所填第二空
mov ax,0
mov ds,ax
mov bx,0
mov cx,8
s:
push [bx]
pop cs:[bx] ;此条指令为所填第三空
add bx,2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
检测点9.1(第170页)
----------------------
(1)若要使jmp指令执行后,CS:IP指向程序的第一条指令,在data段中应该定义哪些数据?
完整程序如下:
assume cs:code,ds:data
data segment
db 0,0,0
data ends
code segment
start: mov ax,data
mov ds,ax
mov bx,0
jmp word ptr [bx+1] ;段内间接转移
code ends
end start
;解题理由:为了使IP的值经跳转后变为0,则需保证ds:[bx+1]处的字型单元数据为0000H,
;所以定义3个字节型数据0就符合“应该”的要求
(2)补全程序,使jmp指令执行后,CS:IP指向程序的第一条指令。
完整程序如下:
assume cs:code,ds:data
data segment
dd 12345678h
data ends
code segment
start: mov ax,data
mov ds,ax
mov bx,0
mov [bx],bx ;源操作数bx为所填内容
mov [bx+2],cs ;源操作数cs为所填内容
jmp dword ptr ds:[0]
code ends
end start
(3)用Debug查看内存,结果如下:
2000:1000 BE 00 06 00 00 00 ......
则此时,CPU执行指令:
mov ax,2000H
mov es,ax
jmp dword ptr es:[1000H]
后,(CS)=? , (IP)=?
提示:为了使本机环境[2000:1000至2000:1005]中的数据与题目中所给出的数据一致,可以通过编写程序来完成,完整程序如下:
assume cs:code
code segment
start:
mov ax,2000h
mov ds,ax
mov bx,1000h
mov word ptr [bx].0,0BEH
mov word ptr [bx].2,6h
mov word ptr [bx].4,0
;运行完上6句则使2000:1000--2000:1005中的数据依次为:BE,00,06,00,00,00
;以上6句则按题目中的数据进行初始化,以便使运行环境符合题目要求
;mov ax,2000h
mov es,ax
jmp dword ptr es:[1000h]
code ends
end start
经上机调试得出:CS=0006H,IP=00BEH
检测点9.2(第172页)
----------------------
从标号s处开始所要填写的四条指令依次如下:
第一条指令:mov cl,[bx] 第二条指令:mov ch,0
第三条指令:jcxz ok 第四条指令:inc bx
检测点9.3(第173页)
----------------------
补全程序,利用loop指令,实现在内存2000H段中查找第一个值为0的byte,找到后,将它的偏移地址存储在dx中。
assume cs:code
code segment
start:
mov ax,2000h
mov ds,ax
mov bx,0
s:
mov cl,[bx]
mov ch,0
inc cx ;此条指令为题目要求补全的指令
inc bx
loop s
ok:
dec bx
mov dx,bx
mov ax,4c00h
int 21h
code ends
end start
解答提醒:此题可用假设法来完成(比如设2000:0000至2000:0003的内容依次为:1E 06 000A)。此题要注意loop指令的使用规则,同时要注意区别[内存单元]与[内存单元中的数据(或内容)]的不同。
检测点10.1(第179页)
----------------------
第一空:1000h
第二空:0
提示:此题等效于把CS的值改为1000H,把IP的值改为0。因为retf指令进行的操作是先将IP出栈,再将CS出栈,所以在进栈时应当进行相反的操作。
检测点10.2(第181页)
----------------------
ax=6
提示:在执行指令"call s"时,IP的值变为6,接着进栈。此时程序直接执行指令"s:popax",这就等于把栈中IP的值放入ax中。所以答案为6。关于更多的call指令的问题请看附注中的“错误指出”中的第6条。
检测点10.3(第181页)
----------------------
ax=1010
提示:
1.寄存器中存放的值为16进制数
2.关于更多的call指令的问题请看附注中的“错误指出”中的第6条。
检测点10.4(第182页)
----------------------
ax=000B
提示:关于更多的call指令的问题请看附注中的“错误指出”中的第6条。
检测点10.5(第183页)
----------------------
(1)答:ax中的数值为3
提示:不能利用T命令进行调试,则改用U和G命令来调试。可用U命令先查看指令"movax,4c00h"处的偏移地址,然后用G命令直接执行到指令"mov ax,4c00h"的偏移地址处。
(2)
ax=1
bx=0
提示:关于更多的call指令的问题请看附注中的“错误指出”中的第6条。
检测点11.1(第205页)
----------------------
ZF PF CF
1 1 0
1 1 0
1 1 0
1 1 0
0 0 0
0 1 0
0 1 0
检测点11.2(第208页)
----------------------
CF OF SF ZF PF
0 0 0 1 1
0 0 0 1 1
0 0 1 0 1
0 0 1 0 1
1 1 0 1 1
1 1 0 1 1
1 0 0 0 0
1 0 0 0 0
0 1 1 0 1
0 1 1 0 1
检测点11.3(第219页)
----------------------
(1)
第一空:jb s0
第二空:ja s0
(2)
第一空:jna s0
第二空:jnb s0
提示:注意区别闭区间[32,128]与开区间(32,128)所表示的数值范围。
检测点11.4(第223页)
----------------------
ax=45H
提示:
1.有符号数在计算机中是以其补码形式进行存储的。
2.注意执行指令"add ax,0010h"后影响的相关标志位的情况。详情如下:
CF OF SF ZF PF
1 0 0 1 1
检测点12.1(第227页)
----------------------
(1)
0070:018B
(2)
N*4
N*4+2
检测点13.1(第246页)
----------------------
(1)答:所能进行的最大转移位移是128[指向前转移]。因为是实现loop的功能,那就应当遵守loop的使用规则。
<注:关于loop指令的详细介绍请查看书中第172页9.8节的内容。>
(2)用7ch中断例程完成jmp near ptr s指令的功能,用bx向中断例程传送转移位移。
应用举例:在屏幕的第12行显示data段中,以0结尾的字符串。
解答完整程序如下:
assume cs:code
data segment
db 'conversation',0
data ends
code segment
start:
mov ax,cs
mov ds,ax
mov si,offset nr
mov ax,0
mov es,ax
mov di,200h
mov cx,offset nrend-offset nr
cld
rep movsb
;以上9句为安装中断例程
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0
;以上2句为设置中断向量
mov ax,data
mov ds,ax
mov si,0
mov ax,0b800h
mov es,ax
mov di,12*160
s: cmp byte ptr [si],0
je ok
mov al,[si]
mov es:[di],al
inc si
add di,2
mov bx,offset s-offset ok
int 7ch
ok: mov ax,4c00h
int 21h
nr: push bp ;定义中断例程[开始]
mov bp,sp
add [bp+2],bx
nrret: pop bp
iret ;中断返回指令
nrend: nop ;定义中断例程[结束]
code ends
end start
检测点13.2(第248页)
----------------------
判断下面说法的正误:
(1)我们可以编程改变FFFF:0处的指令,使得CPU不去执行BIOS中的硬件系统检测和初始化程序。
答:这种说法是错误的。因为该内存单元具有‘只读’属性。
(2)int 19h中断例程,可以由DOS提供。
答:这种说法是错误的。因为int19h是在DOS启动之前就被执行的中断例程,这里面涉及到一个先后次序的问题,而此次序不能被打乱。
检测点14.1(第256页)
----------------------
(1)编程:读取CMOS RAM的2号单元的内容。
完整程序如下:
assume cs:code
code segment
start:
mov al,2
out 70h,al
in al,71h ;此时al中装的是当前时间的‘分’。
mov ax,4c00h
int 21h
code ends
end start
(2) 编程:向CMOS RAM的2号单元写入0。
完整程序如下:
assume cs:code
code segment
start:
mov al,2
out 70h,al
mov al,0
out 71h,al
in al,71h ;执行完此条指令后al中的内容为0
mov ax,4c00h
int 21h
code ends
end start
<提示:如果对这两个程序还不太理解,请再仔细阅读14.2节的中的第(4)、(5)点内容[在第256页]。>
检测点14.2(第258页)
----------------------
编程:用加法和移位指令计算(ax)=(ax)*10
提示:(ax)*10=(ax)*2+(ax)*8
完整程序如下:
assume cs:code
code segment
start:
mov ax,1000h
mov bx,ax
shl bx,1 ;(ax)=(ax)*2
mov cl,3
shl ax,cl ;(ax)=(ax)*8
add ax,bx ;(ax)=(ax)*10
mov ax,4c00h
int 21h
code ends
end start
提示:左移1位相当于乘以[2^1=]2,左移2位相当于乘以[2^2=]4,左移3位相当于乘以[2^3=]8,以此类推。
检测点15.1(第271页)
----------------------
(1)可以精简为:
pushf
call dword ptr ds:[0]
两条指令。
(2)仔细分析上面程序中的主程序[第269页],看看有什么潜在的问题?
在主程序中,如果在执行设置int9中断例程的段地址和偏移地址的指令之间发生了键盘中断,则CPU将转去一个错误的地址执行,将发生错误。
找出这样的程序段,改写它们,排除潜在的问题。
提示:注意sti和cli指令的用法。
改写方法:在pop ds:[2]指令后加入一条cli指令,并在moves:[9*4+2],cs指令后加入一条sti指令即可。
检测点16.1(第278页)
----------------------
下面的程序将code段中a处的8个数据累加,结果存储到b处的dword中,补全程序。
完整程序如下:
assume cs:code
code segment
a dw 1,2,3,4,5,6,7,8
b dd 0
start:
mov si,0
mov cx,8
s: mov ax,a[si]
add word ptr b,ax
adc word ptr b[2],0
add si,2
loop s
mov ax,4c00h
int 21h
code ends
end start
说明:程序中的蓝色部分为题目所要求的填写内容。
检测点16.2(第280页)
----------------------
下面的程序将code段中a处的8个数据累加,结果存储到b处的字中,补全程序。
完整程序如下:
assume cs:code,ds:data
data segment
a db 1,2,3,4,5,6,7,8
b dw 0
data ends
code segment
start:
mov ax,data
mov ds,ax
mov si,0
mov cx,8
s: mov al,a[si]
mov ah,0
add b,ax
inc si
loop s
mov ax,4c00h
int 21h
code ends
end start
说明:程序中的蓝色部分为题目所要求的填写内容。