当前位置: 代码迷 >> 汇编语言 >> 数据段的起初地址必须是16的倍数
  详细解决方案

数据段的起初地址必须是16的倍数

热度:235   发布时间:2016-05-02 04:47:00.0
数据段的起始地址必须是16的倍数?
下图来自王爽的《汇编语言》第二版,第53页。
他这里说,起始地址为16的倍数。 很奇怪,为什么非要16的倍数呢。 如果我就想用内存的第五、第六、第七 这三个字节,难道不行吗?
第二个问题,他让 N<=64K。前面的章节说8086CPU地址总线有20个,也就是可以寻址 2^20 个字节,算一算,是一兆。 这里为什么要让长度小于64K呢?



------解决方案--------------------
起始指的是偏移地址为0的情况下,段地址不管怎么变化,最后的物理地址都是16的倍数。
http://topic.csdn.net/u/20110718/10/a2df88a3-9ef9-4b7c-be9f-159fea7db219.html
------解决方案--------------------
不用这样死读书吧,建议灵活掌握。

我看你问了很多类似的问题,不是说问题不对,但有些问题...
------解决方案--------------------
一、不是不让,就是让你把段地址取在不是16整数倍的地址上,你能做到吗?想一想段寄存器中的数据如果是0B07h,段地址就是0B07h吗?
  二、有20根地址总线,就是说它有能力表示出0~1048575个号码来,再多了就表示不出来了,把这些号码一对一地对应到存储器单元,这就是你说的它能寻址1M个存储单元。可是问题来了,你地址总线有20根,但寄存器却是16位的,一个寄存器的数据只能表示出 0~65535之间的数(号码),所以一个段只能管理65536个存储器单元。(为什么DOS程序可以做成多段的?有什么数据段、代码段、附加段、堆栈段?原因之一不就是要提高使用存储器的能力吗。)

------解决方案--------------------
引用:
不用这样死读书吧,建议灵活掌握。

我看你问了很多类似的问题,不是说问题不对,但有些问题...

我感觉楼主问的问题都很有水平,至少比那些问作业的强几千倍几百倍。如果有疑问的话,如果能解决最好还是立即就解决。不知道你在网上看没看过国外的大学上课的样子,基本所有的老师都要求学生如果在课上遇到问题马上就要问,最极端的那个谁问问题了就给一块糖,没错,是大学。我在教我表弟汇编语言的时候我就发现了,我表弟根本就不会问问题。
------解决方案--------------------
在学习理论的时候遇到的问题是必须要弄懂的,否者你问一万个具体的问题也不一定能把理论弄明白了。
------解决方案--------------------
引用:
那在请教个问题,关于公式: 段地址 * 16 + 偏移地址 = 物理地址
问题在于这里的16,16是硬规定? 还是因为CPU是16位? 现在的CPU普遍都是32位的,这个公式是不是应该变为:段地址 * 32 + 偏移地址 = 物理地址

你忘了这个“段地址 * 16 + 偏移地址 = 物理地址”存在的原因是什么了么?主要的原因是用寄存器无法直接存放物理地址。到了32位的CPU上已经不存在无法直接存放的问题了,32位的寄存器直接就可以直接寻址4G的内存了。但32位的CPU上的段寄存器还是存在的,而且段在某种形式上也保留下来了。但具体的东西比8086上的复杂多了,你有兴趣学完8086再学32位的保护模式汇编吧,那个东西不是一句两句话能说明白的。
------解决方案--------------------
引用:
王爽的《汇编语言》第二版说过“无法直接存放”吗?


2.6
------解决方案--------------------
段起始地址=段地址*16+0
你说能不是16的倍数么?
书上的公式很清楚吧
------解决方案--------------------
王爽的书说的很明白,那本书是基于8086cpu的,所以只有实模式,不存在32位上的保护模式等其他模式.
------解决方案--------------------
引用:
引用:
段起始地址=段地址*16+0
你说能不是16的倍数么?

0 * 16 + 5 = 5
0 * 16 + 6 = 6
0 * 16 + 7 = 7
我倒,起始地址,您老人家+5那是起始地址么
------解决方案--------------------
你还是仔细看看书吧.勤学好问,好问是建立在勤学基础上的.

------解决方案--------------------
引用:
引用:

不用这样死读书吧,建议灵活掌握。

我看你问了很多类似的问题,不是说问题不对,但有些问题...

我感觉楼主问的问题都很有水平,至少比那些问作业的强几千倍几百倍。如果有疑问的话,如果能解决最好还是立即就解决。不知道你在网上看没看过国外的大学上课的样子,基本所有的老师都要求学生如果在课上遇到问题马上就要问,最极端的那个谁问问题了就给一块糖,没错,是大……

中国教育一向如此,要是问了一个问题老师也不会老师难堪,,,我高一时就是问生物老师练习册上的一个问题,,TM老师都居然不知道,,呃呃呃三分钟没说清楚是为什么,,最后说题目有问题要上网查一下,,,操,如此老师
------解决方案--------------------
引用:
引用:
我倒,起始地址,您老人家+5那是起始地址么

怎么了

后面加了就是物理地址了,起始地址加0就可以了

段地址 * 16 = 段起始地址

所以起始地址无论如何都是16的倍数,,当然就是在8086下的 
------解决方案--------------------
我现在也在看王爽的这本书,,,感觉还是有很多地方不清楚的,呵呵,,刚好和LZ一起学习了
------解决方案--------------------
引用:
引用:
加0就可以了

加1、2、3、4、5不行吗


可以,,但你这样就不是起始地址了

起始地址就是说开始的地址,,再加非0就到开始地址后面去了 
------解决方案--------------------
因为CPU是  (段起始地址*16)+偏移地址 来读取数据的

而DS存放的是段地址,,IP是上面的公式就是 DS*16+IP
你是想说  DS = DS + 1 还是 DS = DS*16 + 1  这样来来改变段起始地址吧,,但这应该不可以吧
到CPU读取下条指令时就是

DS*16+IP

按你的就变成了

(DS + 1)*16 + IP了,但段起始地址就变成了 (DS + 1)*16 , 所以还是16的倍数

当然,你可以认为 DS*16+1  才是真正的段起始地址,,但这种理解是不正解的,,而已CPU也不是这样工作的吧

目前所我所知,只有CPU读取指令时才会运算得到段起始地址(我也是新手,还看着前面部分),所以你想修改段起始地址是不可能的吧,,,这种理解也是错误的,,会影响你后面的学习的

LZ要把段地址和段起始地址和物理地址的概念理清
------解决方案--------------------
8086汇编程序段首地址不是一定为16的倍数!
王爽书上那么说,是因为那本书是入门用来入门.不牵涉复杂的.那么说,是方便刚入门的学习者的学习.

一般在80386以下汇编编译时,对段间的连接默认定位类型设为PARA(节-16字节).简单地说就是以16字节为最小单位进行连接.
当然,段间连接还有其他类型.

如:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;      首地址不一定是16的倍数     ;  
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      STACKS  SEGMENT   BYTE
              DB        31 DUP (1)
      STACKS  ENDS
  相关解决方案