检测点 1.1
(1)1个 CPU 的寻址能力为 8KB,那么它的地址总线的宽度为 13
.
(2)1KB 的存储器有 1024
个存储单元。存储单元的编号从 0
到1023
。
(3)1KB 的存储器可以存储8192
个bit,1024
个Byte
(4)1GB、1MB、1KB分别是2^30,2^20,2^10
Byte.
(5)8080、8088、80286、80386 的地址总线宽度分别为 16根、20根、24根、32根,则它们的寻址能力分别为:64KB
、1MB
、16MB
、4GB
。
(6)8080、8088、8086、80286、80386 的数据总线宽度分别为 8根、8根、16根、16根、32根。则它们一次可以传送的数据为:1B
、1B
、2B
、2B
、4B
。
(7)从内存中读取 1024 字节的数据,8086 至少要读512
次,80386 至少要读256
次。
(8)在存储器中,数据和程序以二进制
形式存放。
检测点 2.1
(1)写出每条汇编指令执行后相关寄存器中的值。
mov ax,62627 AX=F4A3H
mov ah,31H AX=31A3H
mov al,23H AX=3123H
add ax,ax AX=6246H
mov bx,826CH AX=826CH
mov cx,ax AX=6246H
mov ax,bx AX=826CH
add ax,bx AX=04D8H
mov al,bh AX=0482H
mov ah,bl AX=6C82H
add ah,ah AX=D882H
add al,6 AX=D888H
add al,al AX=D810H
mov ax,cx AX=6246H
(2)只能使用目前学过的汇编指令,最多使用 4 条指令,编程计算 2 的 4 次方。
mov ax,2 AX=2
add ax,ax AX=4
add ax,ax AX=8
add ax,ax AX=16
检测点2.2
(1)给定短地址为 0001H,仅通过变化偏移地址寻址,CPU 的寻址范围为 00010H
到1000FH
(偏移地址16位最多可寻 64KB个内存单元,即FFFF - 段地址 * 16)
(2)有一数据存放在内存 20000H,现给定段地址为 SA,若想用偏移地址寻到此单元。则 SA 应满足的条件是:最小为1001H
,最大为2000H
。(提示,反过来思考一下,当段地址给定为多少,CPU 无论怎么变化偏移地址都无法寻到 20000H 单元?)
最大段地址:X*16=20000H
X=2000H
最小段地址:X*16+FFFF=20000H
X*16=10001H
但是X右移一位为1000H<1000.1H
所以X=1001H
检测点 2.3
下面的3条指令执行后,cpu几次修改IP?都是在什么时候?最后IP中的值是多少?
mov ax,bx
sub ax,ax
jmp ax
- 第一次:读取mov ax,bx之后
- 第二次:读取 sub ax,ax之后
- 第三次:读取jmp ax 之后
- 第四次:执行jmp ax修改IP
最后IP的值为0000H,因为最后ax中的值为0000H,所以IP中的值也为0000H
检测点 3.1
(1)在 Debug 中,用 “d 0:0 1f
”查看内存,结果如下。
下面的程序执行前,AX=0,BX=0,写出每条汇编指令执行完后相关寄存器中的值。
(2)各寄存器的初始值:CS=2000H,IP=0,DS=1000H,AX=0,BX=0;
- 写出 CPU 执行的指令序列(用汇编指令写出);写出 CPU 执行每条指令后,CS、IP和相关寄存器中的数值。
```shell
CS=2000H,IP=3,DS=1000H,AX=6622,BX=0
mov ax,6622H
CS=0ff0H,IP=0100,DS=1000H,AX=6622,BX=0 这里中断了
jmp 0ff0:0100
CS=0FF0H,IP=0103,DS=1000H,AX=2000H,BX=0
mov ax,2000H
CS=0FF0H,IP=0105,DS=2000H,AX=2000H,BX=0
mov ds,ax
CS=0FF0H,IP=0108,DS=2000H,AX=C389H,BX=0
mov ax,[0008]
CS=0FF0H,IP=010B,DS=2000H,AX=EA66,BX=0
mov ax,[0002]
2. 再次体会:数据和程序有区别吗?如何确定内存中的信息哪些是数据,哪些是程序?
数据和程序在计算机中都是以二进制的形式存放的,在区别程序和数据时,关键是看段地址,如果段地址是`DS`段,说明该内存存放的是数据,如果段地址是`CS`段,说明该内存存放的是指令。
<a name="cCVnw"></a>
# 检测点3.2
```shell
(1)
mov ax,2000
mov ss,ax
mov sp,0010
(2)
mov ax,1000
mov ss,ax
mov sp,0000
检测点 6.1
(1)下面的程序实现依次用内存0:0~0:15单元中的内容改写程序中的数据,完成程序:
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
start: mov ax,0
mov ds,ax ;初始化数据段地址指向段地址0的位置
mov bx,0
mov cx,8 ;寄存器是16位结构的,刚好8个字型数据所以循环8次
s: mov ax,[bx]
;--------------------------修改地方-------------------------------
mov cs:[bx],ax ;程序启动cs自动定位到程序的地址
;因此是dw的数据是在代码段cs偏移地址为0-15的内存单元上的
;-----------------------------------------------------------------
add bx,2 ;一个字型数据占两个内存单元,每次偏移2
loop s
mov ax,4c00h
int 21h
codesg ends
end start
(2)下面的程序实现依次用内存0:0~0:15单元中的内容改写程序中的数据,数据的传送用栈来进行。栈空间设置在程序内。完成程序:
assume cs:codesg
codesg segment
dw 0123h,0456h,0789h,0abch,0defh,0fedh,0cbah,0987h
dw 0,0,0,0,0,0,0,0,0,0 ;10个字单元用作栈空间
;----------------修改地方1------------------------
start: mov ax,cs ;因为栈的段地址也为当前代码段所在的段地址,
;而代码段的地址,在运行程序时会自动指向程序代码的段地址
;-------------------------------------------------
mov ss,ax ;设置栈的段地址和偏移地址
;----------------修改地方2-------------------------
mov sp,24h ;这里可以是十六进制的24h也可以是十进制的36
;-------------------------------------------------
mov ax,0
mov ds,ax ;设置数据段的段地址为0,即从0:0地址开始读取数据
mov bx,0
mov cx,8
s: push [bx] ;不写段前缀默认为ds,此时把0:[bx]地址的数据入栈
;----------------修改地方3-----------------------
pop cs:[bx] ;这里是把入栈的数据改写掉程序中的数据,而程序中的数据
;在cs这个数据段的cs:[0]-[15];所以是cs:[bx]
;也可以写成ss:[bx] ,上面ss已经赋值为cs中的值了
;-----------------------------------------------
add bx,2
loop s
mov ax,4c00H
int 21h
codesg ends
end start