汇编语言程序设计---10~16章习题答案(王爽第二版)
检测点10.1
补全程序,实现从内存1000:0000处开始执行指令。
assume cs:code
stack segment
db 16 dup (0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ax,1000h
push ax
mov ax,0
push ax
retf
code ends
end start
检测点10.2
下面的程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令
1000:0 b8 00 00 mov ax,0
1000:3 e8 01 00 call s
1000:6 40 inc ax
1000:7 58 s:pop ax
解:ax=6
检测点10.3
下面的程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令
1000:0 b8 00 00 mov ax,0
1000:3 9a 09 00 00 10 call far ptr s
1000:8 40 inc ax
1000:9 58 s:pop ax
add ax,ax
pop bx
add ax,bx
解:ax=1010h
检测点10.4
下面的程序执行后,ax中的数值为多少?
内存地址 机器码 汇编指令
1000:0 b8 06 00 mov ax,6
1000:2 ff d0 call ax
1000:5 40 inc ax
1000:6 mov bp,sp
add ax,[bp]
解:ax=11
检测点10.5
(1)下面的程序执行后,ax中的数值为多少?
注:不能用单步中断测试程序,中断涉及堆栈操作,不能带便CPU的真实执行结果。
assume cs:code
stack segment
dw 8 dup (0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov ds,ax
mov ax,0
call word ptr ds:[0EH]
inc ax
inc ax
inc ax
mov ax,4c00h
int 21h
code ends
end start
解:ax=3
(2)下面的程序执行后,ax中的数值为多少?
assume cs:code
stack segment
dw 8 dup (0)
stack ends
code segment
start: mov ax,stack
mov ss,ax
mov sp,16
mov word ptr ss:[0],offset s
mov ss:[2],cs
call dword ptr ss:[0]
nop
s: mov ax,offset s
sub ax,ss:[0cH]
mov bx,cs
sub bx,ss:[0eH]
mov ax,4c00h
int 21h
code ends
end start
解:ax=1,bx=0
检测点11.1
写出下面每条指令后,ZF、PF、SF等标志位的值。
ZF PF SF
sub al,al 1 1 0
mov al,1 1 1 0
push ax 1 1 0
pop bx 1 1 0
add al,bl 0 0 0
add al,10 0 1 0
mul al 0 1 0
检测点11.2
CF OF SF ZF PF
sub al,al 0 0 0 1 1
mov al,10H 0 0 0 1 1
add al,90H 0 0 1 0 1
mov al,80H 0 0 1 0 1
add al,80H 1 1 0 1 1
mov al,0FCH 1 1 0 1 1
add al,05H 1 0 0 0 0
mov al,7DH 1 0 0 0 0
add al,0BH 0 1 1 0 1
检测点11.3
(1) 补全下面的程序,统计F000:0处32个字节中,大小在[32,128]的数据的个数。
mov ax,0f000h
mov ds,ax
mov bx,0
mov dx,0
mov cx,32
s:mov al,[bx]
cmp al,32
jb s0
cmp al,120
ja s0
inc dx
s0:inc bx
loop s
(2) 补全下面的程序,统计F000:0处32个字节中,大小在(32,128)的数据的个数。
mov ax,0f000h
mov ds,ax
mov bx,0
mov dx,0
mov cx,32
s:mov al,[bx]
cmp al,32
jna s0
cmp al,120
jnb s0
inc dx
s0:inc bx
loop s
检测点11.4
下面的程序执行后:(ax)=?
mov ax,0
push ax
popf
mov ax,0fff0h
add ax,0010h
pushf
pop ax
and al,11000101B
and ah,00001000B
解:(ax)=01000101B
检测点12.1
(1) 用Debug查看内存,情况如下:
0000:0000 68 10 A7 00 8B 01 70 00-16 00 9D 03 8B 01 70 00
则3号中断源对应的中断处理程序的入口地址为:0070:018B 。
(2) 存储N号中断源对应的中断处理程序入口的偏移地址的内存单元的地址为:4N 。
存储N号中断源对应的中断处理程序入口的段地址的内存单元的地址为:4N+2 。
实验12 编写0号中断的处理程序
编写0号中断的处理程序,使得在除法溢出发生时,在屏幕中间显示字符串“divide error!”,然后返回到DOS。
解:
assume cs:code
code segment
start:
mov ax,cs
mov ds,ax
mov si,offset do
mov ax,0
mov es,ax
mov di,200h
mov cx,offset doend-offset do ;安装中断例程
cld
rep movsb
mov word ptr es:[0],200h
mov word ptr es:[2],0 ;设置中断向量表
mov dx,0ffffh
mov bx,1 ;测试一下
div bx
mov ax,4c00h
int 21h
do:jmp short dostart
db 'divide error!'
dostart:
mov ax,0
mov ds,ax
mov si,202h
mov ax,0b800h
mov es,ax
mov di,160*10+80
mov cx,13
s:
mov al,ds:[si]
mov ah,2
mov es:[di],ax
inc si
inc di
inc di
loop s
mov ax,4c00h
int 21h
doend:nop
code ends
end start
检测点13.1
(1) 在上面的内容中,我们用 7ch 中断例程实现loop的功能,则上面的 7ch 中断例程能进行的最大转移位移是多少?
解:8000H~7FFFH 即(-32768~32767)
(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 jp
mov ax,0
mov es,ax
mov di,200h
mov cx,offset jpend-offset jp ;安装中断例程
cld
rep movsb
mov word ptr es:[7ch*4],200h
mov word ptr es:[7ch*4+2],0 ;设置中断向量表
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
int 7ch
ok:mov ax,4c00h
int 21h
jp:push bp
mov bp,sp
add [bp+2],bx ;中断例程
pop bp
iret
jpend:nop
code ends
end start
检测点13.2
判断下面说法的正误:
(1)我们可以编程改变FFFF:0处的指令,使得CPU不去执行BIOS中的硬件系统检测和初始化程序。
答:错。因为该内存单元具有‘只读’属性。
(2)int 19h中断例程,可以由DOS提供。
答:这种说法是错误的。因为int 19h是在DOS启动之前就被执行的中断例程,是由BIOS提供的。
检测点14.1
(1)编程:读取CMOS RAM的2号单元的内容。
解:
assume cs:code
code segment
start:
mov al,2
out 70h,al
in al,71h
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
mov ax,4c00h
int 21h
code ends
end start
检测点14.2
编程:用加法和移位指令计算(ax)=(ax)*10
提示:(ax)*10=(ax)*2+(ax)*8
解:
assume cs:code
code segment
start:
mov ax,2
shl ax,1
mov bx,ax
shl ax,1
shl ax,1
add ax,bx
mov ax,4c00h
int 21h
code ends
end start
检测点15.1
(1)仔细分析一下上面的int 9中断例程,看看是否可以精简一下?
其实在我们的int 9中断例程中,模拟int指令调用原int 9中断例程的程序段是可以精简的,因为在进入中断例程后,IF和TF都已经置0,没有必要再进行设置可。对于程序段:
pushf
pushf
pop ax
and ah,11111100b
push ax
popf
call dword ptr ds:[0]
可以精简为:
pushf
call dword ptr ds:[0]
两条指令。
(2)仔细分析上面程序中的主程序[第269页],看看有什么潜在的问题?
在主程序中,如果在执行设置int 9中断例程的段地址和偏移地址的指令之间发生了键盘中断,则CPU将转去一个错误的地址执行,将发生错误。
找出这样的程序段,改写它们,排除潜在的问题。
提示:注意sti和cli指令的用法。
解:
将
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
扩充为:
cli
mov word ptr es:[9*4],offset int9
mov es:[9*4+2],cs
sti
检测点16.1
下面的程序将code段中a处的8个数据累加,结果存储到b处的双字中,补全程序。
assume cs:code
code segment
a dw 1,2,3,4,5,6,7,8
b dw 0,0 ;原题是b dd 0,0 但这样下面无法体现本节内容,估计是作者写错了,我在此更正
start: mov si,0
mov cx,8
s: mov ax,a[si]
add b,ax
adc b[2],0
add si,2
loop s
mov ax,4c00h
int 21h
code ends
end start
检测点16.2
下面的程序将code段中a处的8个数据累加,结果存储到b处的双字中,补全程序。
assume cs:code,es: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 es,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
上一篇: 汇编语言程序设计---1~4章习题答案(王爽第二版)
下一篇: 用Java实现双色球规则以及中奖结果