Cpu从内存读取数据过程

- cpu通过地址线将地址信息3发出
- cpu通过控制线发出内存读命令,选中存储器芯片,并通知他,将要从中读取数据。
- 存储器将3号单元中的数据8通过数据线送入cpu。
写操作和读操作的步骤相似,如向3号单元写入数据26 - cpu通过地址线将信息3发出。
- cpu通过控制线发出内存写命令,选中存储器芯片,并通知他,将要从中写入数据。
- cpu通过数据线将数据26送入内存的3号单元。
地址总线
一个cpu又N根地址线,则可以说这个cpu的地址总线的宽度位N,这样的CPU最多可以寻找2的N次方个内存单元。
数据总线
CPU与内存或者其他器件之间的数据传送是通过数据总线来进行的。数据总线的宽度决定了CPU和外界的数据传送速度,8根数据总线一次可传送一个8位二进制数据。16根数据总线一次可以传送两个字节。
通用寄存器
8086CPU的所有寄存器都是16位的,可以存放两个字节。AX、BX、CX、DX这4个寄存器通常用来存放一般性的数据,被称为通用寄存器。
- AX可分为AH和AL;
- BX可分为BH和BL;
- CX可分为CH和CL;
- DX可分为DH和DL;
8086CPU地址加法器

段寄存器
段地址在8086CPU的段寄存器中存放。8086CPU有4个段寄存器:CS、DS、SS、ES。
CS和IP
CS和IP是8086中两个最关键的寄存器,CS为代码段寄存器,IP为指令指针寄存器。
在8086PC机种,任意时刻,设CS中的内容为M,IP中的内容为N,那么8086CPU将从M×16+N单元开始,读取一天指令并执行。

修改CS和IP寄存器
mov指令不能修改CS和IP的值
若想同时修改CS和IP的值:“jmp 段地址:偏移地址”
jmp 2AE3:3 执行后:CS=2AE3H ,IP=0003H ,CPU将从2AE33H处读取指令。
若想修改IP的内容,可用“jmp 某一合法寄存器”指令完成
功能:用寄存器中的值修改IP
如:
jmp ax 指令执行前:ax=1000H,CS=2000H,IP=0003H
执行后:ax=1000H,CS=2000H,IP=0003H
DS寄存器和[ADDRESS]
8086cpu有个DS寄存器,通常用来存放要访问的数据的段地址。如要读取10000H单元的内容,可用以下程序:
mov bx,10000H
mov ds,bx
mov al,[0]
[…]表示一个内存单元,[0]表示内存单元的偏移地址0,
只有偏移地址并不能定位内存单元,所以执行指令时,8086cpu会自动取DS中的数据为内存单元的段地址。
如何用mov指令从10000H中读取数据。10000H用段地址和偏移地址表示为1000:0,我们先将段地址1000H放入ds,然后用mov al,[0]完成传送。mov指令中的[]说明操作对象是一个内存单元,[]中的0说明这个内存单元的偏移地址是0,它的段地址默认放在ds中,指令执行时,8086CPU会自动从ds中取出。
mov bx,1000H
mov ds,bx
写几条指令,将al中的数据传送如内存单元10000H:
mov bx,1000H
mov ds,bx
mov [0],al
[BX]和loop指令
1.[bx]是什么?和[0]有些类似,[0]表示内存单元,他的偏移地址是0.
mov ax,[0]
将一个内存单元的内容送入ax,这个内存单元的长度为2字节,存放一个字,偏移地址为0,段地址在ds中。
mov al,[0]
将一个内存单元的内容放入al,这个内存单元的长度为1字节,存放一个字节,偏移地址为0,段地址在ds中。
[bx]同样也表示一个内存单元,他的偏移地址在bx中,如:
mov ax,[bx]
将一个内存单元的内容送入ax,内存单元长度为2字节,存放一个字,偏移地址在bx中,段地址在ds中
mov al,[bx]
将一个内存单元的内容送入a1,内存单元长度为1字节,存放一个字节,偏移地址在bx中,段地址在ds中
2.描述符号:()
描述符号()来表示一个寄存器或一个内存单元的内容。比如:(ax)表示ax中的内容
注:()中的元素可以有三种类型:1 寄存器名;2段寄存器名;3内存单元的物理地址
loop指令
用加法计算123*236,结果存在ax中:
assume cs:code
code segment
mov ax,0
mov cx,236
s:add ax,123
loop s
mov ax,4c00h
int 21h
code ends
在代码段中使用数据
编程计算8个数据的和,结果保存在ax中
0123h、0456h、0789h、…..
assume cs:code
code segment
dw 0123h,0456h…….
mov bx,0
mov ax,0
mov cx,8
s:add ax,cs:[bx]
add bx,2
loop s
mov ax,4c00h
int 21h
code ends
end
注:dw的含义是定义字型数据。dw即“define word”
程序中的指令就要对这8个数据进行累加,可这8个数据在哪里呢?由于他们在代码段中,程序在运行的时候cs中存放代码段的段地址,所以可一次从cs中得到他们的段地址。偏移地址为0,这8个数据就在代码段的便宜0、2、3、4.。。。处。对应的地址就是CS:0,CS:2,CS:4………
代码段标号:
assume cs:code
code segment
.
.
.
数据
start:
.
.
.
代码
.
.
.
code end
end start
6.2 在代码段中是用栈
完成下面程序,利用栈,将程序中定义的数据逆序存放。
assume cs:codesg
codeset sement
dw 0123h,0456h,……
codesg ends
end

