汇编语言习题和实验-答案(王爽版)

本博客只有习题和答案,没有详细解析,如发现错误或者不理解的地方可以和博主交流。

第一章 基础知识

检测点1.1

(1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为 13
(2)1KB的储存器有 1024 个储存单元。储存单元的编号从 0 1023
(3)1KB的存储器可以存储 1024*8 个bit, 1024 个Byte。
(4)1GB、1MB、1KB分别是 102 4 3 1024^3 10243 102 4 2 1024^2 10242,1024 Byte。
(5)8080、8088、80286、80386的地址总线分别为16根、20根、24根、32根,则他们的寻址能力分别为: 64 (KB)、 1 (MB)、 16 (MB)、 4 (GB).
(6) 8080、 8088、 8086、80286、 80386的数据总线宽度分别为8根、8根、16根、16根、32根。则它们一-次可以传送的数据为:1 (B)、 1 (B)、 2 (B)、 2 (B)、 4 (B)。
(7)从内存中读取1024字节的数据,8086至少要读 512 次,80386至少要读 256 次。
(8)在存储器中,数据和程序以 二进制 形式存放。

第二章 寄存器

检测点2.1

(1)写出每条汇编指令执行后相关寄存器中的值。

汇编指令相关寄存器中的值
mov ax, 62627AX = F4A3
mov ah,31HAX = 31A3 ¹
mov al,23HAX = 3123 ²
add ax,axAX = 6246
mov bx, 826CHBX = 826C
mov сx,axCX = 6246
mov ax,bxAX = 826C
add ax,bxAX = 04D8 ³
mov al,bhAX = 0482
mov ah,blAX = 6C82
add ah,ahAX = D882
add al,6AX = D888
add al,alAX = D810
mov ax,cxAX = 6246

注解:
1:只对ah寄存器中的值进行操作,al中的值不变,所以 ah = 31 al = A3。
2:H表示16进制下的值,寄存器表示均为16进制。
3:AX = 104D8 数据溢出,AX保留04D8。
4:只对al进行运算,al溢出不会到ah里面,所以al保留10,ah不变。

(2)只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。

mov ax,2
add ax,ax
add ax,ax
add ax,ax

检测点2.2

(1)给定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围为 00010H 1000FH
(2)有一数据存放在内存 20000H 单元中,现给定段地址为 SA,若想用偏移地址寻到此单元。则 SA应满足的条件是:最小为 1001H ,最大为 2000H

检测点2.3

4次,0000H
解释:每条指令读取后都会修改偏移量寄存器IP,所以mov、sub、jmp执行各修改一次,最后执行jmp把IP中的值修改为ax寄存器中的值,由于sub已经把ax中的值变成了0,所以IP中的值也被修改成0。

检测点3.1

(1)2662,E626,E626,2662,D6E6,FD48,2C14,0000,00E6,0000,0026,000C。
(2)

mov ax,6622H					CS=2000H, IP=0003H, DS=1000H, AX=6622H, BX=0000H
jmp 0ff0:0100 					CS=0FF0H, IP=0100H, DS=1000H, AX=6622H, BX=0000H
mov ax,2000H					CS=0FF0H, IP=0103H, DS=1000H, AX=2000H, BX=0000H
mov ds,ax						CS=0FF0H, IP=0105H, DS=2000H, AX=2000H, BX=0000H
mov ax,[0008]					CS=0FF0H, IP=0108H, DS=2000H, AX=C389H, BX=0000H
mov ax,[0002]					CS=0FF0H, IP=010BH, DS=2000H, AX=EA66H, BX=0000H

检测点3.2

(1)

mov ax,1000H
mov ds,ax
mov ax,2000H 
mov ss,ax
mov sp,0010H
push [0]
push [2]
push [4]
push [6]
push [8]
push [A]
push [C]
push [E]

(2)

mov ax,2000H
mov ds,ax
mov ax,1000H
mov ss,ax
mov sp,0010H
pop [E]
pop [X]
pop [A]
pop [8]
pop [6]
pop [4]
pop [2]
pop [0]

检测点6.1

(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)

codesg ends

end startassum cs:codesg

codesg segment
	dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
	dw 0,0,0,0,0,0,0,0,0,0

start:
	mov ax,cs
	mov ss,ax
	mov sp,0024h

	mov ax,0
	mov ds,ax
	mov bx,0
	mov cx,8

s:	push[bx]
	pop cs:[bx]
	add bx,2
	loop s

	mov sx,4c00h
	int 21h

codesg ends

end start

实验五

(1)
在这里插入图片描述
在这里插入图片描述
(2)
除了data段中的数据有变化,其他的没变化
段实际占有的空间以16个字节为单位
(5)不一定最简洁,但是运行了一下功能正常

assume cs:code

a segment
	db 1,2,3,4,5,6,7,8
a ends

b segment
	db 1,2,3,4,5,6,7,8
b ends

c segment
	db 0,0,0,0,0,0,0,0
c ends

code segment

start:
	mov bx,0
	mov cx,8
s:	mov ax,a
	mov ds,ax
	mov dl,[bx]
	mov ax,b
	mov ds,ax
	add dl,[bx]
	mov ax,c
	mov ds,ax
	mov [bx],dl
	inc bx
	loop s

	mov ax,4c00h
	int 21h

code ends

end start

(6)思路应该是把b段当成栈,然后前八个字形的一次入栈就行了,但是a段定义的是子类型的,所以不可以直接用内存入栈,需要把a段中的数据逐个移到字型寄存器中再入栈。

实验7

assume cs:codesg

data segment
	db '1975','1976','1977','1978','1979','1980','1981','1982','1983'
	db '1984','1985','1986','1987','1988','1989','1990','1991','1992'
	db '1993','1994','1995'

	dd 16,22,382,1356,2390,8000,16000,24486,50065,97479,140417,197514
	dd 345980,590827,803530,1183000,1843000,2759000,3753000,4649000,5937000
	
	dw 3,7,9,13,28,38,130,220,476,778,1001,1442,2258,2793,4037,5635,8226
	dw 11542,14430,15257,17800
data ends

table segment
	db 21 dup ('year summ ne ?? ')
table ends

stack segment
	db 16 dup (0)
stack ends

codesg segment
start:
	mov ax,stack
	mov ss,ax
	mov sp,10h
	mov ax,table
	mov es,ax
	mov cx,21
	mov si,0
	mov di,0
s0:	push cx
	mov bx,0

	mov ax,data
	mov ds,ax
	mov cx,3
s1:	mov ax,[bx+di]
	mov es:[bx+si],ax
	inc bx
	loop s1

	mov cx,2
;	mov ax,[bx+di+81] != mov ax,[bx,di+81h]
s2:	mov ax,[bx+di+81]
	mov es:[bx+si+2],ax
	inc bx
	inc bx
	loop s2

	inc bx
	mov ax,di
	mov di,2
	div di
	mov di,ax
	mov ax,[bx+di+160]
	mov es:[bx+si+2],ax
	add di,di
	
	add si,10h
	add di,4h
	pop cx
	loop s0

	mov ax,4c00h
	int 21h
codesg ends

end start

运行结果:
在这里插入图片描述
注:这个程序基本上总结了以上所有学过的知识;因为内存显示的是16进制数值,所以后边的ASCII码部分是乱码;里边的81和160是通过推算和实验得出来的。

检测点9.1

(1)答案:db 3 dup(0)
解释:jmp word ptr [bx+1]就是把内存ds:[bx+1]地址开始的字放到IP寄存器中,如果想让CS:IP指向程序第一条指令只需要IP等于0就可以了,所以数据段应该为0,因为使用的是bx+1所以必须要三个字节的数据。
(2)
答案:bx cs
(3)

CS=0006H
IP=00BEH

检测点9.2

mov cx,0
mov cl,[bx]
inc bx
jcxz ok

检测点9.3

inc cx

检测点10.1

1000H,0H

检测点10.2

ax为6
call是把下一步的地址IP值压入栈

检测点10.3

1010H
先从栈中取出IP=8h放入ax,然后让ax乘以2,再从栈中去除CS=1000h与ax相加之后放入ax,所以ax此时为1010H

检测点10.4

ax=0BH

检测点10.5

(1)
3
(2)
ax=1,bx=0

检测点11.1

sub al,al     al=0h        ZF=1        PF=1        SF=0 

mov al,1      al=1h        ZF=1        PF=1        SF=0 

push ax       ax=1h        ZF=1        PF=1        SF=0 

pop bx        bx=1h        ZF=1        PF=1        SF=0 

add al,bl     al=2h        ZF=0        PF=0        SF=0 

add al,10     al=12h       ZF=0        PF=1        SF=0 

mul al        ax=144h      ZF=0        PF=1        SF=0

检测点11.2

              al(16进制/2进制)    CF    OF    SF    ZF    PF

sub al,al     0h/0000 0000b      0     0     0     1     1

mov al,10h    10h/0010 0000b     0     0     0     1     1

add al,90h    a0h/1010 0000b     0     0     1     0     1

mov al,80h    80h/1000 0000b     0     0     1     0     1

add al,80h    0h/0000 0000b      1     1     0     1     1

mov al,0fch   0fch/1111 1100b    1     1     0     1     1

add al,05h    1h/0000 0001b      1     0     0     0     0

mov al,7dh    7dh/1111 1101b     1     0     0     0     0

add al,0bh    88h/1000 1000b     0     1     1     0     1

检测点11.3

(1)

jb s0         ;如果低于al转到s0,继续循环
ja s0         ;如果高于al转到s0,继续循环

(2)

jna s0        ;如果不高于al转到s0,继续循环
jnb s0        ;如果不低于al转到s0,继续循环

检测点11.4

推算过程:

popf后,标志寄存器中,本章节介绍的那些标志位都为0(但是此时标志寄存器并不是所有位置都为0,这个不用关心,没学过的位置用先代替),向下进行,那么pushf将计算后的当时状态的标志寄存器入栈,然后pop给ax,这是ax是寄存器的值(这个值中包含了我们的号),接下来就是对那些没有学过的标志位的屏蔽操作,这就是最后两条指令的意义所在,将不确定的位置都归0,那么只剩下我们能够确定的位置了,所以,结果就可以推理出来了。

mov ax,0  

push ax  

popf  

mov ax,0fff0h  

add ax,0010h  

pushf

pop ax               0  0  0  0  of df if tf sf zf 0  af 0  pf 0  cf

                     0  0  0  0  0  0  *  *  0  1  0  *  0  1  0  1

                     ax=flag=000000** 010*0101b

and al,11000101B     al=01000101b=45h

and ah,00001000B     ah=00000000b=0h

检测点12.1

(1)
0070:018b
在这里插入图片描述

(2)
存储N号中断源对应的中断处理程序入口的偏移地址的内存单元的地址为: 4N
存储N号中断源对应的中断处理程序入口的段地址的内存单元的地址为: 4N+2
注:N可以从0开始

检测点13.1

(1)
最大位移是FFFFH
(2)

assume cs:code  
code segment 
start:
		mov ax,cs 
		mov ds,ax 
		mov si,offset do0                ;设置ds:si指向源地址 
		mov ax,0 
		mov es,ax 
		mov di,200h                      ;设置es:di指向目标地址 
		mov cx,offset do0end-offset do0  ;设置cx为传输长度 
		cld                              ;设置传输方向为正 
		rep movsb 
		mov ax,0 
		mov es,ax 
		mov word ptr es:[7ch*4],200h 
		mov word ptr es:[7ch*4+2],0      ;设置中断向量表 
		mov ax,4c00h 
		int 21h 
do0:
		push bp
		mov bp,sp
     	add [bp+2],bx                    ;ok的偏移地址+bx得到s的偏移地址
		pop bp
		iret
		mov ax,4c00h 
		int 21h 
do0end:
    	nop
code ends
end start

检测点13.2

判断下面说法的正误:

(1)错误,FFFF:0处的内容无法改变。

(2)错误,先调用int 19h,后启动DOS。

检测点14.1

(1)

assume cs:code

code segment

start:  mov al,2        ;赋值al

        out 70h,al      ;将al送入端口70h

        in al,71h       ;从端口71h处读出单元内容

        mov ax,4c00h

        int 21h

code ends

end start

(2)

assume cs:code

code segment

start:  mov al,2        ;赋值al

        out 70h,al      ;将al送入端口70h

        mov al,0        ;赋值al

        out 71h,al      ;向端口71h写入数据al

        mov ax,4c00h

        int 21h

code ends

end start

检测点14.2

assume cs:code

code segment

start:  mov bx,ax

        shl ax,1   ;左移1位(ax)=(ax)*2

        mov cl,3

        shl bx,cl       ;左移3位(bx)=(ax)*8

        add ax,bx       ;(ax)=(ax)*2+(ax)*8

        mov ax,4c00h

        int 21h

code ends

end start
  • 4
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
检测点1.1 (1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为 13位。 (2)1KB的存储器有 1024 个存储单元,存储单元的编号从 0 到 1023 。 (3)1KB的存储器可以存储 8192(2^13) 个bit, 1024个Byte。 (4)1GB是 1073741824 (2^30) 个Byte、1MB是 1048576(2^20) 个Byte、1KB是 1024(2^10)个Byte。 (5)8080、8088、80296、80386的地址总线宽度分别为16根、20根、24根、32根,则它们的寻址能力分别为: 64 (KB)、 1 (MB)、 16 (MB)、 4 (GB)。 (6)8080、8088、8086、80286、80386的数据总线宽度分别为8根、8根、16根、16根、32根。则它们一次可以传送的数据为: 1 (B)、 1 (B)、 2 (B)、 2 (B)、 4 (B)。 (7)从内存中读取1024字节的数据,8086至少要读 512 次,80386至少要读 256 次。 (8)在存储器中,数据和程序以 二进制 形式存放。 解题过程: (1)1KB=1024B,8KB=1024B*8=2^N,N=13。 (2)存储器的容量是以字节为最小单位来计算的,1KB=1024B。 (3)8Bit=1Byte,1024Byte=1KB(1KB=1024B=1024B*8Bit)。 (4)1GB=1073741824B(即2^30)1MB=1048576B(即2^20)1KB=1024B(即2^10)。 (5)一个CPU有N根地址线,则可以说这个CPU的地址总线的宽度为N。这样的CPU最多可以寻找2的N次方个内存单元。(一个内存单元=1Byte)。 (6)8根数据总线一次可以传送8位二进制数据(即一个字节)。 (7)8086的数据总线宽度为16根(即一次传送的数据为2B)1024B/2B=512,同理1024B/4B=256。 (8)在存储器中指令和数据没有任何区别,都是二进制信息。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值