80x86 汇编语言:存储器分段管理

  8088/8086 CPU,有 20 条地址线,用于连接存储器芯片。
  因此,存储器的地址号码,就是用 20 位二进制数来确定的。
  那么,存储器的地址范围就是:00000H ~ FFFFFH。
  整个系统,共有 2^20 = 1M 个存储单元。
  每个存储单元,只能存放八位二进制数,亦即一个字节 (Byte)。
  所以,8088/8086 系统中的存储空间大小,仅仅是:1MB。

  虽然 8088/8086 CPU 具有 20 条地址线,寻址可达 1M 的范围。
  但是,CPU 内部的寄存器,却都是 16 位的。
  特别是与地址有关的指针寄存器如:BX、BP、SI、DI、SP、IP,个个都是 16 位的。
  如果以 16 位数作为地址,其寻址范围只能达到 2^16 = 64K。
  而 8088/8086 CPU 寻址范围是 1M,即有 16 个 64K。

  这可怎么办呢?
  其实,解决这个问题并不难,只要再配置一个 4 位的寄存器,与那些 16 位的寄存器搭配起来,即可构成 20 位的地址,就能十分方便的对 2^20 = 1M 的地址范围进行寻址。

  但是,Intel 不怕麻烦,反人类的设计了 4 个 16 位的段寄存器 CS、DS、SS、ES。由它们与那些指针寄存器组合,共同形成 20 位的地址号码。 这事这么弄,就比较滥了。
  由此,就出现了四个地址名词:物理地址、逻辑地址、段地址、偏移地址。
  其中的物理地址,就是指输出到地址总线上的 20 位地址号码。
  
段地址,是指段寄存器中的内容偏移地址,是指指针寄存器中的内容
  
逻辑地址,只是一种地址号码的书写格式,形如【段地址偏移地址】。

  8088/8086  CPU 中有一个 20 位的加法器,专门用于产生 20 位的物理地址
  它的功能是:将
段寄存器的内容左移四位,再与偏移地址相加,算出 20 位的地址号码。
  假如已知 (DS) = F800H、(BX) = 180AH,20 位加法器的计算就如下图所示。

  由此可得出物理地址是:F980AH。其逻辑地址,则可写成:F800180AH。

  由于计算过程中的 "段地址左移四位" 也可写成:段地址×16 或 段地址×10H,所以这个计算过程也可写成如下公式:
    物理地址 =
段地址 × 16 + 偏移地址;  
    物理地址 =
段地址 × 10H + 偏移地址。


  初学 8088/8086 CPU 时,确实被这种分段管理的方式惊诧到了。

  当时的教材、参考书,无一不吹捧这种管理方式,满满的都是赞誉之词。做而论道却十分的费解。明明再用一个 4 位的寄存器,就可实现 20 位地址了,为什么要用 16 位的段寄存器呢?还要左移 4 位再与偏移地址相加,弄这么稀烂的,有什么好处吗?

  不久,80286 CPU 诞生了,它具有 24 条地址线,地址号码就是 24 位数,存储器的规模就是 16MB 了。此时,20 位数的地址,当然不够用了。按照前面的思路与方法,窃以为这次一定是把段寄存器左移 8 位再加偏移地址! 

  再后来,80386 CPU 又问世了,它有 32 条地址线,存储器的规模是 4GB!

  但是,Intel 的设计师们,已经明白过来了,所以,就在 286、386 以及更新型的 CPU 中,完全抛弃了【分段管理内存】的思路。而是在 CPU 中增加了保护模式,这就把整个存储器,当成一个整体,也可以说是一个段! 那么,数据和代码,想存哪儿就存哪儿!再也没有 64K 的限制。这不就方便随意多了吗?

  回头再看 8086/8088 的存储器分段管理的方法,已经毫无优点可言了。


  王爽写的教材中,有两个关于地址的习题(检测点2.2),下面分别计算一下。

  (1) 给定段地址为 0001H,仅通过变化偏移地址来寻址,那么,
   CPU 的寻址范围为_______到_______。

  分析:仅通过偏移地址的变化来寻址,变化范围就是 0000~FFFFH。

  把数据代入公式,可算出:
    最小物理地址 = 0001H × 10H + 0000H = 00010H;  
    最大物理地址 = 0001H × 10H + FFFFH = 1000FH。

  CPU 中 20 位加法器的计算过程如下。

   (2) 有一数据存放在内存 20000H 单元中,现给定段地址为 SA,
    若想用偏移地址寻址到此单元。则 SA 应满足的条件是:
    最小为_______,最大为_______。

  分析:题目中,已经给定了物理地址是 20000H。而物理地址是由两项相加而成。求某一项的最小值,另一项就应该取最大值。这个道理,大家都是懂得的。

  那么,偏移地址取最小值 0000H,代入公式,即可得到段地址 SA 的最大值为:
    SA = ( 20000H - 0000H ) / 10H = 2000H。

  另外,在求 SA 的最小值时,偏移地址,显然就应该取最大值了。

  偏移地址的最大值,取 FFFFH 行吗? 不行!
  你认真看一看前面的几张图片,可知:偏移地址的
末位,与物理地址的末位,是相同的!
  在本题中,物理地址是给定的 20000H,末位是
0
  所以,偏移地址的末位,也必须是
0
  因此,偏移地址的最大值,只能取
FFF0H

  把 FFF0H,代入公式,可得:SA = ( 20000H-FFF0H ) / 10H = 1001H。


  对于求段地址 (SA) 的最小值问题,有许多人都选错了数据。

  都是用 FFFFH 代入公式,经过计算,结果就出现了小数。这种结果,显然是错的!

  这些朋友都是用的这个式子:20000H = SA × 10H + FFFFH,
  再导出: SA = ( 20000H - FFFFH ) / 10H = 1000.1 H。

  错误,就出自这个式子:20000H = SA × 10H + FFFFH !

  在这个等式中,等号的两边,根本就不相等!

  无论 SA 是何值 (XXXXH ),等号左边的末位都是 0,而右边的末位是 F !

  看看下图,应该选用 F 还是选 0 ? 一目了然。

  

  许多网友,都是使用一个不成立的 “等式” 来推导,结果,必然就是错的。

  这些问题,可见:链接链接链接链接链接


  后记:
  做而论道回答了网友的问题,给出了正确的算法与答案。却被一位网友批评为:不合理、违背基本计算法则、好好想想除法的意义 ...
  做而论道和这位网友利用答案的评论,争辩了许久,有兴趣的读者可以打开本题目的链接去看。
  其实,这题目,就是一个小学难度的问题。列出一个竖式,一眼便可看出,最大值应该是什么。王爽出此题,就是帮学微机的人,补一补小学知识。呵呵

--本文完--

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值