1. 程式人生 > >~雜記(2):StartUP.s檔案

~雜記(2):StartUP.s檔案

1. S檔案中的彙編知識

彙編程式中以 . 開頭的名稱 並不是指令的助記符,不會被翻譯成機器指令。
而是給彙編器一些特殊指示,稱為彙編指示(Assembler Directive)或偽操作(Pseudo-operation),由於它不是真正的指令所以加個“偽”字。

.section 劃分段

.section指示把程式碼劃分成若干個段(Section),程式被作業系統載入執行時,每個段被載入到不同的地址,作業系統對不同的頁面設定不同的讀、寫、執行許可權。
例如:

.section .data 	//.data段儲存程式的資料,是可讀可寫的,相當於C程式的全域性變數。(data segment)
.section .text	//.text段儲存程式碼,是隻讀和可執行的,後面那些指令都屬於.text段。(code segment/text segment)
.section .bss	//.bss段用來存放程式中未初始化的全域性變數的一塊記憶體區域,BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態記憶體分配。 
.section .vectors	//中斷向量段。
//補充--------------------------------------------------------------------------------
//堆(heap)	當程序呼叫malloc等函式分配記憶體時,新分配的記憶體就被動態新增到堆上(堆被擴張);當利用free等函式釋放記憶體時,被釋放的記憶體從堆中被剔除(堆被縮減) 

//棧(stack) 	存放程式臨時建立的區域性變數,也就是說我們函式括弧“{}”中定義的變數(但不包括static宣告的變數,static意味著在資料段中存放變數)。

.globl 宣告變數到連結器

.globl 用於宣告變數,並通知編譯器,在目標檔案的符號表中標記它是一個全域性符號。表明該變數會被連結器用到。例如:

/*
_start是一個符號(Symbol)
_start就像C程式的main函式一樣特殊,是整個程式的入口
每個彙編程式都要提供一個_start符號並且用.globl宣告
一個符號沒有用.globl宣告,就表示這個符號不會被連結器用到
*/
.globl _start

_start:	//這裡定義了_start符號,它後面一條指令的地址作為這個符號所代表的地址
(略)

.align 對齊段落

.align 後面接立即數,預設是4位元組對齊。屬於編譯器的指令(不屬於ARM指令)。

 .section .vectors
 .align  10

.import 匯入外部標號

.import 宣告標號來自外部檔案,跟C語言中的EXTERN關鍵字類似

.import irq_dispatch
.import g_int_cnt

.space 分配記憶體空間

.space  0x200

.word或.long 資料定義

為特定的資料分配儲存單元,也可以完成已分配儲存單元的初始化

.long Reset_Handler
.long vec_handler
(略)
/*
ADS和GNU兩種環境下的對比
.byte == DCB(分配位元組儲存單元)-128~255之間的數字或字串
.hword或.short == DCW(分配半字儲存單元)-32768~65535間的數字表達式
.word或.long == DCD(分配字儲存單元)是表示式
.quad == 8位元組
.float ==定義浮點數
.string/.asciz/.ascii ==定義多個字串
*/

2、操作指令

相關知識

  1. 指令和偽指令。
  2. 大寫風格的指令和小寫風格的指令。

CPU和記憶體的資料交換

  1. ldr(load register)指令將記憶體內容載入入通用暫存器。
  2. str(store register)指令將暫存器內容存入記憶體空間中。
  3. ldr/str組合用來實現 ARM CPU和記憶體資料交換。

8種定址方式

  1. 暫存器定址 mov r1, r2。
  2. 立即(立即數)定址 mov r0, #0xFF00。
  3. 暫存器移位定址 mov r0, r1, lsl #3。
  4. 暫存器間接定址 ldr r1, [r2] 表示記憶體,記憶體地址存在r2這個暫存器中,把記憶體地址裡的值給r1。
  5. 基址變址定址 ldr r1, [r2, #4]記憶體地址在r2+4裡面。
  6. 多暫存器定址 ldmia r1!, {r2-r7, r12}一次訪問多個暫存器。
  7. 堆疊定址 stmfd sp!, {r2-r7, lr}。
  8. 相對定址 beq flag。

指令字尾

B(byte)功能不變,操作長度變為8位
H(half word)功能不變,長度變為16位
S(signed)功能不變,運算元變為有符號
如 ldr ldrb ldrh ldrsb ldrsh
S(S標誌)功能不變,影響CPSR標誌位
如 mov和movs movs r0, #0

例項解讀(很多指令不知道什麼意思,只知道就是在配置裝置)

希望看的懂得朋友,告訴我一下,我再修改。

Reset_Handler:     /* set the priority cpu ahb */     
    lrw       r0, AHB_BASE     //把AHB基地址載入到R0中。lrw可以理解為loader Word
    movi    r1, 0x1     		 //向R1移動立即數。move immediate number
    movi    r2, 0x2     
    movi    r3, 0x3     
    movi    r4, 0x4     
    stw     r1, (r0, 0x0)     	//將R1中的內容存放到AHB的偏移地址0x0所在記憶體空間。store word
    stw     r2, (r0, 0xc)     
    stw     r3, (r0, 0x4)     
    stw     r4, (r0, 0x8) 
    /* restore the eflash state when system reboot from deep sleep */
    lrw     r0, PMU_LP_CONTROL
    ldw     r1, (r0, 0)
    btsti   r1, 5
    bf      .LSetClk
    lrw     r0, EFLASH_CONTROL_BASE
    movi    r1, 0x35
    stw     r1, (r0, 0x24)
    movi    r1, 0x16
    stw     r1, (r0, 0x28)
    movi    r1, 0x35
    stw     r1, (r0, 0x2c)
    movi    r1, 0x1b9
    stw     r1, (r0, 0x30)
    movi    r1, 0x8b10
    stw     r1, (r0, 0x34)

3、參考文章

https://www.cnblogs.com/snail-micheal/p/4189632.html
https://www.cnblogs.com/zhangj95/p/5646334.html
https://wenku.baidu.com/view/bad36fb577232f60dccca19a.html
https://blog.csdn.net/wuyuzun/article/details/70518507
https://www.cnblogs.com/wxb20/p/6249580.html