主頁 > 作業系統 > SDCC 的 MCS-51 匯編基礎概念和傳參方式

SDCC 的 MCS-51 匯編基礎概念和傳參方式

2022-01-24 06:07:05 作業系統

暫存器 Register

暫存器用于資料的臨時存盤, 其資料可以表示為

  • 用于處理的資料位元組
  • 指向資料的地址

暫存器的結構

8051的暫存器幾乎都是8位暫存器, 因為8位MCU處理的主要是8位資料, 如果資料大于8位, 則需要拆成多段分別處理. 一個8位的暫存器, 從D7到D0代表起第7位到第0位, D7這端為MSB(most significant bit), D0這端為LSB(least significant bit).

常用暫存器

  • A (累加器)
  • B, R0, R1, R2, R3, R4, R5, R6, R7 在函式中使用的變數, R0-R7是變數, 地址并非唯一, 其絕對地址由AR0-AR7指定.
  • DPTR(data pointer), PC(program counter) 這兩個都是16位雙位元組暫存器
    • PC 指向下一個指令的地址, 16位寬度, 因此代碼區的最大范圍為0 - 0xFFFF, 64K位元組
    • 8051啟動時, PC值為0x0000, 從代碼區0x0000開始執行第一條指令
  • SP 堆疊頂指標, 其值為堆疊堆疊頂的地址, SDCC中, 堆疊的地址是向上增長的, 這個與常見的向下增長不同
  • BP 基址指標暫存器BP(base pointer), 和堆疊指標SP聯合使用, 使用BP把SP的值傳遞給BP, 通過BP來尋找堆疊里資料或者地址.

程式狀態暫存器 PSW

其中的6個位是預先定義的, 分別為

  • CY 最高位進位標志位, 當加法等運算結果超過0xFF, 產生進位時, 這個bit會被置1
  • AC D3 至 D4 進位標志位, 當加法等運算低四位產生僅位時, 這個bit會被置1
  • F0
  • RS1 暫存器組選擇, RS1,RS0的組合對應的選擇為
  • RS0 暫存器組選擇: 0,0:bank0, 0,1:bank1, 1,0:bank2, 1,1:bank3
  • OV 溢位標志位
  • --
  • P 奇偶校驗位, 如果在暫存器A中的, 1的個數為偶數時這個bit為0, 1的個數為奇數時這個bit為1

記憶體結構

8051的基礎記憶體為128位元組, 地址為00H - 7FH, 這128位元組被分成三組

  1. 00H - 1FH, 32個位元組, 用于暫存器組和堆疊
    • 這32個位元組被分成4組(4 banks), 每組8個暫存器R0-R7
    • 當8051加電時, 默認使用暫存器組0(bank 0)
    • 通過PWS的D4,D3選擇
    • 堆疊頂地址存盤在SP暫存器
    • SP暫存器只有8位, 因此其范圍只有00H-FFH
    • 當8051加電時, SP暫存器的值為07, 因此記憶體地址08H就是堆疊的第一個地址, 這個地址與暫存器組1是重合的
    • 可以給堆疊指定其它的地址
    • PUSH操作時, SP會加1, 向上增長
    • POP操作時, SP減1, 向下收縮
  2. 20H - 2FH, 16個位元組用于可以按位尋址記憶體訪問
  3. 30H - 7FH, 80個位元組屬于通用記憶體(scratch pad)

暫存器操作示例

MOV 賦值操作

格式為 MOV destination, source

賦值操作有幾種型別

直接數賦值

將值0x55賦值給暫存器A

MOV A,#55H
  • 直接數可以賦值的暫存器為A, B, R0-R7
  • 如果給暫存器賦值 #0 至 #F, 等價于賦值 #00H 至 #0FH
  • 如果直接數超過8位數值, 會產生錯誤

暫存器賦值

將暫存器A的值賦值給R0

MOV R0,A

地址賦值

將R0中存盤的值作為地址, 這個地址存盤的值賦值給A

