tiny6410裸机实验第1章--------------ARM汇编和编程基础(ARM汇编简介)
2014-02-21 13:00
375 查看
【说明】
其实常用的ARM汇编指令并不多,而且在实际编程的时候,大部分是用C语言,只有最开头的一小段是用汇编语言,哪怕裸机也大部分用C写。。下面介绍几个简单的汇编指令,其实对于一般开发也就够了。本文参考《嵌入式linux开发完全手册》
【相对跳转 b, bl】
如果没有任何汇编经验,没关系,后面用到后就懂了,很好理解的。
这两个都是跳转指令,但是有点不一样的就是bl除了跳转到指定地址外,还会将返回地址保存到lr寄存器中,这两条指令都可跳转范围是当前指令的前后32MB。
例如 下面就是一种用法,当执行到 b fun1 时,下一条指令就不会是xxxxx而是 标号fun1下边的aaaaa,同理,bl fun2 后会执行fun2 下边的第一条指令
.......
b fun1
xxxxx
fun1:
aaaaa
........
bl fun2
fun2:
........
........
【数据传送指令mov,地址读取伪指令ldr】
mov 可以将一个寄存器的内容赋值给另外一个,或者将一个立即数赋值给一个寄存器,比如
mov r1, r2
//就是将寄存器r2的值赋值给r1,,,注意赋值的方向
mov r1, #4096 //就是直接指定r1 里边的值为 4096
其实不是任何常数都能表示成立即数的,其实不需要记什么数可以表示而什么数不能,因为我们有ldr指令,这个指令不是真正的指令,而是称为伪指令,编译器会把他扩展成真正的指令。。使用他以后,如果常数可以表示成立即数,那么就用mov
,如果不能,就会把常熟保存在一个位置,用内存读取指令来读到寄存器中而不用mov。。用法如下
ldr r1, =4096
//在不知道4096是不是立即数的时候用这个
【内存访问指令 ldr, str】
我们经常需要从内存里面取数据,或者往内存里边写数据,那我们需要用到ldr, str 命令,,一看就知道 ldr是读, str是写。。
ldr r1, [r2, #4] //将地址为r2 + 4的内存地址单元的数据读取到r1中
ldr r1, [r2] //将地址为r2的内存单元数据读取到r1中
ldr r1, [r2], #4 //将地址为r2的内存单元数据读取到r1中,然后 r2 = r2 + 4
上面几条ldr 改成 str 就是写入相应的写操作
【批量内存访问 ldm, stm】
每次一个一个的写和读对于操作大量数据太麻烦了,当然你可以用循环来实现,但是ARM提供了处理批量访问内存的指令
例如:
stmdb sp!, {r0-r12,lr} //保存使用到的寄存器,r0-r12,lr会被保存在sp表示的内存中,“!”使得指令执行后 sp = sp-14*4
ldmia sp!, {r0-r12, pc}^ // "^"表示将 spsr 的值复制到cpsr中,这个后面遇到的时候会解释,“!”表示指令执行后,sp = sp+14*4
【运算指令: add, sub】
add r1, r2, #1 //表示 r1 = r2 + 1
sub r1, r2, #1 // r1 = r2 - 1
【程序状态寄存器的访问指令 : msr, mrs】
ARM有7种工作模式,后面关于中断处理的文章会详细介绍,用来控制各种模式的是一个程序状态寄存器cpsr,我们想操作里边的值需要如下2个指令
msr cpsr, r0 // cpsr = r0
mrs r0, cpsr
//r0 = cpsr
【其他伪指令】
.extern 定义一个外部符号,用来引用别的文件中的变量或者函数
.text 表示下边是代码段
.global 将本文件中某个程序标号定义为全局,用来让别的文件使用某个标号
【执行条件】
其实大多数ARM指令都是可以条件执行的,比如moveq, movgt 后面的eq gt就是条件,只有满足条件的时候才会执行这条语句指令的条件码如下
比如我想实现类似C语言
if (a == b) { aaaaaaaa}
else { bbbbbbb}
cccccccccccc
用汇编就可以是如下框架
cmp a, b //这个会改变 cpsr
beq fun_yes // a==b
b fun_else // a!=b
fun_yes:
aaaaaaaa
b fun_out
fun_else:
bbbbbbbb
fun_out:
cccccccccccc
【ARM寄存器使用规则】
其实常用的ARM汇编指令并不多,而且在实际编程的时候,大部分是用C语言,只有最开头的一小段是用汇编语言,哪怕裸机也大部分用C写。。下面介绍几个简单的汇编指令,其实对于一般开发也就够了。本文参考《嵌入式linux开发完全手册》
【相对跳转 b, bl】
如果没有任何汇编经验,没关系,后面用到后就懂了,很好理解的。
这两个都是跳转指令,但是有点不一样的就是bl除了跳转到指定地址外,还会将返回地址保存到lr寄存器中,这两条指令都可跳转范围是当前指令的前后32MB。
例如 下面就是一种用法,当执行到 b fun1 时,下一条指令就不会是xxxxx而是 标号fun1下边的aaaaa,同理,bl fun2 后会执行fun2 下边的第一条指令
.......
b fun1
xxxxx
fun1:
aaaaa
........
bl fun2
fun2:
........
........
【数据传送指令mov,地址读取伪指令ldr】
mov 可以将一个寄存器的内容赋值给另外一个,或者将一个立即数赋值给一个寄存器,比如
mov r1, r2
//就是将寄存器r2的值赋值给r1,,,注意赋值的方向
mov r1, #4096 //就是直接指定r1 里边的值为 4096
其实不是任何常数都能表示成立即数的,其实不需要记什么数可以表示而什么数不能,因为我们有ldr指令,这个指令不是真正的指令,而是称为伪指令,编译器会把他扩展成真正的指令。。使用他以后,如果常数可以表示成立即数,那么就用mov
,如果不能,就会把常熟保存在一个位置,用内存读取指令来读到寄存器中而不用mov。。用法如下
ldr r1, =4096
//在不知道4096是不是立即数的时候用这个
【内存访问指令 ldr, str】
我们经常需要从内存里面取数据,或者往内存里边写数据,那我们需要用到ldr, str 命令,,一看就知道 ldr是读, str是写。。
ldr r1, [r2, #4] //将地址为r2 + 4的内存地址单元的数据读取到r1中
ldr r1, [r2] //将地址为r2的内存单元数据读取到r1中
ldr r1, [r2], #4 //将地址为r2的内存单元数据读取到r1中,然后 r2 = r2 + 4
上面几条ldr 改成 str 就是写入相应的写操作
【批量内存访问 ldm, stm】
每次一个一个的写和读对于操作大量数据太麻烦了,当然你可以用循环来实现,但是ARM提供了处理批量访问内存的指令
例如:
stmdb sp!, {r0-r12,lr} //保存使用到的寄存器,r0-r12,lr会被保存在sp表示的内存中,“!”使得指令执行后 sp = sp-14*4
ldmia sp!, {r0-r12, pc}^ // "^"表示将 spsr 的值复制到cpsr中,这个后面遇到的时候会解释,“!”表示指令执行后,sp = sp+14*4
【运算指令: add, sub】
add r1, r2, #1 //表示 r1 = r2 + 1
sub r1, r2, #1 // r1 = r2 - 1
【程序状态寄存器的访问指令 : msr, mrs】
ARM有7种工作模式,后面关于中断处理的文章会详细介绍,用来控制各种模式的是一个程序状态寄存器cpsr,我们想操作里边的值需要如下2个指令
msr cpsr, r0 // cpsr = r0
mrs r0, cpsr
//r0 = cpsr
【其他伪指令】
.extern 定义一个外部符号,用来引用别的文件中的变量或者函数
.text 表示下边是代码段
.global 将本文件中某个程序标号定义为全局,用来让别的文件使用某个标号
【执行条件】
其实大多数ARM指令都是可以条件执行的,比如moveq, movgt 后面的eq gt就是条件,只有满足条件的时候才会执行这条语句指令的条件码如下
比如我想实现类似C语言
if (a == b) { aaaaaaaa}
else { bbbbbbb}
cccccccccccc
用汇编就可以是如下框架
cmp a, b //这个会改变 cpsr
beq fun_yes // a==b
b fun_else // a!=b
fun_yes:
aaaaaaaa
b fun_out
fun_else:
bbbbbbbb
fun_out:
cccccccccccc
【ARM寄存器使用规则】
相关文章推荐
- Linux 与 Windows 对UNICODE 的处理方式
- Ubuntu12.04下QQ完美走起啊!走起啊!有木有啊!
- 解決Linux下Android开发真机调试设备不被识别问题
- 运维入门
- 运维提升
- Linux 自检和 SystemTap
- Ubuntu Linux使用体验
- c语言实现hashmap(转载)
- Linux 信号signal处理机制
- linux下mysql添加用户
- Scientific Linux 5.5 图形安装教程
- 基于 Linux 集群环境上 GPFS 的问题诊断
- 谁是桌面王者?Win PK Linux三大镇山之宝
- vivi下重新调整分区
- Linux VS Unix:Linux欲一统天下 Unix不死
- linux下设定环境变量
- Linux下修改MySQL编码的方法
- Linux串口通信
- 从Windows系统下访问Linux分区相关软件