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 目的暫存器, 儲存器位址
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 register, 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的資料。
幾個彙編指令iret,ret,int
ret指令用棧中的資料,修改ip的值,從而實現近轉移。cpu執行ret指令時,進行下面兩步操作 ip ss 16 sp sp sp 2 另一種用法 ret n n為整數 等效於 ip ss 16 sp sp sp 2 sp sp n 例如ret 4 pop ip add sp,4 例 push ea...
彙編 常用指令
一 資料傳送指令 mov 傳送資料 兩個運算元 xchg 交換指令 兩個運算元 movsx 擴充套件資料指令 兩個運算元 movzx 擴充套件資料指令 兩個運算元 xlat 查表指令 無運算元 push pop 入棧,出棧 乙個運算元 lea 位址傳送指令 兩個運算元 in out 輸入輸出指令 兩...
彙編常用指令
一 資料傳輸指令i.4.標誌傳送指令.lahf 標誌暫存器傳送,把標誌裝入ah.sahf 標誌暫存器傳送,把ah內容裝入標誌暫存器.pushf 標誌入棧.popf 標誌出棧.pushd 32位標誌入棧.popd 32位標誌出棧.二 算術運算指令 add 加法.adc 帶進製加法.inc 加 1.aa...