MOV	A,@R0

加法操作

ADD A, source
  • 將source的值與A相加, 結果存盤在A
  • source可以是暫存器或直接數, 但是結果一定存盤在暫存器A
  • ADD的第一個引數, 目標暫存器必須A

例如計算 #25H + #34H

MOV A, #25H     ;load one operand
                ;into A (A=25H)
ADD A, #34H     ;add the second
                ;operand 34H to A

SDCC匯編語言基礎概念

匯編語言的指令格式為

[label:] Mnemonic [operands] [;comment]

匯編語言的編譯程序

  1. 文本匯編程式, file.asm
  2. 匯編編譯, 產生lst檔案 file.lst 和 obj檔案 file.obj
  3. 連接器, 產生abs檔案, file.abs
  4. Object to Hex轉換, 產生hex檔案, file.hex

如果使用VSCode + PlatformIO開發, 可以在專案的 .pio 目錄下看到這些檔案

LST檔案

lst(list)檔案對于開發者非常有用, 在里面會按行顯示每一句匯編陳述句對應的機器指令, 及其在代碼區的偏移位置. 可以檢查語法錯誤已經debug分析.

偽指令

  • DB: 用于定義資料, 可以是十進制數, 二進制數, 十六進制數, ASCII等
  • ORG(origin): 用于指定起始地址
  • END: 標識代碼結束
  • EQU(equate): 用于定義常量

SDCC匯編函式引數傳遞

第一個引數和回傳值

編譯器總是使用全域暫存器 DPL, DPH, B 和 ACC 傳遞第一個函式引數(必須是非bit型引數)和傳遞函式回傳結果

  • 1個位元組回傳值存盤在DPL
  • 2個位元組: DPL(LSB)和DPH(MSB)
  • 3個位元組(通用指標): DPH, DPL和 B
  • 4個位元組: DPH, DPL, B 和 ACC

在 B 中存盤通用指標的型別:

  • 0x00 – xdata/far, 外部資料存盤
  • 0x40 – idata/near – , 內部資料存盤
  • 0x60 – pdata, 外部資料存盤
  • 0x80 – code, 代碼區

bit型引數, 位引數

  • 在可重入函式中, 位引數在位可尋址空間中被傳遞到虛擬暫存器bits中
  • 其它的情況, 直接在位記憶體中存盤

第二個之后的引數

第二個引數可以在堆疊上存盤(reentrant 或者使用 --stack-auto ), 也可以在資料/xdata存盤器中存盤(取決于存盤器型號)

可重入函式

對于通過函式指標呼叫, 并且帶兩個或兩個以上引數的函式, 必須是可重入的, 這樣編譯器才能正確地傳遞引數.

相關暫存器的說明

除非函式被定義為 _naked 或 --callee-saves/--all-callee-saves 或者使用了 callee_saves pragma, 呼叫方會在呼叫前后對暫存器 R0-R7 的值進行保護和恢復, 所以被呼叫的函式可以隨意讀寫 R0-R7.

并且如果函式未被定義為 _naked, 如果呼叫方和被呼叫函式使用了不同的暫存器組(register banks, 使用 __using 宣告), 呼叫方會在呼叫前后處理暫存器組的切換.

被呼叫的函式使用 DPL, DPH, B 和 ACC 獲取引數和存盤回傳結果

示例說明

非重入的函式呼叫

在 C 語言里, 呼叫函式時會將函式引數以及函式的區域變數放入堆疊, 但是由于8位MCS-51芯片內部堆疊空間有限, 無法像 windows/unix 那樣使用堆疊, 所以無法使用這種方式, 而是為每個函式的區域變數和引數申請一個空間來存放.

下面的例子是一個簡單的函式int test(int a, int b)用于計算 a 與 b 的和并回傳. 其中

  • 第一個引數用 DPL, DPH, B, ACC 傳遞(從LSB -> MSB), a 是雙位元組, 所以存盤在 DPL, DPH
  • 第二個引數用全域變數傳遞_test_PARM_2
