TX2440 裸跑实验-伪指令学习例子(ADS1.2编译) 进阶(三)

来源:互联网 发布:必赢客软件使用技巧 编辑:程序博客网 时间:2024/05/29 10:53

TX2440 裸跑实验-伪指令学习例子(ADS1.2编译) 进阶(三)

 

学习进度:

        学习完前面入门级,进阶一.二.我们还不能全面系统地写一编有变量和逻辑控制思想的程序.学习完进阶三.就可以基本可以写出一编完整的arm汇编程序出来.剩下的需要大家多练习才能写出高效的程序出来.

 

 

 

源码 init.s

 

;我的源码(伪指令学习):EastonWoo

base_adr equ 0x30010000
field_adr equ 0x30020000
registList rlist {v1-v8,ip}
register0 rn r0  ;rn 别名 ,给r0定义一个别名register0

;********************全局变量**************************************
 gbla nValue
 gbll bValue
 gbls sValue
nValue seta 0xaa    ;其实nValue 就相当于标号了,所以要顶可写.
bValue setl {false}   ;{false} ;{TRUE}
sValue sets "hello"

 gbls sPrintf
sPrintf sets "nValue = $nValue.; bValue = $bValue.; sValue = $sValue."  ;使用'.'来表示字符串中变量名的结束
;******************************************************************

 
;********************最简单宏**************************************
 macro     ;伪指令都不能顶格写.前面要有空格.宏定义可以看成是一个代码段.
 my_macro  ;my_macro不是标号,而成为了伪指令.所以不能顶格写.
 lcla nLValue
nLValue seta 0x11
 mov r0,#nValue
 mend
;******************************************************************


;********************带参数宏**************************************
  macro
$func_index ldr_r0_r1 $value1,$value2

$func_index         ;这个标号会被展开成ldr_1_2和ldr_3_4.成为两个函数. 有点像函数指针:#define void (pFunc*)(int a, int b);
 ldr r0,=$value1
 ldr r1,=$value2
 mov pc,lr
 
 mend
;******************************************************************


 area init,code,readonly
 
 ;import print
 entry
 
 code32   ;声明为32位ARM指令
 ldr sp,=0x33ff3800


main
 ;============== 数据定义( Data Definition )伪指令 ===================
 ldr r0,=allocateMemery ;adr 是相对寻址,ldr是绝对寻址.
 ldr r1,[r0]           ;r1 = nValue前四个字母nVal
 ;bl print
 
 ldr r0,=allocateBYTE1  ;r0 = 0x3000002c  1byte
 ldr r1,[r0]           ;r1 = 0x44
 
 ldr r0,=allocateBYTE2  ;r0 = 0x3000002d  1byte
 ldr r1,[r0]           ;r1 = 0x55
 
 ldr r0,=allocateDWORD  ;r0 = 0x3000002e  2byte
 ldr r1,[r0]           ;r1 = 0x8899
 
 ldr r0,=allocateWORD   ;r0 = 0x30000030  4byte  
 ldr r1,[r0]           ;r1 = 0x11223344
 
 ldr r0,=buf
 mov v1,#1
 mov ip,#2
 stmia r0,registList  ;将v1-v8,ip的值全装入到r0指向的内存地址.
 ldr r0,=base4_0
 ldr r0,=base16_1
 ldr r0,=base4_2
 ldr r0,=base4_3
 
 ;----------------华丽分界线---------------------------------
 
 ;============== 符号定义( Symbol Definition )伪指令 ===================
 ldr r0,=allocateMoney ;注:ldr r0,allocateMoney的LDR是ARM的装载寄存器指令,而ldr r0,=allocateMoney的LDR是ARM汇编语言伪指令
 ldr r1,[r0]
 
 bl FuncRMB
 bl |Func$money|   ; $号已超出标号的命名规则.所以有加"||"加以屏蔽.
 
 
 
 ;----------------华丽分界线---------------------------------
    
 ;============== 汇编控制( Assembly Control )伪指令 ===================
 [ nValue = 0xaa                 ;if(nValue == 0xaa)
  [ bValue                    ;{    if(bValue == true)
   mov r0,#0x03            ;     { r0 = 3; }
   |                       ;     else
   mov r0,#0x04            ;     { r0 = 4; }
  ]                           ;}
  |                           ;else
  mov r0,#0x02                ;{r0 = 2;}
 ]                               ;}
 
 if nValue = 0xaa
  if bValue
   mov r0,#0x03
  else
   mov r0,#0x04
  endif
 else
 mov r0,#0x02
 endif
 
 gbla counter
