arm汇编编程(示例)
过程
(1)程序从ENTRY后面指令处开始运行(即主函数)
R0和R1赋初值2和5
将R0与R1相加后存入R5内
(2)CMP用于比较两个数据,指令格式如下:
CMP操作数1,操作数2
CMP用于把一个寄存器的内容和另一个寄存器或立即数进行比较,同时
更新CPSR中条件标志位的值。标志位表示操作数1和操作数2的关系。然后执行后面的语句
(3)条件助记符
BEQB为跳转指令,EQ为条件相等,读取CPSR内的条件标志位,如相等则跳转到所指定的标号处
BNEB为跳转指令,NE为不相等(0),如不相等则跳转到所指定的标号处
ADDHIADD为相加指令,HI为无符号大于,如大于则执行相加
ADDLSADD为相加指令,LS为无符号小于或等于,如小于或等于则相加
(4)位运算
ANDSAND按位与,0x80取出第7位,S为将该位与的值写入标志位
3.循环语句
AREAExample,CODE,READONLY;声明代码段Example
ENTRY;程序入口
Start
MOVR1,#0;将R1赋初值0
LOOP
ADDR1,R1,#1
CMPR1,#10
BCCLOOP;R1小于10则执行跳转到LOOP处执行循环,即R1从0到10后退出循环
END
例:编写一具有完整汇编格式的程序,实现冒泡法排序功能。
设无符号字数据存放在从0x400004开始的区域,字数据的数目字存放在0x400000中。
AREASORT,CODE,READONLY
ENTRY
START
MOV R1,#0x400000
LP
SUBS R1,R1,#1
BEQ EXIT
MOV R7,R1
LDR R0,=0x400004
LP1
LDR R2,[R0],#4
LDR R3,[R0]
CMP R2,R3
STRLOR3,[R0,#-4]
STRLOR2,[R0]
SUBSR7,R7,#1
BNE LP1
B LP
EXIT
END
练习:
1.编写1+2+3+…+100的汇编程序。
2.实现子函数,该函数返回两个参数中的最大值,在主函数内调用。
//*arm体系结构第四天*
四.伪操作和宏指令
伪指令——是汇编语言程序里的特殊指令助记符,在汇编时被合适的机器指令替代。
伪操作——为汇编程序所用,在源程序进行汇编时由汇编程序处理,只在汇编过程起作用,不参与程序运行。
宏指令——通过伪操作定义的一段独立的代码。在调用它时将宏体插入到源程序中。也就是常说的宏。
说明:所有的伪指令、伪操作和宏指令,均与具体的开发工具中的编译器有关
1.宏定义(MACRO、MEND)
格式:MACRO
{$标号名}宏名{$参数1,$参数2,……}
指令序列
MEND
MACRO、MEND伪指令可以将一段代码定义为一个整体,称为宏指令,在程序中通过宏指令多次调用该段代码。
{}为可选项
$标号在宏指令被展开时,标号会被替换为用户定义的符号
在宏定义体的第一行应声明宏的原型(包含宏名、所需的参数),然后就可以在汇编程序中通过宏名来调用该指令序列
写在代码段或数据段前面
MEXIT跳出宏
例:没有参数的宏(实现子函数返回)
MACRO
MOV_PC_LR;宏名
MOVPC,LR;子程序返回,R0内为返回的结果
MEND
AREAExample,CODE,READONLY;声明代码段Example
ENTRY;程序入口
Start
MOVR0,#0;设置实参,将传递给子程骗子的实参存放在r0和r1内
MOVR1,#10
BLADD_NUM;调用子程序ADD_NUM
BLSUB_NUM;调用子程序SUB_NUM
BOVER;跳转到OVER标号处,进入结尾
EXPORTADD_NUM
ADD_NUM
ADDR0,R0,R1;实现两数相加
MOV_PC_LR;调用宏,代表子函数结束
EXPORTSUB_NUM
SUB_NUM
SUBR0,R1,R0;实现两数相减
MOV_PC_LR;调用宏,代表子函数结束
OVER
END
例:有参数宏
宏定义从MACRO伪指令开始,到MEND结束,并可以使用参数。类似于C的#define
MACRO;宏定义
CALL$Function,$dat1,$dat2;宏名称为CALL,带3个参数
IMPORT$Function;声明外部子程序宏开始
MOVR0,$dat1;设置子程序参数,R0=$dat1
MOVR1,$dat2
BL$Function;调用子程序宏最后一句
MEND;宏定义结束
CALLFADD1,#3,#2;宏调用,后面是三个参数
汇编预处理后,宏调用将被展开,程序清单如下:
IMPORTFADD1
MOVR0,#3
MOVR1,#3
BLFADD1
2.符号定义伪操作
1)定义常量(EQU)
格式:标号名称EQU表达式{,类型}
用于为程序中的常量、标号等定义一个等效的字符名称,类似于C语言中的#define。
其中EQU可用*代替。
标号名称:为常量名。
表达式:寄存器的地址值、程序中的标号、32位地址常量、32位常量
当表达式为32位的常量时,可以指定表达式的数据类型,可以有以下三种类型:
CODE16、CODE32和DATA
示例:EQU的使用
XEQU45;即#defineX45,必须顶格
YEQU64
stack_topEQU0x30200000,CODE32
AREAExample,CODE,READONLY
CODE32
ENTRY
Start
LDRSP,=stack_top;stack_top内的值0x30200000是地址,=stack_top是取stack_top常量地址(即指针的指针)
MOVR0,#X;将X替换为45
STRR0,[SP];将R0内的45存入到SP所指向的内存中(SP此时是指针的指针)
MOVR0,#Y
LDRR1,[SP];从内存中读取数据到R1内
ADDR0,R0,R1
STRR0,[SP]
END
注:X,Y,stack_top为标号,必须顶格写,大多写在代
arm汇编编 相关文章:
- ARM汇编编程基础之四-ARM汇编伪操作(11-27)
- ARM汇编编程基础之三-基本寻址方式与基本指令(11-27)
- ARM汇编编程基础之一-寄存器(11-27)
- ARM汇编编程基础之五-ADS开发环境的使用(11-27)
- ARM汇编编程基础之二-流水线对PC值的影响(11-27)
- ARM汇编编程基础之六-其它寻址模式与其它指令(11-27)