看《匯編語言》(王爽)這本書,里面提到CPU對內存的訪問尋址問題,關於段地址和偏移地址那一節,有些沒看明白。於是百度了一下,結合自己的思考,發現其實並不復雜。
該書所使用的CPU是8086,字長16位,數據總線寬度為20位。字長如果是16的話,那么CPU尋址范圍是2^16 = 64k,而數據總線寬度是20位的話,那么通過數據總線尋址范圍就是2^20 = 1M(這就是為什么32位機器2^32=4G只能使用4G內存空間的原理),這里就出現矛盾了,一邊是64k,一般是1m,而cpu設計數據總線寬度為20的目的也很明顯,增大尋址范圍,增大可用內存,所以cpu就得變換一下尋址方式來使用這20位的數據總線。
那么是怎么解決的呢?其實也簡單,既然一個寄存器存不下20位地址,那就用兩個寄存器,而這兩個寄存器其實存的數據不一樣,分別就是段地址和偏移地址。2^20剛好是2^16的四倍大小,也就是二進制左移4未,16進制左移1位,也就是要用1的長度來訪問16的長度。
書上說內存無分段,也別按照內存分段的思路理解,其實是正確的,一塊內存區域,從頭至尾,很平滑,並無分段,但是為了兼容字長和地址總線寬度的問題,我們大概可以想象成內存是分了段的,用偏移量達標一段的長度,為64k,那么2^20就能分2^4=16段,所以內存就分為16段,每一段長度64k。這種理解對嗎?答案是不對。原因在於:我們用16位來表示20位,相當於是擴大了16倍,那么如果16位的地址 x 16就剛好可以表示20位地址。所以在任何時候16位那一頭的地址 x 16就能夠完全表示20位這一頭,於是:
物理地址 = 段地址 x 16 + 偏移地址 這個公式就是成立的,假如段地址和物理地址都是從0開始,那么任何一個段地址 x 16 +偏移地址就能夠完全表示物理地址。如果段地址最大值 x 16的值 + 偏移地址最大值 = 物理地址的最大值。
