【愚公系列】2022年06月 ARM汇编 寄存器介绍
学习数据类型和寄存器的知识。
可以供我们载入(load)或者存储(store)的数据类型可以分为有符号和无符号类型的字,半字,或字节。对这些数据类型的扩展是:半字为-h,-sh,字节为-b或者-sb,字没有扩展。
涉及到的指令集包括
ldr = Load Word 载入字
ldrh = Load unsigned Half Word 载入无符号半字
ldrsh = Load signed Half Word 载入有符号半字
ldrb = Load unsigned Byte 载入无符号字节
ldrsb = Load signed Bytes 载入有符号字节
str = Store Word 储存字
strh = Store unsigned Half Word 储存无符号半字
strsh = Store signed Half Word 储存有符号半字
strb = Store unsigned Byte 储存无符号字节
strsb = Store signed Byte 储存有符号字节
寄存器的数量取决于ARM的版本。根据ARM参考手册可知,有30个32位的通用寄存器(除了ARMv6-M和ARMv7-M的处理器)。在本基础系列课程中,我们学习的对象是在任意特权模式下都可以访问的寄存器:R0-R15。这16个寄存器可以被分成两组:通用寄存器和特殊功能寄存器。
R0-r11都是通用寄存器
特殊功能寄存器如下,其中,R12是IP寄存器,内部程序调用寄存器。R13,SP,堆栈指针寄存器。R14,LR,连接寄存器。R15,PC,程序计数器。CPSR,当前程序状态寄存器
R0-R12可以在通常的运算过程中用来存储临时的数据,指针(定位内存)等。以R0为例,当我们执行算数运算或者存储当前函数的返回值时,可以把R0视为累加器。系统调用发生时,R11开始生效,它存储了系统调用数值。R11作为栈指针帮助我们追踪栈的边界(稍后会讲到)。此外,ARM专用的函数调用规则规定了函数的前四个参数应该分别存贮与R0到R3中。
我们写一个名为test1.s的汇编文件,内容如下
然后编译得到test1的二进制文件
接着使用gdb载入调试,在_start设置断点
运行该程序,输入run即可
可以看到,PC此时为0x10054
这里有一个重点:
现在我们输入nexti来执行下一条指令,下一条指令是mov r0,pc;即把pc赋给r0,那么也就是说r0的值应该为0x10054,真的是这样吗?
可以看到现在r0为0x1005c,而不是0x10054,而0x10054+8=0x1005c,也就是说它不是保持之前读取的pc值,而是储存了相对之前读取的0x10054之后的两条指令的地址。从这儿我们可看成,当我们直接读取PC时,它按照定义,PC指向下一条指令,但是当我们调试程序时,PC却指向当前PC值的下面两条指令的地址处(0x10054+8=0x1005C)。这是因为,老款的ARM处理器总是获取当前已经执行的指令的后两条指令的地址。ARM保留着这个定义的原因是为了保证和早期处理器的兼容性。
- 点赞
- 收藏
- 关注作者
评论(0)