原文:
https://blog.stephenmarz.com/2021/05/12/tips-to-writing-assembly/
當用戶使用 C、C++ 或任何其他高級語言時,編譯器決定了程序的藝術(shù)。然而這一次,我們將自行面對 CPU,新手實現(xiàn)面向指令集編程的藝術(shù),本文使用RISC-V 為例來向大家展示,來如何使用編寫語言設(shè)計程序邏輯,并最終將程序邏輯轉(zhuǎn)換為匯編語言的程序。
1
用合適的語言設(shè)計邏輯對于初學者來說,這是最難的一步,因為現(xiàn)在學生們常用的高級語言中,往往使用更抽象的工具進行邏輯設(shè)計,許多學生想直接編寫完整的功能模塊。但是對于匯編語言來說,這是一種注定要失敗的方法。相反,為了把邏輯和語言分開,我們必須用我們理解的語言來設(shè)計程序邏輯。
如果一個學生不懂 C 或一些“低級”語言,那么我建議他們用偽碼寫。因為用太高級的語言如 Java 其實是面向虛擬機編程的,這會增加程序邏輯到匯編語言的轉(zhuǎn)換難度,而使用太低級的語言會使程序邏輯設(shè)計變得困難。因此,我推薦 C 或 C++,在將代碼進行轉(zhuǎn)換的時候,最好將有對應(yīng)的代友橫向放在一起,一些編輯可以把它們并排放在一起,這是很有幫助的。
說實話這部分雖然看似平平無奇,但卻讓我頗感到意外,因為 C 語言和匯編的對照完全可以通過 gcc 的 -o -g 參數(shù)以及 objdump 實現(xiàn)。
在譯者的理念中,匯編語言是專門用于填補空白,只有當其它語言不能勝任的時候才會考慮用匯編語言上場工作,不過從這篇博文中透露出的信息來看,國外在教學過程中對于匯編語言的運用范圍也是不設(shè)限的,而在譯者印象中能用匯編語言實現(xiàn)任何功能的程序員,在國內(nèi)只有求伯君,嚴援朝等廖廖數(shù)人而已,由此可見我們在 IT 基礎(chǔ)教育領(lǐng)域要做的工作還很多。
2
小步快跑,不要試圖一口吃個胖子很多匯編語言的初學者試著從頭到尾寫完整的程序,而沒有在中間進行過任何測試關(guān)鍵,但是我建議在完成部分邏輯時就立刻進行測試。這樣做其實很簡單,比如完成了一個 for 循環(huán),等等一小部分功能就要開始測試。
可以將 C 或 C++ 程序與匯編程序連接起來。通過在 C++ 中原型化組裝函數(shù)的名稱實現(xiàn)這一點。按照一般的做法通常會在 C 函數(shù)前面加上一個 “c” 來區(qū)分。我們可以調(diào)用 Show 來運行匯編語言編寫的函數(shù)。
其實這部分的建議并不僅僅針對于 RISC-V 甚至不是針對匯編語言,無論是什么語言的編程,當你想到要進行單元測試的時候往往就已經(jīng)晚了,隨時對于一個細小的模塊進行測試真的是一個好習慣。
3
了解匯編語言的功能定位這里我們必須要充分認識到?jīng)]有匯編語言和有編譯器解釋器的高級語言真的完全不一樣,不養(yǎng)兒不知父母恩,不寫匯編不知各類語言之父有多神。在匯編語言中操作順序都需要程序員自己去掌握。
例如,4+3*4 的運算,作何一種語言的編譯器都先執(zhí)行乘法,然后再加法。然而在匯編語言的編程世界中,我們必須首先選擇乘法指令,然后再選擇加法指令。沒有為我們進行運算符號的優(yōu)先級重排。
4
了解如何調(diào)用函數(shù)
在匯編語言中編寫一個函數(shù)是一項非常艱苦的任務(wù),大多數(shù) ISA 體系結(jié)構(gòu)(如ARM和RISC-V)的芯片都將附帶專門的工作手冊,當然這些手冊中只是制定了一些基本規(guī)則,如何傳遞參數(shù),如何接收返回結(jié)果,又如何構(gòu)造函數(shù)棧禎等等具體的話題都值得深入討論。
不過幸運的是 RISC-V 寄存器的 “ABI” 命名規(guī)則,有助于程序員理解它們的含義。比如:
整數(shù)參數(shù)在寄存器 A0-A7 中,浮點參數(shù)在寄存器 FA0-FA7 中
通過對堆棧指針的 sub 操作去分配函數(shù)堆棧。在調(diào)用完成后使用 add 操作進行銷毀
堆棧大小必須以 8 的整數(shù)倍形式分配
所有參數(shù)和臨時寄存器必須在函數(shù)調(diào)用后,被視為銷毀態(tài)
在函數(shù)調(diào)用之后,已保存寄存器才能被顯式保存。如果使用了任何已保存的寄存器,則必須在函數(shù)返回之前還原它們的原始值
通過 a0 寄存器做為返回值,將數(shù)據(jù)返回給調(diào)用方。
以下面這段代碼為例:
.global mainmain:addi sp, sp, -8sd ra, 0(sp)la a0, test_solvecall solvemv a0, zerold ra, 0(sp)addi sp, sp, 8ret
我們可以看到先通過 addi sp,sp,-8 的語句構(gòu)造函數(shù)禎,保存所有寄存器后執(zhí)行相應(yīng)函數(shù)邏輯,接下來將所有包括sp寄存器內(nèi)的調(diào)用環(huán)境恢復,最后返回。
5
文檔建議使用 C 或其他語言編寫匯編語言的注釋,用以下代碼為例:
# used |= 1 《《 ( x[i * 9 + col] - 1) li t0, 9 mul t1, s3, t0 # t1 = i * 9 add t1, t1, s2 # t1 = i * 9 + col slli t2, t1, 2 # Scale by 4 add t2, t2, s6 # x + i * 9 + col lw t3, 0(t2) # x[i * 9 + col] addi t3, t3, -1 # x[i * 9 + col] - 1 li t4, 1 sll t4, t4, t3 # 1 《《 x[i * 9 + col] - 1 or s5, s5, t4 # used |= 。。.
原始 C 語言代碼進行一個總的注釋,然后將每個匯編語言片段的也使用 C 語言進行注釋。尤其當涉及到運算操作順序時,這樣的方式使我們能夠保證程序可以正確地執(zhí)行每一步。
免責聲明:本文素材來源網(wǎng)絡(luò),版權(quán)歸原作者所有。如涉及作品版權(quán)問題,請與我聯(lián)系刪除。
編輯:jq
-
寄存器
+關(guān)注
關(guān)注
31文章
5357瀏覽量
120581 -
數(shù)據(jù)
+關(guān)注
關(guān)注
8文章
7073瀏覽量
89139 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4333瀏覽量
62721 -
代碼
+關(guān)注
關(guān)注
30文章
4797瀏覽量
68707
原文標題:新手 RISC-V 編程的幾點內(nèi)容
文章出處:【微信號:strongerHuang,微信公眾號:strongerHuang】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論