and和or指令
and指令:逻辑与指令,按位进行与运算。
mov al, 01100011B
and al, 00111011B
执行后:al=00100011Bor指令:逻辑或指令,按位进行或运算
mov al,01100011B
or al,00111011B
执行后:al=01111011B
汇编实现大小写转换
assume cs:codessg,ds:datasg
datasg segment
db ‘BaSic’
db ‘iNfOrMaTion’
datasg ends
codesg segment
start:mov ax,datasg
mov ds,ax
mov bx,0
mov cx,5
s:mov al,[bx]
如果(al)>61H,则为小写字母的ASCII码,则:sub al,20H
mov [bx],al
inc bx
loop s
codesg ends
end start
[bx+idata]
在前面,我们用[bx]的方式来指明一个内存单元,还可以用[bx+idata]表示一个内存单元,偏移地址为(bx)+idata(bx中的数值加上idata)。
指令 mov ax,[bx+200]的含义:
将一个内存单元的内容送入ax,这个内存单元的长度为2个字节,偏移地址为bx中的数值加上200,段地址在ds中
数学化的描述为:(ax)=((ds)*16+(bx)+200)
mov ax,[200+bx]
mov ax,200[bx]
mov ax,[bx].200
SI和DI
si和di是8086CPU中和bx功能相近的寄存器,si和di不能够分成两个8位寄存器来使用。下面的3组指令实现了相同的功能
mov bx,0
mov ax,[bx]mov si,0
mov ax,[si]
3.mov di,0
mov ax,[di]
[bx+si]和[bx+di]
我们以[bx+si]为例进行讲解
[bx+si]表示一个内存单元,它的偏移地址为(bx)+(si)(即bx中的数值加上si中的数值)
mov ax,[bx+si]:
将一个内存单元的内容送入ax,偏移地址位bx中的数值加上si中的数值,段地址在ds中
(ax)=((ds)*16+(bx)+(si))
或
mov ax,[bx][si]
[bx+si+idata]和[bx+di+idata]
指令mov ax,[bx+si+idata]的含义如下:
将一个内存单元的内容送入ax,这个内存单元的长度为2字节,偏移地址为bx中的数值再加上idata,段地址在ds中。
数学化的描述位:(ax) = ((ds)*16+(bx)+(si)+idata)
不同的寻址方式的灵活应用
- [idata]用一个常量来表示地址,可用于直接定位一个内存单元;
- [bx]用一个变量来表示内存地址,可用于间接定位一个内存单元;
- [bx+idata]用一个变量和常量表示地址,可在一个起始地址的基础上用变量间接定位一个内存单元;
- [bx+si]用两个变量表示地址;
- [bx+si+idata]用两个变量和一个常量表示地址。