本博客只有习题和答案,没有详细解析,如发现错误或者不理解的地方可以和博主交流。
第一章 基础知识
检测点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, 62627 | AX = F4A3 |
mov ah,31H | AX = 31A3 ¹ |
mov al,23H | AX = 3123 ² |
add ax,ax | AX = 6246 |
mov bx, 826CH | BX = 826C |
mov сx,ax | CX = 6246 |
mov ax,bx | AX = 826C |
add ax,bx | AX = 04D8 ³ |
mov al,bh | AX = 0482 |
mov ah,bl | AX = 6C82 |
add ah,ah | AX = D882 |
add al,6 | AX = D888 |
add al,al | AX = D810 ⁴ |
mov ax,cx | AX = 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