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

2021-07-15 06:01:10 字數 4224 閱讀 8486



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...