;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
	.globl _test_PARM_2
	.globl _test

;--------------------------------------------------------
; overlayable items in internal ram 
;--------------------------------------------------------
	.area	OSEG    (OVR,DATA)          ; DATA area 0x00 ~ 0x80, 可重疊的空間
_test_PARM_2:
	.ds 2                             ; 預留的空間, 2位元組

;--------------------------------------------------------
; code
;--------------------------------------------------------
	.area CSEG    (CODE)
;------------------------------------------------------------
;Allocation info for local variables in function 'test'
;------------------------------------------------------------
;b                         Allocated with name '_test_PARM_2'
;a                         Allocated to registers r6 r7 
;c                         Allocated to registers 
;------------------------------------------------------------
;	src/st7567_stc8h3k.c:32: int test(int a, int b)
;	-----------------------------------------
;	 function test
;	-----------------------------------------
_test:
	ar7 = 0x07                        ; ar0-ar7表示當前選中的暫存器組r0-r7的暫存器絕對地址, 
	                                  ; 這里將r0-r7的地址設定為00H到07H
	ar6 = 0x06
	ar5 = 0x05
	ar4 = 0x04
	ar3 = 0x03
	ar2 = 0x02
	ar1 = 0x01
	ar0 = 0x00
	mov	r6,dpl                        ; 將第一個引數存入 r6, r7
	mov	r7,dph
;	src/st7567_stc8h3k.c:34: int c = a + b;
	mov	a,_test_PARM_2                ; 將第二個引數的LSB存入a
	add	a,r6                          ; 低8位相加
	mov	dpl,a                         ; 結果存入DPL
	mov	a,(_test_PARM_2 + 1)          ; 將第二個引數的MSB存入a
	addc	a,r7                        ; 高8位相加, 帶前一次運算的進位
	mov	dph,a                         ; 結果存入DPH
;	src/st7567_stc8h3k.c:35: return c;
;	src/st7567_stc8h3k.c:36: }
	ret

從main中呼叫時, 第一個引數存入DPL, DPH, 第二個引數存入 _test_PARM_2_test_PARM_2 + 1

	mov	_test_PARM_2,r4
	mov	(_test_PARM_2 + 1),r5
	mov	dpl,r6
	mov	dph,r7
	lcall	_test

可重入的函式呼叫

SDCC 將區域變數放到全域變數中后, 相當于成為了靜態變數, 因此無法在遞回函式中使用(無法重入), 并且在 interrupt function 中不能呼叫, 因為當中斷發生在這些函式中時就會發生重入,
造成區域變數被修改, 造成不可預期的結果. 所以對于這類場景, 需要在函式上加上__reentrant關y鍵詞. 此時編譯器會將區域變數放到堆疊上. 在這種情況下, 第二個及之后的引數將被放在堆疊中,
引數從右到左依次入堆疊, 因此第二個引數總是最后一個入堆疊, 在堆疊的頂部.

下面的例子還是上面的簡單函式int test(int a, int b), 但是加了__reentrant關鍵詞.

在函式的入口, 舊的 _bp 被入堆疊, 之后 SP 的值被復制給 _bp, 如果在堆疊上有區域變數, 也會在 SP 上存盤, 此時 _bp 指向的是堆疊上的第一個區域變數, 引數則存盤在更低的地址上.
sp是堆疊指標, 如果不保存的話就無法回傳呼叫它的程式,
因為下面要改變堆疊指標, 所以不能用入堆疊的方法保存, 只能保存在暫存器中
bp這個暫存器是專門在堆疊段操作在堆疊區的子程式的臨時變數用的, 很方便, 所以用bp保存sp的內容

;--------------------------------------------------------
; Public variables in this module
;--------------------------------------------------------
	.globl _test                         ; 可以看到, 只有函式宣告, 沒有引數二的宣告
	                                     ; 也沒有.area	OSEG中對引數二的存盤預留

