<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
會員中心
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

淺談鴻蒙內核源碼的棧

鴻蒙系統HarmonyOS ? 來源:my.oschina ? 作者: 鴻蒙內核源碼分析 ? 2021-04-24 11:21 ? 次閱讀

精讀內核源碼就繞不過匯編語言,鴻蒙內核有6個匯編文件,讀不懂它們就真的很難理解以下問題.

1.系統調用是如何實現的?

2.CPU是如何切換任務和進程上下文的?

3.硬件中斷是如何處理的?

4.main函數到底是怎么來的?

5.開機最開始發生了什么?

6.關機最后的最后又發生了什么?

以下是一個很簡單的C文件編譯成匯編代碼后的注解.讀懂這些注解會發現匯編很可愛,甚至還會上癮,并沒有想象中的那么恐怖,讀懂它會顛覆你對匯編和棧的認知.

#include 
#include 

int square(int a,int b){
    return a*b;
}

int fp(int b)
{
    int a = 1;
    return square(a+b,a+b);
}

int main()
{
    int sum = 1;
    for(int a = 0;a < 100; a++){
        sum = sum + fp(a);
    }
    return sum;
}
//編譯器: armv7-a clang (trunk)
square(int, int):
        sub     sp, sp, #8     @sp減去8,意思為給square分配??臻g,只用2個??臻g完成計算
        str     r0, [sp, #4]   @第一個參數入棧
        str     r1, [sp]       @第二個參數入棧
        ldr     r1, [sp, #4]   @取出第一個參數給r1
        ldr     r2, [sp]       @取出第二個參數給r2
        mul     r0, r1, r2     @執行a*b給R0,返回值的工作一直是交給R0的
        add     sp, sp, #8     @函數執行完了,要釋放申請的??臻g
        bx      lr             @子程序返回,等同于mov pc,lr,即跳到調用處
fp(int):
        push    {r11, lr}      @r11(fp)/lr入棧,保存調用者main的位置
        mov     r11, sp        @r11用于保存sp值,函數棧開始位置 
        sub     sp, sp, #8     @sp減去8,意思為給fp分配??臻g,只用2個??臻g完成計算
        str     r0, [sp, #4]   @先保存參數值,放在SP+4,此時r0中存放的是參數
        mov     r0, #1         @r0=1
        str     r0, [sp]       @再把1也保存在SP的位置
        ldr     r0, [sp]       @把SP的值給R0
        ldr     r1, [sp, #4]   @把SP+4的值給R1
        add     r1, r0, r1     @執行r1=a+b
        mov     r0, r1         @r0=r1,用r0,r1傳參
        bl      square(int, int)@先mov lr, pc 再mov pc square(int, int)   
        mov     sp, r11        @函數執行完了,要釋放申請的??臻g 
        pop     {r11, lr}      @彈出r11和lr,lr是專用標簽,彈出就自動復制給lr寄存器
        bx      lr             @子程序返回,等同于mov pc,lr,即跳到調用處
main:
        push    {r11, lr}      @r11(fp)/lr入棧,保存調用者的位置
        mov     r11, sp        @r11用于保存sp值,函數棧開始位置
        sub     sp, sp, #16    @sp減去8,意思為給main分配??臻g,只用2個??臻g完成計算
        mov     r0, #0         @初始化r0
        str     r0, [r11, #-4] @作用是保存SUM的初始值 
        str     r0, [sp, #8]   @sum將始終占用SP+8的位置
        str     r0, [sp, #4]   @a將始終占用SP+4的位置
        b       .LBB1_1        @跳到循環開始位置
.LBB1_1:                       @循環開始位置入口
        ldr     r0, [sp, #4]   @取出a的值給r0
        cmp     r0, #99        @跟99比較
        bgt     .LBB1_4        @大于99,跳出循環 mov pc .LBB1_4
        b       .LBB1_2        @繼續循環,直接 mov pc .LBB1_2
.LBB1_2:                       @符合循環條件入口
        ldr     r0, [sp, #8]   @取出sum的值給r0,sp+8用于寫SUM的值
        str     r0, [sp]       @先保存SUM的值,SP的位置用于讀SUM值
        ldr     r0, [sp, #4]   @r0用于傳參,取出A的值給r0作為fp的參數
        bl      fp(int)        @先mov lr, pc再mov pc fp(int)
        mov     r1, r0         @fp的返回值為r0,保存到r1
        ldr     r0, [sp]       @取出SUM的值
        add     r0, r0, r1     @計算新sum的值,由R0保存
        str     r0, [sp, #8]   @將新sum保存到SP+8的位置
        b       .LBB1_3        @無條件跳轉,直接 mov pc .LBB1_3
.LBB1_3:                       @完成a++操作入口
        ldr     r0, [sp, #4]   @SP+4中記錄是a的值,賦給r0
        add     r0, r0, #1     @r0增加1
        str     r0, [sp, #4]   @把新的a值放回SP+4里去
        b       .LBB1_1        @跳轉到比較 a < 100 處
.LBB1_4:                       @循環結束入口
        ldr     r0, [sp, #8]   @最后SUM的結果給R0,返回值的工作一直是交給R0的
        mov     sp, r11        @函數執行完了,要釋放申請的??臻g
        pop     {r11, lr}      @彈出r11和lr,lr是專用標簽,彈出就自動復制給lr寄存器
        bx      lr             @子程序返回,跳轉到lr處等同于 MOV PC, LR

這個簡單的匯編并不是鴻蒙的匯編,只是先打個底,由淺入深, 但看懂了它基本理解鴻蒙匯編代碼沒有問題, 后續將詳細分析鴻蒙內核各個匯編文件的作用. 開始分析上面的匯編代碼.

第一:上面的代碼和鴻蒙內核用棧方式一樣,都采用了遞減滿棧的方式, 什么是遞減滿棧? 遞減指的是棧底地址高于棧頂地址,滿棧指的是SP指針永遠在棧頂.一定要理解遞減滿棧,否則讀不懂內核匯編代碼.舉例說明:

square(int, int):
        sub     sp, sp, #8     @sp減去8,意思為給square分配??臻g,只用2個??臻g完成計算
        str     r0, [sp, #4]   @第一個參數入棧
        str     r1, [sp]       @第二個參數入棧
        ldr     r1, [sp, #4]   @取出第一個參數給r1
        ldr     r2, [sp]       @取出第二個參數給r2
        mul     r0, r1, r2     @執行a*b給R0,返回值的工作一直是交給R0的
        add     sp, sp, #8     @函數執行完了,要釋放申請的??臻g
        bx      lr             @子程序返回,等同于mov pc,lr,即跳到調用處

首句匯編的含義就是申請??臻g,sp = sp - 8,一個棧內單元(??臻g)占4個字節,申請2個??臻g搞定函數的計算,仔細看下代碼除了在函數的末尾sp = sp + 8又恢復在之前的位置的中間過程,SP的值是沒有任務變化,它的指向是不動的, 這跟很多人對棧的認知是不一樣的,它只是被用于計算,例如ldr r1, [sp, #4]的意思是取出SP+4這個虛擬地址的值給r1寄存器,SP的值并沒有改變的,為什么要+呢,因為SP是指向棧頂的,地址是最小的. 滿棧就是用棧過程中對地址的操作不能超過SP,所以你很少在計算過程中看到 把sp-4地址中的值給某個寄存器, 除非是特別的指令,否則不可能有這樣的指令.

第二:sub sp, sp, #8和add sp, sp, #8是成對出現的,這就跟申請內存,釋放內存的道理一樣,這是內核對任務的運行棧管理方式,一樣用多少申請多少,用完釋放.空間大小就是棧幀,這是棧幀的本質含義.

第三:push {r11, lr}和pop {r11, lr}也是成對出現的,主要是用于函數調用,例如 A -> B, B要保存A的棧幀范圍和指令位置, lr保存是是A函數執行到哪個指令的位置, r11干了fp的工作,其實就是指向 A的棧頂位置,如此B執行完后return回A的時候,先mov pc,lr 內核就知道改執行A的哪條指令了,同時又知道了A的棧頂位置.

第四:頻繁出現的R0寄存器的作用用于傳參和返回值, A調用B之前,假如有兩個參數,就把參數給r0 ,r1記錄,充當了A的變量, 到了B中后,先讓r0,r1入棧,目的是保存參數值, 因為 B中要用r0,r1,他們變成B的變量用了. 返回值都是默認統一給r0保存. B中將返回值給r0,回到A中取出R0值對A來說這就是B的返回值.

這是以上為匯編代碼的分析,追問兩個問題

第一:如果是可變參數怎么辦? 100個參數怎么整, 通過寄存器總共就12個,不夠傳參啊 第二:返回值可以有多個嗎?

編輯:hfy

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 寄存器
    +關注

    關注

    30

    文章

    5164

    瀏覽量

    118135
收藏 人收藏

    評論

    相關推薦

    鴻蒙內核源碼分析:用通俗易懂的語言告訴你鴻蒙內核發生了什么?

    鴻蒙虛擬內存全景圖圖來自 鴻蒙內核源碼注釋中文版 【Gitee倉 】再看鴻蒙用戶空間全景圖圖來自 鴻蒙
    發表于 11-19 10:14

    鴻蒙內核源碼分析(源碼注釋篇):給HarmonyOS源碼逐行加上中文注釋

    每個碼農,職業生涯,都應精讀一遍內核源碼. 鴻蒙內核源碼就是很好的精讀項目.一旦熟悉內核代碼的實
    發表于 11-19 10:32

    鴻蒙內核源碼分析:給HarmonyOS源碼逐行加上中文注釋

    原文鏈接:https://bbs.elecfans.com/jishu_2010058_1_1.html 每個碼農,職業生涯,都應精讀一遍內核源碼. 鴻蒙內核
    發表于 11-19 15:06

    鴻蒙源碼分析系列(總目錄) | 給HarmonyOS源碼逐行加上中文注釋

    鴻蒙內核源碼注釋中文版 【Gitee倉】 給 HarmonyOS 源碼逐行加上中文注解,詳細闡述設計細節, 助你快速精讀 HarmonyOS 內核
    發表于 11-20 11:24

    鴻蒙內核源碼分析(雙循環鏈表篇) :內核最重要結構體

    鴻蒙源碼分析系列文章圖解鴻蒙內核, 從 HarmonyOS 架構層視角整理成文, 并首創用生活場景講故事的方式試圖去解構內核,一窺究竟。為何
    發表于 11-24 13:39

    鴻蒙內核源碼分析(百篇博客分析.挖透鴻蒙內核)

    致敬內核開發者感謝開放原子開源基金會,致敬鴻蒙內核開發者??梢院敛豢鋸埖恼f鴻蒙內核源碼可作為大學
    發表于 07-04 17:16

    如何尋找鴻蒙源碼入口

    因為鴻蒙源碼剛開源,所以網上是不會搜到源碼講解的,搜到的基本都是鴻蒙OS應用開發教程,這個和鴻蒙源碼
    的頭像 發表于 10-14 14:22 ?3661次閱讀
    如何尋找<b class='flag-5'>鴻蒙</b><b class='flag-5'>源碼</b>入口

    淺談鴻蒙內核源碼的CPU四次換棧,寄存器改值

    本篇有相當的難度,涉及用戶棧和內核棧的兩輪切換,CPU四次換棧,寄存器改值,將圍繞下圖來說明.? 解讀 為本篇理解方便,把圖做簡化標簽說明: user:用戶空間 kernel:內核空間 source
    的頭像 發表于 04-28 16:56 ?1426次閱讀
    <b class='flag-5'>淺談</b><b class='flag-5'>鴻蒙</b><b class='flag-5'>內核</b><b class='flag-5'>源碼</b>的CPU四次換棧,寄存器改值

    為何要精讀鴻蒙內核源碼?

    一個沒學過計算機知識的賣菜大媽就不可能知道內核的基本運作了嗎? 不一定!在系列篇中試圖用 鴻蒙內核源碼分析(總目錄)之故事篇 去引導這一層級的認知,希望能卷入更多的人來關注基礎軟件,尤
    的頭像 發表于 04-26 15:00 ?1508次閱讀
    為何要精讀<b class='flag-5'>鴻蒙</b><b class='flag-5'>內核</b><b class='flag-5'>源碼</b>?

    淺談鴻蒙內核源碼的原子操作

    ARMv6架構引入了LDREX和STREX指令,以支持對共享存儲器更縝密的非阻塞同步。由此實現的原子操作能確保對同一數據的“讀取-修改-寫入”操作在它的執行期間不會被打斷,即操作的原子性。
    的頭像 發表于 04-25 16:05 ?1138次閱讀
    <b class='flag-5'>淺談</b><b class='flag-5'>鴻蒙</b><b class='flag-5'>內核</b><b class='flag-5'>源碼</b>的原子操作

    淺談鴻蒙內核源碼的信號量運作原理

    基本概念 信號量(Semaphore) 是一種實現任務間通信的機制,可以實現任務間同步或共享資源的互斥訪問。 一個信號量的數據結構中,通常有一個計數值,用于對有效資源數的計數,表示剩下的可被使用的共享資源數,其值的含義分兩種情況: 0,表示該信號量當前不可獲取,因此可能存在正在等待該信號量的任務。 正值,表示該信號量當前可被獲取。 以同步為目的的信號量和以互斥為目的的信號量在使用上有如下不同: 用作互斥時,初始信號量計數
    的頭像 發表于 04-24 10:44 ?1353次閱讀

    鴻蒙內核源碼分析:鴻蒙內核的每段匯編代碼解析

    本篇說清楚CPU的工作模式 讀本篇之前建議先讀鴻蒙內核源碼分析(總目錄)其他篇. 正如一個互聯網項目的后臺管理系統有權限管理一樣,CPU工作是否也有權限(模式)? 一個成熟的軟硬件架構,肯定會
    的頭像 發表于 03-02 09:56 ?3834次閱讀
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>內核</b><b class='flag-5'>源碼</b>分析:<b class='flag-5'>鴻蒙</b><b class='flag-5'>內核</b>的每段匯編代碼解析

    鴻蒙內核源碼分析: 虛擬內存和物理內存是怎么管理的

    有了上篇鴻蒙內核源碼分析(內存概念篇)的基礎,本篇講內存管理部分,本章源碼超級多,很燒腦,但筆者關鍵處都加了注釋。廢話不多說,開始吧。內存一開始就是一張白紙,這些extern就是給它畫
    發表于 11-23 11:45 ?19次下載
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>內核</b><b class='flag-5'>源碼</b>分析: 虛擬內存和物理內存是怎么管理的

    鴻蒙內核源碼分析 :內核最重要結構體

    為何鴻蒙內核源碼分析系列開篇就說 LOS_DL_LIST ? 因為它在鴻蒙 LOS 內核中無處不在,在整個
    發表于 11-24 17:54 ?35次下載
    <b class='flag-5'>鴻蒙</b><b class='flag-5'>內核</b><b class='flag-5'>源碼</b>分析 :<b class='flag-5'>內核</b>最重要結構體

    華為鴻蒙系統內核源碼分析上冊

    鴻蒙內核源碼注釋中文版【 Gitee倉】給 Harmoηy○S源碼逐行加上中文注解,詳細闡述設計細節,助你快速精讀 Harmonyos內核源碼
    發表于 04-09 14:40 ?16次下載
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>