今天又受教了,在彙編中對於一條指令的計較,代表了更高的效能和更小的 code size,工程師不能僅僅滿足於功能的實現,挖掘硬體和編譯器的全部潛力才是目標。學無止境~
1,之前講到scr1的cpu timer暫存器是mmio的,定義為:
#define mem_mtime_ctrl 0x00490000
#define mem_mtime_div 0x00490004
#define mem_mtime 0x00490008
#define mem_mtimeh 0x0049000c
#define mem_mtimecmp 0x00490010
#define mem_mtimecmph 0x00490014
彙編中如下操作:
li t0, mem_mtimecmp
sw a1, 4(t0)
sw a2, 0(t0)
編譯器轉為:
4817e2: 004902b7 lui t0,0x490
4817e6: 01028293 addi t0,t0,16 # 490010 <__tcm_end_vma>
4817ea: 00b2a223 sw a1,4(t0)
4817ee: 00c2a023 sw a2,0(t0)
而更好的辦法是定義為:
#define mmio_base 0x00490000
#define mmio_mtime_ctrl 0x00
#define mmio_mtime_div 0x04
#define mmio_mtime 0x08
#define mmio_mtimeh 0x0c
#define mmio_mtimecmp 0x10
#define mmio_mtimecmph 0x14
**這樣寫:
li t0, mmio_base
sw a2, mmio_mtimecmp(t0)
sw a1, mmio_mtimecmph(t0)
編譯後:
4817da: 004902b7 lui t0,0x490
4817de: 00c2a823 sw a2,16(t0) # 490010 <__tcm_end_vma>
4817e2: 00b2aa23 sw a1,20(t0)
實現一樣的操作,節約了一條指令。
2,gp(global pointer) 應該初始化。理論上官方和很多sample code都對gp register進行了初始化,應該加入。
理論上gp暫存器 賦值為資料段中間位址,編譯器可以利用這個位址的正負2k的訪問範圍 來替換 lui和aupic指令,這樣可以節約一條指令
但實際測試下來,結果不一致,用最新版本編譯器看到的結果也是不符合的,但還是建議這樣做,一是沒有壞處,二是你可以避開因gp無值而導致的硬體異常。
編譯器明明知道a0可以用gp+0x420來獲取,但它竟然使用兩條指令先lui a0,0x2,再加1052來取,也沒用gp暫存器。
有可能是設定問題或是編譯器問題,如果大家誰知道原因還請賜教。
一條指令安裝fbprophet
將 c programdata anaconda36 c programdata anaconda36 scripts c programdata anaconda36 library bin 這句加在環境變數的path裡面的開頭 我的anaconda裝在這個路徑下 cmd裡面執行 conda in...
一條cpu指令執行過程
計算機每執行一條指令都可分為三個階段進行。即取指令 分析指令 執行指令。取指令的任務是 根據程式計數器pc中的值從程式儲存器讀出現行指令,送到指令暫存器。計算機執行程式的過程實際上就是逐條指令地重複上述操作過程,直至遇到停機指令可迴圈等待指令。一般計算機進行工作時,首先要通過外部裝置把程式和資料通過...
一條cltq指令引發的血案
文章 我的個人部落格上了 但是很久沒有維護已經被關掉了。現在重新將裡面的東西移到csdn上了。兩個 a.c b.c,a.c裡實現了乙個函式 void malloc2d 返回乙個void型的二級指標,然後b.c裡會呼叫這個malloc2d的函式,但是在除錯的時候始終得不到正確的值,遂用gdb進行除錯一...