1. 程式人生 > >自己動手寫CPU之第九階段(2)——載入儲存指令說明2(lwl、lwr)

自己動手寫CPU之第九階段(2)——載入儲存指令說明2(lwl、lwr)

將陸續上傳新書《自己動手寫CPU》,今天是第38篇,我儘量每週四篇,但是最近已經很久沒有實現這個目標了,一直都有事,不好意思哈。

開展晒書評送書活動,在亞馬遜、京東、噹噹三大圖書網站上,發表《自己動手寫CPU》書評的前十名讀者,均可獲贈《步步驚芯——軟核處理器內部設計分析》一書,大家踴躍參與吧!活動時間:2014-9-11至2014-10-20

今天繼續對MIPS32中載入儲存指令進行說明(主要是lwl、lwr),上次已經介紹一些其他的載入儲存指令,大家可以回顧。

9.1.4 載入指令lwllwr說明

      載入指令lwllwr的格式如圖9-6所示。


  •  當指令中的指令碼為6'b100010時,是
    lwl指令,非對齊載入指令,向左載入

      指令用法為:lwl rt, offset(base)

      指令作用為:從記憶體中指定的載入地址處,載入一個字的最高有效部分。lwl指令對載入地址沒有要求,從而允許地址非對齊載入,這是與前面介紹的lhlhulw指令的不同之處。在大端模式、小端模式下,lwl指令的效果不同,因為OpenMIPS是大端模式,所以此處只介紹在大端模式下lwl指令的效果。假設計算出來的載入地址是loadaddrloadaddr的最低兩位的值為n,將loadaddr最低兩位設為0後的值稱為loadaddr_align,如下。

載入地址loadaddr = signed_extended(offset) + GPR[base]

n = loadaddr[1:0]

loadaddr_align = loadaddr – n

      例如:假設計算出來的載入地址是5lwl指令要從地址5載入資料,那麼loadaddr就等於5n等於1loadaddr_align等於4

      lwl指令的作用是從地址為loadaddr_align處載入一個字,也就是4個位元組,然後將這個字的最低4-n個位元組儲存到地址為rt的通用暫存器的高位,並且保持低位不變。

      繼續上例,此時loadaddr_align4,所以從地址4處載入一個字,對應的是地址為4567的位元組,因為n等於1,所以將載入到的字的最低3個位元組儲存到地址

rt的通用暫存器的高3個位元組。如圖9-7所示。一個更加通用的描述如圖9-8所示。


  •  當指令中的指令碼為6'b100110時,是lwr指令,非對齊載入指令,向右載入

      指令用法為:lwr rt, offset(base)

      指令作用為:從記憶體中指定的載入地址處,載入一個字的最低有效部分。還是假設計算出來的載入地址是loadaddrloadaddr的最低兩位的值為n,將loadaddr最低兩位設為0後的值稱為loadaddr_align,如下。

載入地址loadaddr = signed_extended(offset) + GPR[base]

n = loadaddr[1:0]

loadaddr_align = loadaddr – n

      例如:假設計算出來的載入地址是9lwr指令要從地址9載入資料,那麼loadaddr就等於9n等於1loadaddr_align等於8

      lwr指令的作用是從地址為loadaddr_align處載入一個字,也就是4個位元組,然後將這個字的最高n+1個位元組儲存到地址為rt的通用暫存器的低位,並且保持高位不變。

      繼續上例,此時loadaddr_align8,所以從地址8處載入一個字,對應的是地址為891011的位元組,因為n等於1,所以將載入到的字的最高2個位元組儲存到地址rt的通用暫存器的低2個位元組。如圖9-9所示。一個更加通用的描述如圖9-10所示。


      lwllwr指令配合可以實現從一個非對齊地址載入一個字,而且只需要使用2條指令,提高了效率。例如:使用一般指令從地址7處載入一個字,那麼可以使用以下程式碼實現,共5條指令。

lw  $1, 4($0)          # 取得地址0x4處的字,儲存在$1中
lw  $2, 8($0)          # 取得地址0x8處的字,儲存在$2中
sll $1, $1, 24         # $1左移24位
slr $2, $2, 8          # $2右移8位
or  $1, $1, $2         # $1與$2進行邏輯“或”運算,得到最終結果

      而有了lwllwr指令後,只需要2條指令即可。如下,圖9-11是對這個過程的描述。

lwl $1, 7($0)
lwr $1,10($0)