汇编语言程序设计---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
  • 5
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小天才才

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值