標籤:
jmpi是段間跳轉指令,用於x86實模式下,
如:BOOTSEG = 0x0c70
jmpi 4, #BOOTSEG
假如當前段CS==00h,那麼執行此指令後將跳轉到段CS==0x0c70,當然段cs的值也變為0x0c70,接下來將執行指令0x0c70:0004處的指令。
實模式下定址是為了相容8086處理器,8086是16位CPU(是ALU的資料寬度),20位地址匯流排可定址1M記憶體空間。其定址方式:段基址+位移 的方式,段基址儲存在CS、DS、ES等段寄存器內,相當於定址的高16位,而位移是內部16位匯流排提供,在送往外部地址匯流排時,段基址和位移合成20位地址,來定址1M的物理地址空間。
合成方式:段基址左移4位,然後加上位移地址。但還不是一般的相加,由於相加前段基址已經左移4位,變成20位了(最低4位是0),而位移還是16位,所以,其實是段基址和位移的高12位相加,位移的低4位不變。
如:段基址左移4位後: 0x 8880:0
位移地址(0x0440): + 0x 044 0
________________
外部匯流排20位地址: 0x88c4 0
可看出,這個所謂段式記憶體管理,並不是純粹的基址加位移的方式,據說這是Intel當時欺騙了大家。以下是,我看到的一篇文章中的說法:
8086/8088的定址問題
===============
8088和80286都是16位CPU,Intel當初為什麼會警告IBM和蓋茨呢?到底發生了什嗎?
要瞭解發生了什麼,我們要看看處理器的內部,會看到巨大的差異。首先,你找一片8088CPU,把封裝磨掉,磨到CPU矽片,放到顯微鏡下,你會看到8086/88的內部結構,它根本不是一個新的設計,而是兩個並聯啟動並執行8085(8位)微處理器再多那麼一點點。
每個8085有它自己的8位元據和16位定址能力。結合2個8位元據寄存器假裝16位寄存器很容易。事實上這沒有任何新東西,RCA COSMAC微處理器就使用16個8位寄存器,可作為內部的8位或16位寄存器使用,你可以有多達16個8位寄存器或8個16位寄存器或兩者的任何組合。現在,一個中國的普通IC廠都可以輕易設計的出來。
可能由於受當時生產工藝所限,8088隻能有40個腳,intel的設計“精英”左思右想,確定了20條地址線(1M的定址空間),而且16條資料線還要和20條地址線中的16條複用(分時複用,即一會是地址線,一會是資料線,對此要想瞭解,可看8088晶片手冊的時序部分,也可看8052單片機書籍,它的地址線和資料線也是複用的)。
到了問題的實質了,8088內的兩個8085各有一套16位定址寄存器,如何讓他們定址20位的1M地址呢?其實把他們並在一起形成32位定址很簡單,如果是那樣後來的很多麻煩可能就都沒有了(如A20門),但當時那些“精英”可能認為32位定址(4G地址空間)那是扯淡,估計地球消失了也用不到那麼多的記憶體吧?再說了老闆逼的又緊,於是他們採用了在一個硬體上使用兩個8085非常好實現的方法--分段:
他們把1024K地址空間分成16位元組的段,共64K個段,用一個8085的16位定址寄存器作地址位移寄存器(故段的長度是64K),而另一個8085的16位定址寄存器作16位元組段的段地址寄存器,注意,他儲存的不是16位元組段的地址,而是16位元組段的序號(0,1,...65535)。
這樣做的好處是:只要在兩8085CPU之間加一個移位器和一個20位的加法器,就可以完成20位的地址定址--一個8085的地址寄存器(段地址--就是16位元組段的序號)左移4位(*16 = 16位元組小段的首地址),加上另一個8085的地址寄存器就可以啦,哈哈!可以向老闆交差了,製作成本低,設計速度快,有錢不搶是孫子!至於以後,。。。。
linux源碼閱讀筆記 jmpi指令(轉)