
- [thedaydreamwang] 有空把单精度的表示方法给我们讲下谢谢了!!感觉百度写的很不详细!!好久不见了哈!! 07/08 03:03
- [游客] 恩。非常有道理。 顶。。 07/05 18:52
- [游客] 我终于知道下一步该学什么了。 06/22 15:26
- [stcn] 我刚学汇编不久,看了这让我对编程语言有了更深入的了解了!以后一定要多关注技术的更新和发展趋势! 04/14 22:40
- [游客] 地址译码逻辑是不是应该在CPU内部啊? 04/08 22:34
- [scuzg] SP的初值=堆栈容量=栈底的偏移量+2。 而ss决定栈段起点。 即堆栈的所有结构元素都是由S 03/01 10:05
- [dwtqin] 还是有点模糊, 不懂,为什么栈是64K,没有说明64K从哪里得知 02/26 17:26
- [thedaydreamwang] 我是在错误中寻找正确的答案,需要自已用脑子思考我相信这是很重要的事情对一个人 01/21 07:55
- [dq051524] 穿上马甲评论 好不 01/15 16:27
- [regex] 学习~~~ 01/15 15:52
- [suixin] 少了个你,呵呵 “看着你的回答真长见识” 12/01 09:31
- [suixin] 看着的回答真长见识 12/01 09:29
- [fangorc] 先弄个友情链接,老师这的好东西太多了,慢慢消化~ 08/07 22:03
- [zdpopup] 谢谢scuzg 的宝贵意见,我看了2次你的话 08/05 01:43
- [游客] 过来踩踩。哈哈!端他爸 08/03 11:28
[2009-09-23 21:49]
存储器寻址小议(二):8086/8088的物理地址、段机制和逻辑地址
为寻址(或管理、使用)1M 字节的存储空间,8086/8088 CPU 设计有 20 条地址线。这 20 条地址线从全 0 到全 1 的 1M 种状态通过驱动地址译码逻辑,即可寻址 1M 字节的内存。
这从全 0 到全 1 的每一个二进制数,很自然地可以作为内存字节单元的编号,即地址;由于使用这种地址能直接控制地址译码器在物理上唯一地选通某个字节单元,故被称做“物理地址”。
程序是不能直接给出 20 位地址信息的,这是因为 8086/8088 CPU 可编程的 14 个寄存器都是 16 位的,更没有通过编程直接输出20 位地址信息的其他途径。20 位地址输出是通过来自段寄存器的和 CPU 内部总线(16位)的两个 16 位地址分量“移位相加”得到的(见上图)。显然,通过改变这两个 16 位地址分量,就可实现 1M 字节的寻址。
不过来自段寄存器的和来自 CPU 内部总线的两个 16 位地址分量的作用是不同的。由于段寄存器的内容左移后空出的四位均被自动充 0,又假设来自 CPU 内部总线的地址信息为零的话,单靠段寄存器只能定位 1M 字节空间内地址低四位为 0 的那些单元,并且 8086/8088 CPU 也没有提供单独通过段寄存器直接访问内存单元的指令;与此相反,来自内部总线的 16 位地址分量支持连续、灵活的变化和内存访问——不过如果不依赖段寄存器内容的帮助,这个地址分量也只能局限在 64K 的范围之内。
因此我们可以看出,段寄存器的内容决定了内存某一“段”的起点,这正是段寄存器名称的由来:段寄存器的内容左移四位,加上低四位自动填充的 0,就决定了一个段的起点,这个起点被称作“段基址”。显然,段寄存器保存的是段基址的高 16 位:段的起点只能从物理地址低四位为零的字节单元开始。
来自 CPU 内部总线的 16 位地址分量以段基址为起点,利用其连续、灵活的变化,即可遍历本段 64K 字节单元。由于这个地址分量本质上是所访问的字节单元到本段段基址的距离,所以被称作“偏移量”。
可见,20 位的物理地址只能通过编程可控的是段寄存器的内容(段基址高 16位)和 16 位偏移量间接地给出。可能是为了技术讨论方便并且和物理地址相区别,就把这两个地址分量合称为“逻辑地址”,习惯上写成这样:
段基址(的高16位): 偏移量
尽管逻辑地址确定的物理地址只有 20 位,但却无奈地占用了 32 位即 4 个字节的空间。
和物理地址与字节单元一一对应的关系不同,一个物理地址有可能对应若干个逻辑地址。这是因为可以调整两个地址分量的值,但使其结果仍然和原来的 20 位地址值相等。比如:
2053H:0100H
和:
2043H:0200H
2063H:0000H
计算出来的物理地址均为 20630H。至于一个物理地址最多可能对应多少个逻辑地址?有没有物理地址只有一个逻辑地址相对应?如果有那么这种物理地址和逻辑地址一一对应的单元有多少?它们的物理地址范围在哪一段?这些问题就留给有兴趣的朋友思考。
这从全 0 到全 1 的每一个二进制数,很自然地可以作为内存字节单元的编号,即地址;由于使用这种地址能直接控制地址译码器在物理上唯一地选通某个字节单元,故被称做“物理地址”。
程序是不能直接给出 20 位地址信息的,这是因为 8086/8088 CPU 可编程的 14 个寄存器都是 16 位的,更没有通过编程直接输出20 位地址信息的其他途径。20 位地址输出是通过来自段寄存器的和 CPU 内部总线(16位)的两个 16 位地址分量“移位相加”得到的(见上图)。显然,通过改变这两个 16 位地址分量,就可实现 1M 字节的寻址。
不过来自段寄存器的和来自 CPU 内部总线的两个 16 位地址分量的作用是不同的。由于段寄存器的内容左移后空出的四位均被自动充 0,又假设来自 CPU 内部总线的地址信息为零的话,单靠段寄存器只能定位 1M 字节空间内地址低四位为 0 的那些单元,并且 8086/8088 CPU 也没有提供单独通过段寄存器直接访问内存单元的指令;与此相反,来自内部总线的 16 位地址分量支持连续、灵活的变化和内存访问——不过如果不依赖段寄存器内容的帮助,这个地址分量也只能局限在 64K 的范围之内。
因此我们可以看出,段寄存器的内容决定了内存某一“段”的起点,这正是段寄存器名称的由来:段寄存器的内容左移四位,加上低四位自动填充的 0,就决定了一个段的起点,这个起点被称作“段基址”。显然,段寄存器保存的是段基址的高 16 位:段的起点只能从物理地址低四位为零的字节单元开始。
来自 CPU 内部总线的 16 位地址分量以段基址为起点,利用其连续、灵活的变化,即可遍历本段 64K 字节单元。由于这个地址分量本质上是所访问的字节单元到本段段基址的距离,所以被称作“偏移量”。
可见,20 位的物理地址只能通过编程可控的是段寄存器的内容(段基址高 16位)和 16 位偏移量间接地给出。可能是为了技术讨论方便并且和物理地址相区别,就把这两个地址分量合称为“逻辑地址”,习惯上写成这样:
段基址(的高16位): 偏移量
尽管逻辑地址确定的物理地址只有 20 位,但却无奈地占用了 32 位即 4 个字节的空间。
和物理地址与字节单元一一对应的关系不同,一个物理地址有可能对应若干个逻辑地址。这是因为可以调整两个地址分量的值,但使其结果仍然和原来的 20 位地址值相等。比如:
2053H:0100H
和:
2043H:0200H
2063H:0000H
计算出来的物理地址均为 20630H。至于一个物理地址最多可能对应多少个逻辑地址?有没有物理地址只有一个逻辑地址相对应?如果有那么这种物理地址和逻辑地址一一对应的单元有多少?它们的物理地址范围在哪一段?这些问题就留给有兴趣的朋友思考。
评论次数(3) |
浏览次数(737) |
类型(汇编语言) |
收藏此文 |
[ huibian2009 发表于 2009-11-12 10:12 ]
还是有点看不太懂,希望以后能向您请教一些问题。
[ dwtqin 发表于 2010-02-26 17:26 ]
还是有点模糊, 不懂,为什么栈是64K,没有说明64K从哪里得知
[ scuzg 发表于 2010-03-01 10:05 ]
SP的初值=堆栈容量=栈底的偏移量+2。
而ss决定栈段起点。
即堆栈的所有结构元素都是由SS、SP决定的。