段地址

处理器负责执行指令,内存里面存着CPU要执行的指令。
当CPU通电之后,CPU内部所有的寄存器会进行复位,比如初始化成0000H,CPU就从这个地址开始提取指令,当然这是举例。

为了做某件事而编写的指令,当这样几条,几十条,甚至几百万条,几千万条这样的程序组合在一起,形成了我们平时所说的程序。
程序总要操作大量的数据,这些数据也应该集中在一起,位于内存中的某个地方,形成一个段,叫做数据段。


假定我们有16个数要相加,这些数都是16位的二进制数,分别是0005H、00A0H、00FFH、…。
为了让处理器把它们加起来,我们应该先在内存中定义一个数据段,将这些数字写进去。数据段可以起始于内存中的任何位置,既然如此,我们将它定在0100H处。

这样一来,第一个要加的数位于地址0100H,第二个要加的数位于地址0102H,最后一个数的地址是011EH。
一旦定义了数据段,我们就知道了每个数的内存地址。然后,紧挨着数据段,我们从内存地址0120H处定义代码段。

严格地说,数据段和代码段是不需要连续的,但这里把它们挨在一起更自然一些。为了区别数据段和代码段,我们使用了不同的底色。


代码段是从内存地址0120H处开始的,第一条指令是A1 00 01,其功能是将内存单元0100H里的字传送到AX寄存器。指令执行后,AX的内容为0005H。
第二条指令是03 06 02 01,功能是将AX中的内容和内存单元0102H里的字相加,结果在AX中。由于AX的内容为0005H,而内存地址0102H里的数是00A0H,这条指令执行后,AX的内容为00A5H。
第三条指令是03 06 04 01,功能是将AX中的内容和内存单元0104H里的字相加,结果在AX中。此时,由于AX里的内容是00A5H,内存地址0104H里的数是00FFH,本指令执行后,AX的内容为01A4H。
图2-






我们的程序OK,搞定了。
但是平常我们使用计算机的时候,游戏,视频,操作系统已经把内存占用了。

当我们在操作系统里面,双击一个这样的程序运行的时候,它很可能压根不会运行成功。
因为操作系统,会考虑哪里的内存比较空闲,就把这些指令放到哪里去。
可能把我们这些数据段和代码段放到了1000H的内存地址。

而我们指令相加的内存地址却是0100……0104.。这肯定就出问题了。。








我们让指令运行的时候,定位数据用的是绝对的内存地址。
这样子程序真正执行的知道,被操作系统不知道分配到哪个内存位置了,就出问题了。

所以,我们只能使用相对地址。
当然,CPU的设计者们也为我们考虑到这些问题了,那么如何解决这个问题呢?


在8086 16位CPU中,除了我们刚才学习的几个通用寄存器,再介绍两个寄存器,这两个寄存器分别为:
代码段寄存器  CS  [Code Segment]
数据段寄存器  DS  [Data Segment]
附加段几次器  ES  [Extra Segment]
指令寄存器     IP   它和CS一起使用。

栈段寄存器    SS 










当CPU要运行我们程序的时候,首先把CS和DS的位置确定下来,然后放到这两个寄存器里面。
CS和IP共用形成逻辑地址,并经过CPU的一个部件变成物理地址来取得指令。
访问内存则使用DS加偏移

按照套路8086应该最大只有64KB内存。
但是64KB太小了。

内存的大小取决于CPU可以定位的范围和物理内存本身的大小。


0000 0000 0000 0000
1111 1111 1111 1111  地址定位
FFFF = 65536 =64KB的内存
1111 1111 1111 1111 1111  地址定位。 

这样子可以定位1MB的内存.
00000H到FFFFFH

而寄存器却都是16位的。
CS:0008
IP: 0003
CS:IP= 0008:0003 =000B 真实的内存物理地址。

但却是00080:0003=00083



 


 

所以,这个问题可以这样理解。
我有两个16位寄存器最大都可以表示 FFFF
现在我要通过这两个寄存器的组合,能够表示FFFFF


为了让大家能够理解这种工作模式,我们转换成十进制给大家理解。

A最大可以表示9999,最小为0000 
B最大可以表示9999 , 最小为0000
C最大可以表示99999,最小为00000

我们怎么样可以用A和B来表示C呢?
假如A是1230,B是80
那么A x 10 + B= 12300+80 =12380

A和B C
9999:0009 99999
9999:0008 99998
9999:0007 99997
9999:0006 99996
9999:0005 99995
9999:0004 99994
9999:0003 99993
9999:0002 99992
9999:0001 99991
9999:0000 99990
... ...
... ...
... ...
0001:0009 00019
0001:0008 00018
0001:0007 00017
0001:0006 00016
0001:0005 00015
0001:0004 00014
0001:0003 00013
0001:0002 00012
0001:0001 00011
0001:0000 00010
0000:0009 00009
0000:0008 00008
0000:0007 00007
0000:0006 00006
0000:0005 00005
0000:0004 00004
0000:0003 00003
0000:0002 00002
0000:0001 00001
0000:0000 00000

 

 

十六进制

A和B C
FFFF:000F FFFFF
FFFF:000E FFFFE
FFFF:000D FFFFD
FFFF:000C FFFFC
FFFF:000B FFFFB
FFFF:000A FFFFA
FFFF:0009 FFFF9
FFFF:0008 FFFF8
FFFF:0007 FFFF7
FFFF:0006 FFFF6
FFFF:0005 FFFF5
FFFF:0004 FFFF4
FFFF:0003 FFFF3
FFFF:0002 FFFF2
FFFF:0001 FFFF1
FFFF:0000 FFFF0
... ...
... ...
... ...
0001:000F 0001F
0001:000E 0001E
0001:000D 0001D
0001:000C 0001C
0001:000B 0001B
0001:000A 0001A
0001:0009 00019
0001:0008 00018
0001:0007 00017
0001:0006 00016
0001:0005 00015
0001:0004 00014
0001:0003 00013
0001:0002 00012
0001:0001 00011
0001:0000 00010
0000:000F 0000F
0000:000E 0000E
0000:000D 0000D
0000:000C 0000C
0000:000B 0000B
0000:000A 0000A
0000:0009 00009
0000:0008 00008
0000:0007 00007
0000:0006 00006
0000:0005 00005
0000:0004 00004
0000:0003 00003
0000:0002 00002
0000:0001 00001
0000:0000 00000
0000:0000-0000:000F
0001:0000-1000:000F
0002:0000-0002:000F
FFFF:0000-FFFF:000F

把1M的内存分成了65536个段,每个段16个字节。


当然,这只是一种组合定位物理地址的方法。
我们还可以这么定位。
0000:0000 - 0000:FFFF
1000:0000 - 1000:FFFF
2000:0000 - 2000:FFFF
F000:0000 -F000:FFFF 

把1M的内存分成了16个段,每个段64KB

这是两种不同的分法:
比如FFFF:000F和F000:FFFF其实是一个物理地址。


假设现在物理地址00000H-82251H都被其他程序占用了。
二后面82252H-FFFFFH,都是空闲的。
为了让我们的程序能够加载。
我们可以选择82260H这个位置。然后把DS:偏移设置成8226H:0000H
因为我们要让偏移的初值地址为0000

转载于:https://www.cnblogs.com/xiaodaxiaonao/p/7135232.html

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值