幾個常用(僞)彙編指令詳解



SDRAM例程:

從Nand Flash啓動CPU時,CPU會自動將Nand Flash開始的4K數據複製到4KB的內部Ram中(起始地址0),然後地址0開始執行。

本例程先用匯編設置好SDRAM,將程序從內部Ram複製到SDRAM,然後跳轉到SDRAM執行。

源代碼包括sdram.S、gpio.c、s3c2440.h,編譯爲二進制文件後燒寫到NandFlash運行。

sdram.S如下:

1.@***************************************** 
2.@ File name   : sdram.S 
3.@ Project name: sdram 
4.@ Author      : Bob 
5.@ Date        : 2011-7-9 
6.@ Description : 設置SDRAM,將steppingstone中的程序複製到sdram,然後跳轉到sdram執行。 
7.@***************************************** 
8. 
9..data 
10..equ MEM_CTL_BASE, 0x48000000  @ 存儲器控制器的寄存器首地址 
11..equ SDRAM_BASE,   0x30000000  @ sdram的起始地址 
12. 
13..text 
14..global _start 
15._start: 
16.    bl disable_watch_dog 
17.    bl memsetup 
18.    bl copy_steppingstone_to_sdram 
19.    ldr pc, =on_sdram   @ 跳轉到on_sdram,這是sdram中的地址 
20. 
21.on_sdram: 
22.    ldr sp, =0x34000000       @設置棧 
23.    bl main 
24.halt_loop: 
25.    b halt_loop 
26. 
27.@ 禁止watch dog 
28.disable_watch_dog: 
29.    mov r1, #0x53000000    @ watch dog 寄存器的地址 
30.    mov r2, #0x0 
31.    str r2, [r1] 
32.    mov pc, lr            @返回 
33. 
34.@ 將steppingstone的內容全部複製到sdram 
35.copy_steppingstone_to_sdram: 
36.    mov r1, #0            @ r1存放steppingstone的起始地址 
37.    ldr r2, =SDRAM_BASE   @ r2存放sdram的起始地址 
38.    mov r3, #4*1024       @ steppingstone的大小時4KB 
39.1: 
40.    ldr r4, [r1],#4     @ 從steppingstone中讀取4Byte,[r1]->r4,r1=r1+4 
41.    str r4, [r2],#4     @ 將4Byte複製到sdram,r4->[r2],r2=r2+4 
42.    cmp r1, r3    @ 判斷是否複製完4KB,r1等於4*1023時,複製結束 
43.    bne 1b        @ 如果不相等,跳回1處 
44.    mov pc, lr    @ 返回 
45. 
46.@ 設置存儲器控制器的寄存器 
47.memsetup: 
48.    mov r1, #MEM_CTL_BASE  @ r1存放存儲器控制器的寄存器首地址 
49.    adrl r2, mem_cfg_val   @ r2存放mem_cfg_val的起始地址 
50.    add r3, r1,#52       @ r3=r1+52,r3存放mem_cfg_val的結束地址,有13個寄存器,13*4=52 
51.1: 
52.    ldr r4, [r2],#4 
53.    str r4, [r1],#4 
54.    cmp r1, r3 
55.    bne 1b 
56.    mov pc, lr 
57. 
58.@ 存儲器控制器的13個寄存器的值 
59..align 4   @ 以下數據都以4Byte對齊 
60.mem_cfg_val: 
61.    .long 0x22011110      @ BWSCON 
62.    .long 0x00000700      @ BANKCON0 
63.    .long 0x00000700      @ BANKCON1 
64.    .long 0x00000700      @ BANKCON2 
65.    .long 0x00000700      @ BANKCON3 
66.    .long 0x00000700      @ BANKCON4 
67.    .long 0x00000700      @ BANKCON5 
68.    .long 0x00018005      @ BANKCON6 
69.    .long 0x00018005      @ BANKCON7 
70.    .long 0x008c07a3      @ REFRESH 
71.    .long 0x000000b1      @ BANKSIZE 
72.    .long 0x00000030      @ MRSRB6 
73.    .long 0x00000030      @ MRSRB6  

說明:
ldr:

當第二個操作數前面沒有“=”時,表示內存訪問指令,從內存中讀取4Byte數據到寄存器,語法格式如下:

ldr{條件} 目的寄存器, 存儲器地址

如果第二個操作數前面有“=”,表示大範圍地址讀取僞指令,用於加載32位的立即數或一個地址到指定寄存器,語法格式如下:

ldr 目的寄存器, =32位立即數/地址

str:

內存訪問指令,從源寄存器將一個32位數據傳送到存儲器中,語法格式如下:

str{條件} 源寄存器, 存儲器地址

adrl r2, mem_cfg_val:

adrl是中等範圍地址讀取僞指令,將基於pc相對偏移的地址值或基於寄存器相對偏移的地址值讀取到寄存器中,在彙編編譯器編譯源程序時,adrl僞指令被編譯器替換成兩條合適的指令。若不能用兩條指令實現,則產生錯誤,編譯失敗。這條代碼會替換爲:

30000050: e28f2018  add r2, pc, #24 ; 0x18

30000054: e1a00000  nop (mov r0,r0)

adrl僞指令格式:

adrl{cond}   register, expr

地址表達式expr的取值範圍:

當地址值是字節對齊時,其取指範圍爲: -64K~64K;

當地址值是字對齊時,其取指範圍爲: -256K~256K;

nop:

空操作僞指令,在彙編是替換成ARM中的空操作,例如mov r0, r0

cmp:

比較指令,格式如下:

cmp{條件} 操作數1, 操作數2

用與將一個寄存器的內容和另一寄存器的內容或立即數進行比較,然後更新CPSR中條件標誌位的值,標誌位表示操作數1和操作數2的關係(大於、小於、相等)。

bne 1b:

b(跳轉指令)+ne(條件:不相等),如果CPSR的Z位爲0(不相等),就跳轉到後面的1標號處。

b表示向後搜索,已經執行過的代碼爲‘後’;

f表示向前搜索,還未執行的代碼爲‘前’。

mov  pc, lr

從子程序返回。lr爲子程序鏈接寄存器(r14),當執行bl子程序調用指令時,lr會備份pc(程序計數器r15)。

.align

指定對齊方式,gnu彙編命令都以一個點開頭。

.equ

賦值命令,格式如下:

.equ symbol, expression

設置symbol的值爲expression。

.long

定義一個4Byte的數據。

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