~雜記(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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章