; 还未更新完...
;--------作者:时空自由民
;
;-----------ARM 汇编语言 例子
;-------常见指令后缀
EQ ;相等
NE ;不相等
CS/HS ;无符号数大于或等于
......
ADD R0,R0,#1 ; R0+1 -> R0
MOV R0,#0X00FF ; R0=0X00FF
MOVS R0,R1,LSL #3 ;将寄存器R1值 左移3位后传送到R0 并影响标志位
MVN R0,R1 ;将寄存器R1值按位求反后送入R0
MVN R0,#0XFF ;将立即数0XFF 按位取反后装入R0 然后R0=0xffffff00
ADD R0,R1,R2 ; R1+R2 ->R0
MOV R0,R1 ; R1->R0
LDR R0,[R1] ; [R1]->R0 假设 R1存储的是0x3FE是内存地址 则是将00X3FE内存地址中的数据存入R0
MOV R0,R1,LSL #2 ; R1<<2 ->R0, LSL 左移命令 LSR右移命令 ASR算数右移 ROR循环右移 RRX带扩展的循环右移
ADD R0,R1,R2,LSR #3 ;R1 + R2>>3 ->R0
SUB R0,R0,#1 ; R0=R0-1
SUB R0,R1,R2 ; R0=R1-R2
SUB R0,R1,R2,LSL #3 ;R0=R1-(R2<<3)
LDR R0,[R1,#2] ; [R1+2] ->R0 R1中的值+2 当作内存地址 然后将内存地址中的值 赋值到R0
STR R1,[R0,#0X12] ; R1 ->R0+0X12地址内存中去
STR R1,[R0],#0X12 ; R1 ->R0+0X12地址内存中去 R0=R0+0X12
RSB R0,R0,#0XFFFF ;R0=0XFFFF - R0
RSB R0,R1,R2 ;R0=R2-R1
AND R0,R1,R2 ; R0= R1 & R2
AND R0,R0,#3 ; R0=R0&3
ORR R0,R0,#3 ; R0=R0|3
EOR R0,R0,#0F ; R0=R0 异或 0F
BIC R0,R0,#0F ; 将R0的低4位 清0
CMP R1,R0 ; R1-R0 并改变CPSR的标志位
CMN R1,R0 ; R1+R0 并改变CPSR的标志位
CMN R1,#0x200 ; 将R1值和立即数0X200相加 并根据结果改变CPSR标志位
TST R1,#0XF ; 检测R1的低4位是否为0
TEQ R1,R2 ; 将R1的值 和R2的值 进行异或运算 然后改变CPSR的标志位
;程序状态寄存器处理指令
MRS R0,CPSR ;将CPSR->R0
ORR R0,R0,#C0 ;R0=R0|C0 ,即屏蔽外部中断 和快速外部中断
MSR CPSR,R0 ;R0->CPSR
;多寄存器寻址
;从左赋值到右 用于存储器读取数据 比单字读取操作方便
;IA:每次传送后地址加4
;IB:每次传送前地址加4
;DA:每次传送后地址减4
;DB:每次传送前地址减4
;FD:满递减堆栈
;ED:空递减堆栈
;FA:满递增堆栈
;EA:空递增堆栈
LDMIA R0!,{ R1-R3,R5} ; [R0] ->R1 假设R0=0XF1 将内存地址0XF1中的数据赋值到 R1
; [R0+4] ->R2 R0=0XF1+4 将内存地址0XF1+4 中的数据赋值到R2
; [R0+8] ->R3
; [R0+12] ->R5
STMIA R1!,{R3-R9} ;将R3~R9 数据存储到R1 R1更新值
;R3->[R1]
;R4->[R1+4]
;R5->[R1+8]
;R6->[R1+12]
SWP R1,R1,[R0] ;将R1的内容和R0指向的存储单元内容进行交换
;异常产生指令
SWI 0x02 ;软中断 调用操作系统编号为0X02的系统例程
BKPT 0XFF32 ;
;堆栈寻址 栈会向上增长 递增堆栈,也会向下增长 递减堆栈
;后缀 IB 先增加堆栈地址值 SP+4,然后再出栈 入栈 SP->XX
;后缀 IA 先完成操作在增加地址 SP->XX SP+4
;后缀 DB 先减少堆栈地址值 SP-4,然后再出栈 入栈 SP->XX
;后缀 DA 先完成操作在减少地址值 SP->XX SP-4
STMFD SP!,{R1-R3,LR} ; 将寄存器R1~R3 LR 入栈,满递减堆栈 R1->SP SP++ R2->SP SP++....
LDMFD SP!,{R1-R3,LR} ; 将栈中数据 出栈 存入R1~R3 LR,SP->R1 SP--, SP->R2 SP--
;跳转指令
LDR PC,[PC,#+0X00FF] ; [PC+8+0X00FF] ->PC 修改程序指针 PC值 实现跳转
B task1 ;无条件 跳转到task1处执行
B 0x1234 ;跳转到绝对地址 0X1234处
BL task1 ;先将当前执行指令的下一条指令的地址值 存储到链接寄存器R14(LR)中(以便再返回来) 在跳转到task1标号执行
BLX task1 ;先将当前执行指令的下一条指令的地址值 存储到链接寄存器R14(LR)中(以便再返回来) 并从ARM状态切换到Thumb状态 在跳转到task1标号执行
BLX R0 ;先将当前执行指令的下一条指令的地址值 存储到链接寄存器R14(LR)中(以便再返回来) 并从ARM状态切换到Thumb状态 在跳转到R0中的地址处执行
BX R0 ; 跳转到R0处执行 如果R0[0]=1 则切换到Thumb状态
;ARM 常见伪指令
DCB ;分配一段字节的内存单元 并用指定的数据初始化
DCD DCDU ;分配一段字的内存单元 ,并用指定的数据初始化
DCQ DCQU ;分配一段双字的内存单元 并用64位整型数据初始化
DCW DCWU ;分配一段半字的内存单元 并用指定的数据初始化
ALIGN ; 边界对齐
AREA ; data段 rom段定义
END ; 汇编结束
ENTRY ; 程序入口
EQU ;常量定义 类似C宏定义
EXPORT , GLORBAL ;声明一个符号可以被 其他文件引用
IMPORT EXYERN ;声明一个外部符号
NOP ; 延时空操作
;---------ARM asm Example -------
AREA BUF,DATA,READWRITE ;声明一个数据段 BUF in RAM , BUF 可读可写
count DCB 30 ; 定义一个字节单元count
AREA EXAMPLE1 ,CODE,READONLY ; 声明代码段 EXAMPLE1 in ROM , 只读
ENTRY ; 程序入口
CODE32 ;声明32位ARM指令
START
LDRB R0,count ;R0=count
MOV R1,#10 ;R1=0X10
ADD R0,R0,R1 ;R0=R0+R1
B START ;跳转到START处执行
END ;程序结束
;----------------STM32启动文件.s 代码分析---------------
;Reset_Handler 类似于子函数的函数名
Reset_Handler PROC ;PROC 定义的子程序的开始 类似C语言函数的{ }的开头{
EXPORT Reset_Handler [WEAK] ; WEAK 意思若定义 就是或者函数定义的作用很弱 就小领导的说话没啥用 这个也是在这里定义了权威作用不太大,在其他地方还可以再定义这个子函数,其他地方如果在定义了这个子函数,那这里的定义就无效了
;EXPORT 类似于C语言的extern关键字 声明外部可调用的全局属性
IMPORT __main ; __main是外部的文件 IMPORT在这里 就是引入外部变量 类似于extern pwm; 这个PWM是其他.c文件定义的全局变量 然后在本文件中引用
ENDP ;子函数结束的标志 类似函数{}的末尾}
源代码文件的链接
链接:https://pan.baidu.com/s/12kvtT8djz1hL0X3KFBbK-A?pwd=y4gp
提取码:y4gp
————————————————
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/m0_57249200/article/details/129478705
|
|