龍芯組合語言程式設計藝術

2021-06-08 09:07:18 字數 1540 閱讀 1725

發表日期: 2007-04-27 17:49

分析系統呼叫的實現時看到這麼一段**,令人不禁拍案叫絕。

系統呼叫的引數傳遞,前4個引數通過a0~a3傳,後面的引數要通過棧來傳,目前核心

系統呼叫最長的引數個數為8。

用棧傳遞引數時,涉及到要將位於使用者空間的引數先複製到核心空間(核心棧)。

因為系統呼叫的引數個數不定,因此就需要判斷引數個數為5、6、7、8 不同情況時,

相應的複製操作個數。5個引數時需要複製個數為1,6個時為2,以此類推。

通常的解決方法是用switch語句,這個編譯出來,得要四條分支判斷語句吧

看看核心的一些牛人怎麼實現:

la t1, 5f # 標號5所示之位址入t1

subu t1, t3 # t3 的內容為當前系統呼叫引數個數減去5,再乘以4

# 這個已經預先計算好,儲存於系統呼叫表每項的第二個

# 字段,用時直接載入。

# 另外,此前已經判斷過,t3 的內容大於等於0

1: lw t5, 16(t0) # t0 的內容為使用者空間第乙個引數的位址

.set push

.set noreorder

.set nomacro

jr t1

addiu t1, 6f - 5f # 妙用分支延遲槽

2: lw t8, 28(t0) # 取使用者空間第8個引數

3: lw t7, 24(t0) # 取使用者空間第7個引數

4: lw t6, 20(t0) # 取使用者空間第6個引數

5: jr t1

sw t5, 16(sp) # 第5個引數進入核心棧

c: sw t8, 28(sp) # 第8個引數進入核心棧

b: sw t7, 24(sp) # 第7個引數進入核心棧

a: sw t6, 20(sp) # 第6個引數進入核心棧

6: j stack_done # 引數複製完畢,返回

nop只用兩條 jr 指令,效率大大提高!簡直妙不可言!

下面詳細分析之:

(1) t3 的值,在引數個數為5 時,t3 為0,6 時為4,7 時為8,8 時為12

這個 t3 在這裡,實際上是用來表示相對於標號5處的位址偏移! 因為mips/godson下,

指令的長度都是4個位元組。因此 t3 值為4(引數個數為6)時,第乙個 jr t1 是跳轉到

標號4處開始執行的。

(2) 第乙個 jr t1 用來解決從使用者空間複製資料操作的個數問題,相對應的,則是解決寫入

操作的個數問題,這個用第二個 jr t1 來解決。在此之前,更新 t1 的指令(addiu)的

位置放的很巧妙,置於第乙個 jr t1 的延遲槽中,不占用標號4與標號5之間的空間。

(3) 可以看到引數個數為5時,第二個 jr t1 直接跳轉到標號6處執行,將第5個引數寫入內

核棧的操作置於延遲槽中;引數個數為6時,會跳轉到標號a處執行;引數個數為8時,會

跳轉到標號c處執行,依次完成第5、8、7、6引數的寫入。

結論:該段程式的作者對mips平台下的延遲槽有深刻的理解,故而才能有如此神乎其技的妙用。

MIPS 組合語言程式設計的藝術(龍芯適用)

分析系統呼叫的實現時看到這麼一段 令人不禁拍案叫絕。系統呼叫的引數傳遞,前4個引數通過a0 a3傳,後面的引數要通過棧來傳,目前核心 系統呼叫最長的引數個數為8。用棧傳遞引數時,涉及到要將位於使用者空間的引數先複製到核心空間 核心棧 因為系統呼叫的引數個數不定,因此就需要判斷引數個數為5 6 7 8...

組合語言程式設計

1.彙編語句的三種基本型別 2.標號相關 3.變數相關 4.運算元定址方式 buffer dw 500 x 17 rept 500 這是乙個重複巨集,以下重複彙編500遍 x x 979 mod 65535 這句話我也不懂 dw x endm 巨集在這裡結束transto10 proc near 函...

組合語言程式設計

乙個完整的源程式通常由若干邏輯段組成,包括資料段 附加段 堆疊段和 段。它們分別對映到儲存器中的物理段上。每個邏輯段以segment語句開始,以ends結束,整個源程式用end語句結尾。段中存放源程式的所有指令碼 資料 變數等則放在資料段和附加段中。程式中可以定義堆疊段,也可以直接利用系統中的堆疊段...