counter seta 3
 mov r0,#0
 while counter <= 10
 add r0,r0,#counter    ;循环3-10,最后r0的结果为52.
counter seta counter+1
 wend
 
 ;----------------华丽分界线---------------------------------
 
 ;============== 宏指令以及其他伪指令 ===================
 
 ;;;;CODE32 ;通知编译器其后的指令为 32 位的 ARM 指令   
    ;;;;LDR R0 ,= NEXT + 1 ;将跳转地址放入寄存器 R0   
    ;;;;BX R0 ;程序跳转到新的位置执行,并将处理器切换到 Thumb 工作状态   
    ;;;;......
    ;;;;CODE16 ;通知编译器其后的指令为 16 位的 Thumb 指令   
    ;;;;NEXT LDR R3,=0x3FF
   

 mov register0,#4   ;相当于 mov r0,#4
 
   
 bl ldr_1_2
 bl ldr_3_4
 
 my_macro            ;汇编后,只有"MOV      r0,#0x11" 这一句
 mov r0,#nValue      ;nValue 是全局标号.
 ;mov r0,#nLValue    ;nLValue 是局部标号.是编译不过的.
 
 b main

ldr_1_2 ldr_r0_r1 1,2
ldr_3_4 ldr_r0_r1 3,4

 gbls money
money sets "RMB"

Func$money       ;替换后,标号应该为"FuncRMB"
 mov r0,#1
 mov pc,lr

|Func$money|     ;在两个"|"之间的"$"并不进行变量的代换,标号应该为"Func$money"
 mov r0,#2
 mov pc,lr


 area read_mem_data,data,readwrite
 map base_adr ;MAP 伪指令用于定义一个结构化的内存表的首地址。 MAP 也可用 "^" 代替
base4_0    # 4       ;base4_0 = base_adr
base16_1    # 16     ;base16_1 = base4_0 + 4
base4_2    # 4       ;base4_2 = base16_1 + 16
base4_3    # 4       ;base4_3 = base4_2 + 4

;注意 MAP 和 FIELD 伪指令仅用于定义数据结构,并不实际分配存储单元。

 ^ field_adr     ;定义结构化内存表首地址的值为 0x30020000 。 ; space 也可用 "#" 代替  
A field 16          ;定义 A 的长度为 16 字节,位置为 0x30020000   
B # 32          ;定义 B 的长度为 32 字节,位置为 0x30020010   
S field 256         ;定义 S 的长度为 256 字节,位置为 0x30020030

buf
 space 9*4 ;% 9*4    ; space 也可用 "%" 代替

allocateMoney
 dcb "$$$$sValue$abcd$"     ;字符串只能用dcb;内存中的值为"$$hello$abcd$",可以看出,$sValue被替换成hello了.两个"$$"就被看作"$"
allocateMemery
 dcb "$sPrintf"         ;类似于开辟内存,把"nValue = 000000AA; bValue = F; sValue = hello"的AIISC码写进去.
 
allocateBYTE1
 dcb 0x44               ;类似于memset(p,0,sizeof(char));*p = 0x44
 
allocateBYTE2
 dcb 0x55

allocateDWORD
  dcw 0x8899
  
allocateWORD
  dcd 0x11223344
 end

 

 

参考网址:

ARM汇编伪指令介绍 http://patton.spaces.eepw.com.cn/articles/article/item/32951

ARM http://wenku.baidu.com/view/d8d763323968011ca30091e3.html

ARM汇编语言中的伪操作(一) http://www.kingofcoders.com/viewNews.php?type=newsCpp&id=185&number=1521487605



 

 

原创粉丝点击