自己動手寫CPU之第九階段(2)——載入存儲指令說明2(lwl、lwr)
將陸續上傳新書《自己動手寫CPU》。今天是第38篇,我盡量每周四篇,可是近期已經非常久沒有實現這個目標了。一直都有事,不好意思哈。
開展曬書評送書活動,在
q=%E4%BA%9A%E9%A9%AC%E9%80%8A&ie=utf-8&src=se_lighten_f" style="color:rgb(51,102,153); text-decoration:none; font-family:Arial; font-size:14px; line-height:26px; display:inline; position:static">亞馬遜、京東、當當三大圖書站點上,發表《
今天繼續對MIPS32中載入存儲指令進行說明(主要是lwl、lwr),上次已經介紹一些其它的載入存儲指令,大家能夠回想。
9.1.4 載入指令lwl、lwr說明
載入指令lwl、lwr的格式如圖9-6所看到的。
- 當指令中的指令碼為6‘b100010時,是lwl指令。非對齊載入指令,向左載入
指令使用方法為:lwl rt, offset(base)
指令作用為:從內存中指定的載入地址處,載入一個字的最高有效部分。lwl
載入地址loadaddr = signed_extended(offset) + GPR[base]
n = loadaddr[1:0]
loadaddr_align = loadaddr – n
比如:如果計算出來的載入地址是5。lwl指令要從地址5載入數據。那麽loadaddr就等於5,n等於1。loadaddr_align等於4。
lwl指令的作用是從地址為loadaddr_align處載入一個字,也就是4個字節,然後將這個字的最低4-n個字節保存到地址為rt的通用寄存器的高位。而且保持低位不變。
繼續上例,此時loadaddr_align為4,所以從地址4處載入一個字,相應的是地址為4、5、6、7的字節,由於n等於1,所以將載入到的字的最低3個字節保存到地址rt的通用寄存器的高3個字節。如圖9-7所看到的。
一個更加通用的描寫敘述如圖9-8所看到的。
- 當指令中的指令碼為6‘b100110時,是lwr指令。非對齊載入指令,向右載入
指令使用方法為:lwr rt, offset(base)
指令作用為:從內存中指定的載入地址處,載入一個字的最低有效部分。還是如果計算出來的載入地址是loadaddr,loadaddr的最低兩位的值為n。將loadaddr最低兩位設為0後的值稱為loadaddr_align,例如以下。
載入地址loadaddr = signed_extended(offset) + GPR[base]
n = loadaddr[1:0]
loadaddr_align = loadaddr – n
比如:如果計算出來的載入地址是9,lwr指令要從地址9載入數據。那麽loadaddr就等於9,n等於1。loadaddr_align等於8。
lwr指令的作用是從地址為loadaddr_align處載入一個字。也就是4個字節。然後將這個字的最高n+1個字節保存到地址為rt的通用寄存器的低位,而且保持高位不變。
繼續上例,此時loadaddr_align為8。所以從地址8處載入一個字,相應的是地址為8、9、10、11的字節,由於n等於1。所以將載入到的字的最高2個字節保存到地址rt的通用寄存器的低2個字節。如圖9-9所看到的。一個更加通用的描寫敘述如圖9-10所看到的。
lwl與lwr指令配合能夠實現從一個非對齊地址載入一個字,並且僅僅須要使用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進行邏輯“或”運算,得到終於結果
而有了lwl、lwr指令後。僅僅須要2條指令就可以。
例如以下。圖9-11是對這個過程的描寫敘述。
lwl $1, 7($0) lwr $1,10($0)
自己動手寫CPU之第九階段(2)——載入存儲指令說明2(lwl、lwr)