;--------------------------------------------------------
; code
;--------------------------------------------------------
	.area CSEG    (CODE)
;------------------------------------------------------------
;Allocation info for local variables in function 'test'
;------------------------------------------------------------
;b                         Allocated to stack - _bp -4       ; 引數二被放到了 _bp -4 位置, 
                                                             ; 如果還有引數三, 并且也是int, 會被放到 _bp -6 的位置
;a                         Allocated to registers r6 r7 
;c                         Allocated to registers 
;------------------------------------------------------------
;	src/st7567_stc8h3k.c:32: int test(int a, int b) __reentrant
;	-----------------------------------------
;	 function test
;	-----------------------------------------
_test:
	ar7 = 0x07                  ; ar0-ar7表示當前選中的暫存器組r0-r7的暫存器絕對地址, 這里將r0-r7的地址設定為00H到07H
	ar6 = 0x06
	ar5 = 0x05
	ar4 = 0x04
	ar3 = 0x03
	ar2 = 0x02
	ar1 = 0x01
	ar0 = 0x00
	push	_bp                   ; 將堆疊幀指標入堆疊, 原來堆疊頂是回傳地址, _bp入堆疊后, 堆疊頂變成了: 
	                            ; _bp, 回傳地址, 引數二, 因為入堆疊動作, 堆疊頂地址增長了(SDCC中堆疊地址是往上增長的), 
	                            ; SP指向了新的堆疊頂地址
	mov	_bp,sp                  ; 將此時的堆疊頂賦值給_bp, 注意, 這時候_bp里保存的變成了一個地址, 堆疊頂的地址.
	mov	r6,dpl                  ; 將引數一放入r6, r7
	mov	r7,dph
;	src/st7567_stc8h3k.c:34: int c = a + b;
	mov	a,_bp                   ; 將_bp值賦值給a, 此時a里面存了堆疊頂地址
	add	a,#0xfc                 ; 8bit數加0xfc就等于減4, 得到最后一個引數的指標, 這里第二個引數就是最后一個引數
	mov	r0,a                    ; 結果賦值給r0
	mov	a,@r0                   ; 將r0作為地址, 取到的值賦值給a
	add	a,r6                    ; 與r6相加(低8位)
	mov	r6,a                    ; 結果存回r6
	inc	r0                      ; r0++(下一個位元組的地址)
	mov	a,@r0                   ; 將r0作為地址, 取到的值賦值給a
	addc	a,r7                  ; 與r7相加(高8位), 帶前一步的進位
	mov	r7,a                    ; 將結果存回r7
	mov	dpl,r6                  ; 將回傳結果存到dpl, dph
	mov	dph,r7
;	src/st7567_stc8h3k.c:35: return c;
;	src/st7567_stc8h3k.c:36: }
	pop	_bp                     ; 在回傳前, 恢復堆疊指標
	ret

從main中呼叫這個函式, 在呼叫后恢復堆疊頂指標

	push	ar4       ; 引數二入堆疊
	push	ar5
	mov	dpl,r6      ; 引數一賦值給DPTR
	mov	dph,r7
	lcall	_test     ; 呼叫(此時會將回傳地址入堆疊)
	dec	sp          ; 此時恢復到了呼叫前的堆疊頂地址, 再dec兩次抵消掉引數二入堆疊產生的地址增長, 恢復堆疊頂位置
	dec	sp

在匯編的 reentrant 函式開頭, 有一個變數_bp, 這個變數在 sdcc/lib/src/_bp.c 中宣告, 是基址指標暫存器, 用來計算進入堆疊的引數和區域變數的偏移.
_bp is the stack frame pointer and is used to compute the offset into the stack for parameters and local variables.

基址指標暫存器BP(base pointer)的用途比較特殊, 是和堆疊指標SP聯合使用的, 例如在帶引數的子程序中用BP來獲取引數和訪問設在堆疊里面的臨時變數. 例如堆疊中壓入了資料或者地址, 如果想訪問這些資料或者地址, 但SP指向堆疊頂, 不能隨便亂改, 并且SP會隨著帶有堆疊操作(PUSH, CALL, INT, RETF)而變化, 這時候可以使用BP, 把SP的值傳遞給BP, 通過BP來尋找堆疊里資料或者地址.

