ARM汇编程序设计之:汇编语言文件格式
下面的两个例子说明了变量替换的过程。
;直接的变量替换
GBLSadd4ff
;
add4ffSETSADDr4,r4,#0xFF ;给变量add4ff赋值
$add4ff.00 ;引用变量
;codes
ADDr4,r4,#0xFF00
;有特殊符号的变量替换
GBLSs1
GBLSs2
GBLSfixup
GBLAcount
;
countSETA14
s1SETSa$$b$count ;s1=a$b0000000E
s2SETSabc
fixupSETS|xy$s2.z| ;fixup=|xyabcz|
|C$$code|MOVr4,#16 ;label=C$$code
4.程序标号(label)
在ARM汇编中,标号代表一个地址,段内标号的地址在汇编时确定,而段外标号地址值在链接时确定。根据标号的生成方式,程序标号分为以下三种。
·程序相关标号(Program-relativelabels)。
·寄存器相关标号(Register-relativelabels)。
·绝对地址(Absoluteaddress)。
(1)程序相关标号
程序相关标号指位于目标指令前的标号或程序中的数据定义伪操作前的标号。这种标号在汇编时将被处理成PC值加上或减去一个数字常量。它常用于表示跳转指令的目标地址或代码段中所嵌入的少量数据。
(2)寄存器相关地址
这种标号在汇编时将被处理成寄存器的值加上或减去一个数字常量。它常被用于访问数据段中的数据。这种基于寄存器的标号通常用MAP和FIELD伪操作定义,也可以用EQU伪操作定义。
(3)绝对地址
绝对地址是一个32位的数字量,使用它可以直接寻址整个内存空间。
5.局部标号
局部标号是一个0~99之间的十进制数字,可重复定义。局部标号后面可以紧接一个通常表示该局部变量作用范围的符号。局部变量的作用范围为当前段,也可以用伪操作ROUT来定义局部标号的作用范围。
局部标号在子程序或程序循环中常被用到,也可以配合宏定义伪操作(MACRO和MEND)来使程序结构更加合理。
在同一个段中,可以使用相同的数字命名不同的局部变量。默认情况下,汇编器会寻址最近的变量。也可以通过汇编器命令选项来改变搜索顺序。
局部变量命名语法如下。
n{routname}
局部变量引用的语法格式如下。
%{F|B}{A|T}n{routname}
其中,routname为变量作用范围名称;%表示引用操作;F指示汇编器只向前搜索;B指示汇编器只向后搜索;A指示汇编器搜索所有宏的嵌套。T指示汇编器只搜索宏的当前层。
如果在引用过程中,没有指定F和B,则汇编器先向后搜索,再向前搜索。
如果A和T没有指定,汇编器搜索所有从当前层次到宏最高层次,比当前层次低的层次不再搜索。
如果指定了routname,汇编器向前搜索最近的ROUT操作,若routname与该ROUT伪操作定义的名称不匹配,汇编器报告错误并结束汇编。
10.3.3汇编语言程序中的表达式和运算符
在汇编语言程序设计中经常使用各种表达式,表达式一般由变量、常量、运算符和括号构成。常用的表达式有数字表达式、逻辑表达式和字符串表达式。
下面分别介绍表达式中各元素。
1.字符串表达式
字符串表达式一般由字符串常量、字符串变量、运算符和括号构成。字符串由包含在双引号内的一系列字符组成。编译器所支持的字符串最大长度为512字节。
当在字符串中包含“$”或引号时,可以用“$$”表示“$”,用两个双引号表示一个双引号。
例如:
abcSETSonedoublequote
defSETSone$$dollarsymbol
上面的例子分别将字符串abc和def赋值为“onedoublequote”和“one$dollarsymbol”。
字符串可以通过SETA、SETL、SETS伪操作对其赋值。
常用的与字符串表达式相关的运算符如下。
·LEN:计算字符串长度运算符。
·CHR:ASCII码转换运算符。
·STR:字符串转换运算符。
·LEFT:字符串取左运算符。
·RIGHT:字符串取右运算符。
·CC:字符串连接运算符。
详见后面操作符一节。
下面的例子说明了如何使用字符串操作符给字符串变量赋值。
improbSETSliteral:CC:(strvar2:LEFT:4)
这个例子将字符串赋值为“literalatrv”。
2.整数表达式
整数表达式一般由数字常量、数字变量、数字运算符和括号构成。
整数表示式可以包含寄存器相关(register-relative)或程序相关(program-relative)表达式,这些表达式在编译时被汇编器翻译为地址无关数字常量。
整数表达式一般被计算为32位的整数,当此整数被定义为无符号数时,其取值范围为0~232-1,当被定义为有符号数时,其取值范围为-231~231-1。汇编器认为-n和232-n是相等的。对于关系操作,如比较两个数的大小,汇编器将其操作数看作无符号的数,也就是说“0>-1”对汇编器来说取值为“假({FLASE})”。
下面的例子说明了在程序中,如何对整数表达式进行操作。
aSETA256*256;将数字变量赋值为256*256
MOVr1,#(a*22);将数字表达式(a*22)的值放入r1
汇编语言中,整数数字量有以下几种形式。
·十进制数(decimal-digis)
·“0x”+十六进制数(0xhexadecimal-digits)
·“”+十六进制数(hexadecimal-digits)
·n进制数(n_base-n-digits)
·字符(character)
其中,十进制数(decimal-digis)可以是“0”到“9”数字的任意组合;十六进制数(hexadecimal-digits)可以是“0”到“9”数字和字母“A”到“F”的任意组合;“n_”可以取2到9,“base-n-digits”是在n进制下合法的任意数值;字符(character)可以是除单引号以外的所有字符。
下面的例子说明了整数表达式的基本用法。
aSETA34906
addrDCD0xA10E
LDRr4,=1000000F
DCD2_11001010
c3SETA8_74007
DCQ0x0123456789abcdef
LDRr1,='A' ;ARM伪指令将整数65(A的ASCII码)存入寄存器
ADDr3,r2,#' ;将整数39(字符“/”的ASCII码)加到r2,结果存入r3
评论