关于8086的段基址加偏移量
之前也知道只是没有去细想,如今一细想更好的理解了一下。
都知道8086的寄存器是16位的,也就是 只能寻址 64K(64k=2^16),但是却有20根地址线,那要肿么办呢。
于是就想出了一个分段寻址的方法,也就是 段基址+偏移量,其中段基址和偏移量都是16位的,但是在计算地址的时候,
将段基址左移4位,然后在加上偏移量,这样就20位了。每一段根据偏移量来看,就是64k。
但是,今天一想,这样做的话会有重复的情况啊,也就是不同的段基址和偏移量加起来,可能会对应同样的一个地址,
而且还会有溢出啊,比如段基址是0xFFFF,偏移量是0xFFFF,这样不就超出了么。
然后查了下,在维基百科中有这么一段:http://zh.wikipedia.org/wiki/Intel_8086
086有4个存储器区段(segment)暂存器,可以通过索引暂存器来设置。区段暂存器可以让CPU一种当时是全新的方式访问多达1MB之存储器。在现今有区段的处理器中,8086把区段暂存器左移4位然后把它加上去寻址。这通常被认为是一个不太好的设计,因为这么做会让各区段有重叠。
8086的分段寻址,是指一个物理地址由段地址(segment selector)与偏移量(offset)两部分组成, 长度各是16比特。其中段地址左移4位(即乘以16)与偏移量相加即为物理地址。例如,06EFh:1234h,表示段地址为06EFh, 偏移量为1234h, 物理地址为06EF0h + 1234h = 08124h。在计算物理地址时如果发生上溢出,8086处理器舍弃进位。例如,FFFFh:0010h所对应的物理地址为00000h.
一个20位的物理地址对应着4096个不同的"段地址:偏移量"的组合。这是因为,偏移量的最低4位对应于物理地址的最低四位,而偏移量的高12位共有4096个取值。
顺便又回顾了一下 远近指针
在8086上运行的编译器, 一般支持两种C语言的指针:近指针(near)与远指针(far)。近指针是16位的地址偏移值,隐式与程序的代码段地址或数据段地址结合使用以确定物理 地址。远指针是32位的“段地址:偏置量”成对出现,用以确定20位的物理地址。某些编译器支持“巨指针”(huge),类似于远指针。但巨指针的地址运 算是线性20位;而远指针的地址运算在16位偏移值溢出时不影响段地址部分,因此远指针的线性部分是16位。
原来这些问题真的是问题啊。汗。