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
A
ARM汇编语言中的伪操作(一) http://www.kingofcoders.com/viewNews.php?type=newsCpp&id=185&number=1521487605