參考

  • SDCC使用手冊 http://sdcc.sourceforge.net/doc/sdccman.pdf
  • 關于_BP和重入 http://jyhshin3.blogspot.com/2010/

轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/419900.html

標籤:其他

上一篇:在VS code使用Remote-SSH遠程連接Linux 開發C++ 配置詳細介紹

下一篇:檔案權限問題導致plink報錯 Failed to open 21JAN.log. Try changing the --out parameter.

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • CA和證書

    1、在 CentOS7 中使用 gpg 創建 RSA 非對稱密鑰對 gpg --gen-key #Centos上生成公鑰/密鑰對(存放在家目錄.gnupg/) 2、將 CentOS7 匯出的公鑰,拷貝到 CentOS8 中,在 CentOS8 中使用 CentOS7 的公鑰加密一個檔案 gpg -a ......

    uj5u.com 2020-09-10 00:09:53 more
  • Kubernetes K8S之資源控制器Job和CronJob詳解

    Kubernetes的資源控制器Job和CronJob詳解與示例 ......

    uj5u.com 2020-09-10 00:10:45 more
  • VMware下安裝CentOS

    VMware下安裝CentOS 一、軟硬體準備 1 Centos鏡像準備 1.1 CentOS鏡像下載地址 下載地址 1.2 CentOS鏡像下載程序 點擊下載地址進入如下圖的網站,選擇需要下載的版本,這里選擇的是Centos8,點擊如圖所示。 決定選擇Centos8后,選擇想要的鏡像源進行下載,此 ......

    uj5u.com 2020-09-10 00:12:10 more
  • 如何使用Grep命令查找多個字串

    如何使用Grep 命令查找多個字串 大家好,我是良許! 今天向大家介紹一個非常有用的技巧,那就是使用 grep 命令查找多個字串。 簡單介紹一下,grep 命令可以理解為是一個功能強大的命令列工具,可以用它在一個或多個輸入檔案中搜索與正則運算式相匹配的文本,然后再將每個匹配的文本用標準輸出的格式 ......

    uj5u.com 2020-09-10 00:12:28 more
  • git配置http代理

    git配置http代理 經常遇到克隆 github 慢的問題,這里記錄一下幾種配置 git 代理的方法,解決 clone github 過慢。 目錄 git配置代理 git單獨配置github代理 git配置全域代理 配置終端環境變數 git配置代理 主要使用 git config 命令 git單獨 ......

    uj5u.com 2020-09-10 00:12:33 more
  • Linux npm install 裝包時提示Error EACCES permission denied解

    npm install 裝包時提示Error EACCES permission denied解決辦法 ......

    uj5u.com 2020-09-10 00:12:53 more
  • Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包

    Centos 7下安裝nginx,使用yum install nginx,提示沒有可用的軟體包。 18 (flaskApi) [root@67 flaskDemo]# yum -y install nginx 19 已加載插件:fastestmirror, langpacks 20 Loading ......

    uj5u.com 2020-09-10 00:13:13 more
  • Linux查看服務器暴力破解ssh IP

    在公網的服務器上經常遇到別人爆破你服務器的22埠,用來挖礦或者干其他嘿嘿嘿的事情~ 這種情況下正確的做法是: 修改默認ssh的22埠 使用設定密鑰登錄或者白名單ip登錄 建議服務器密碼為復雜密碼 創建普通用戶登錄服務器(root權限過大) 建立堡壘機,實作統一管理服務器 統計爆破IP [root ......

    uj5u.com 2020-09-10 00:13:17 more
  • CentOS 7系統常見快捷鍵操作方式

    Linux系統中一些常見的快捷方式,可有效提高操作效率,在某些時刻也能避免操作失誤帶來的問題。 ......

    uj5u.com 2020-09-10 00:13:31 more
  • CentOS 7作業系統目錄結構介紹

    作業系統存在著大量的資料檔案資訊,相應檔案資訊會存在于系統相應目錄中,為了更好的管理資料資訊,會將系統進行一些目錄規劃,不同目錄存放不同的資源。 ......

    uj5u.com 2020-09-10 00:13:35 more
最新发布
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:43:21 more
  • vim的常用命令

    Vim的6種基本模式 1. 普通模式在普通模式中,用的編輯器命令,比如移動游標,洗掉文本等等。這也是Vim啟動后的默認模式。這正好和許多新用戶期待的操作方式相反(大多數編輯器默認模式為插入模式)。 2. 插入模式在這個模式中,大多數按鍵都會向文本緩沖中插入文本。大多數新用戶希望文本編輯器編輯程序中一 ......

    uj5u.com 2023-04-20 08:42:36 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:26:53 more
  • 設定Windows主機的瀏覽器為wls2的默認瀏覽器

    這里以Chrome為例。 1. 準備作業 wsl是可以使用Windows主機上安裝的exe程式,出于安全考慮,默認情況下改功能是無法使用。要使用的話,終端需要以管理員權限啟動。 我這里以Windows Terminal為例,介紹如何默認使用管理員權限打開終端,具體操作如下圖所示: 2. 操作 wsl ......

    uj5u.com 2023-04-19 09:25:49 more
  • docker學習

    ###Docker概述 真實專案部署環境可能非常復雜,傳統發布專案一個只需要一個jar包,運行環境需要單獨部署。而通過Docker可將jar包和相關環境(如jdk,redis,Hadoop...)等打包到docker鏡像里,將鏡像發布到Docker倉庫,部署時下載發布的鏡像,直接運行發布的鏡像即可。 ......

    uj5u.com 2023-04-19 09:19:04 more
  • Linux學習筆記

    IP地址和主機名 IP地址 ifconfig可以用來查詢本機的IP地址,如果不能使用,可以通過install net-tools安裝。 Centos系統下ens33表示主網卡;inet后表示IP地址;lo表示本地回環網卡; 127.0.0.1表示代指本機;0.0.0.0可以用于代指本機,同時在放行設 ......

    uj5u.com 2023-04-18 06:52:01 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:50 more
  • 解決linux系統的kdump服務無法啟動的問題

    問題:專案麒麟系統服務器的kdump服務無法啟動,沒有相關日志無法定位問題。 1、查看服務狀態是關閉的,重啟系統也無法啟動 systemctl status kdump 2、修改grub引數,修改“crashkernel”為“512M(有的機器數值太大太小都會導致報錯,建議從128M開始試,或者加個 ......

    uj5u.com 2023-04-12 09:59:01 more
  • 你是不是暴露了?

    作者:袁首京 原創文章,轉載時請保留此宣告,并給出原文連接。 如果您是計算機相關從業人員,那么應該經歷不止一次網路安全專項檢查了,你肯定是收到過資訊系統技術檢測報告,要求你加強風險監測,確保你提供的系統服務堅實可靠了。 沒檢測到問題還好,檢測到問題的話,有些處理起來還是挺麻煩的,尤其是線上正在運行的 ......

    uj5u.com 2023-04-05 16:52:56 more
  • 細節拉滿,80 張圖帶你一步一步推演 slab 記憶體池的設計與實作

    1. 前文回顧 在之前的幾篇記憶體管理系列文章中,筆者帶大家從宏觀角度完整地梳理了一遍 Linux 記憶體分配的整個鏈路,本文的主題依然是記憶體分配,這一次我們會從微觀的角度來探秘一下 Linux 內核中用于零散小記憶體塊分配的記憶體池 —— slab 分配器。 在本小節中,筆者還是按照以往的風格先帶大家簡單 ......

    uj5u.com 2023-04-05 16:44:11 more