1.
指令和数据在存储器(内存)中存放。CPU从内存中读取数据,首先要指定存储单元的地址。内存单元构成的存储空间是一维的线性空间。每个内存单元都有唯一的地址。
CPU通过地址总线指定存储器单元。
总线:
a. cpu有n根地址总线,就可以最多寻址2^n内存单元。
b. CPU与内存或其他器件之间的数据传送通过数据总线进行。数据总线的宽度决定cpu与外界的数据传送速度。
8086cpu数据总线宽度为16,一次可传送两个字节,也就是一个字。
c. 控制总线:cpu对外部器件的控制。
2
物理地址=段地址*16+偏移地址
因为段地址*16定位段的起始地址,用偏移地址定位段中的内存单元。所以一个段的起始地址一定是16倍数;偏移地址为16位,16位寻址能力为64kb,所以一个段最长为64kb。
8086cpu有4个段寄存器:cs,ds,ss,es。CPU访问内存时,由这几个段寄存器提供内存单元的段地址。、
8086工作过程:
从cs:ip指向的内存单元中读取指令,读取的指令进入指令缓冲器
ip指向下一条指令
执行指令
1
mov指令不能设置cs,ip的值。
jmp 段地址:偏移地址 可以修改cs,ip的值。
jmp 寄存器。可以修改ip的值。
3
ds寄存器存放访问的数据的段地址。8086不支持直接将数据送进段寄存器,用一个寄存器中转。(硬件设计问题)225
mov ds,1000h错误,不支持将立即数直接送入段寄存器。
mov ax,1000h
mov ds,ax正确
注意:1.不支持将立即数直接送入段寄存 器。
2段寄存器不可用在算数运算指令中。add ds,ax和add ax,ds均错误。
如图:
栈:8086入栈和出栈以字为单位。栈底在高地址。
push,pop指令执行时,cpu从ss,sp中得到栈顶的地址。
入栈时。栈顶从高地址向低地址增长。
栈空时,sp指向最高地址空间的下一个单元。
入栈时,sp-2
出栈,sp+2;
注意:8086不保证栈操作会不会越界。
栈顶的变化范围最大是64k(0~ffffh)
4
汇编程序:
(以下编译连接需要微软的masm的4个文件)
用文本编辑器编辑汇编源程序,生成.asm或.text文件
进入dos(单任务操作系统)方式,运行masm.exe,生成目标文件.obj,
用连接器link.exe,连接生成.exe文件。(当源程序很大时,可分成多个源程序进行编译,生成目标文件.obj后,再用连接器把他们连接起来生成可执行文件。
生成可执行文件后,要把它装载到内存运行(下文的P2)。在dos中,用户输入要执行的程序文件,由command找到文件,然后把它装载到内存,设置cs:ip指向程序的入口,并把控制权交给cpu(此时command放弃了cpu的控制权)。程序运行结束后,返回到command。
dos中程序在加载后,ds存放程序所在内存区的段地址,偏移地址为0。程序所在地址为ds:0。ds前256个字节存放psp,dos用来和程序通信的。因为psp占256字节,所以程序的物理地址为:SA*16+0+256=(SA+16)*16+0;所以程序的段地址和偏移地址为:SA+10h:0.(此时cs:ip指向这儿)
4.2源程序:
assume cs:code;assume(假设),将cs与程序中code segment...code ends定义的段相关联
code segment;伪指令,由编译器执行,segment同ends定义一个段
mov ax,0123h
mov ax,bx
mov ax,4c00h;
int 21h;
code ends;程序的结束,编译器遇到end结束编译
end
程序返回:程序经过编译连接转变为机器码,存在可执行文件中,那么他是如何得到运行
我们在DOS(一个单任务操作系统)的基础上,简单讨论:一个程序p2在可执行文件中,则必须有一个正在运行的程序p1将p2从可执行文件中加载到内存,把cpu的控制权交给p2,p2才能运行,此时p1暂停运行。当p2运行完毕,应将cpu的控制权交给使它得以运行的程序p1,此后p1继续运行。现在,我们知道,一个程序结束后,把cpu控制权交还给使它得以运行的程序,我们称之为:程序返回。
程序如何返回?应该在末尾添加返回程序段。
上图的mov ax,4c00h
int 21h;
实现程序返回。