汇编基础知识教程之数据类型与寄存器

数据类型这是 arm 汇编基础知识系列教程的第二部分,涉及数据类型和寄存器。
与高级语言类似,arm支持对不同数据类型的操作。我们可以加载(或存储)的数据类型可以是有符号和无符号字、半字或字节。这些数据类型的扩展是。-h或-sh用于半字,-b或-sb用于字节,而字则没有扩展。有符号和无符号数据类型之间的区别是。
有符号的数据类型可以容纳正值和负值,因此范围较小。
无符号数据类型可以保存大的正值(包括 零),但不能保存负值,因此范围更广。
下面是一些例子,说明这些数据类型如何与指令load和store一起使用。
大小端在内存中,有两种查看字节的基本方法。小端(le)或大端(be)。区别在于一个对象的每个字节在内存中的存储顺序。在像英特尔x86这样的小端机器上,最不重要的字节被存储在最低地址(最接近零的地址)。在big-endian机器上,最重要的字节被存储在最低地址。arm架构在第3版之前是小-endian,从那时起,它是双-endian,这意味着它有一个允许可切换endianness的设置。例如,在armv6中,指令是固定的小字节,数据访问可以是小字节或大字节,由程序状态寄存器(cpsr)的第9位(e位)控制。
arm寄存器寄存器的数量取决于arm的版本。根据arm参考手册,除了基于armv6-m和armv7-m的处理器外,有30个通用的32位寄存器。前16个寄存器可在用户级模式下访问,其他寄存器可在特权软件执行中使用(armv6-m和armv7-m例外)。在本系列教程中,我们将处理在任何特权模式下都可以访问的寄存器:r0-15。这16个寄存器可以分成两组:通用寄存器和特殊用途寄存器。
下表展示了arm寄存器与intel处理器中的寄存器之间的关系。
r0-r12:在普通操作中可用于存储临时值、指针(存储器的位置)等。例如,r0在进行算术运算时可作为累加器,或用于存储先前调用的函数的结果。r7在处理系统调用时变得非常有用,因为它存储了系统调用的编号,r11帮助我们跟踪堆栈上的边界,作为框架指针(将在后面介绍)。此外,arm的函数调用惯例规定,函数的前四个参数存储在寄存器r0-r3中。
r13:sp(堆栈指针)。堆栈指针指向堆栈的顶部。堆栈是一个用于特定函数存储的内存区域,在函数返回时被回收。因此,堆栈指针用于分配堆栈的空间,方法是用堆栈指针减去我们要分配的值(以字节为单位)。换句话说,如果我们想分配一个32位的值,我们从堆栈指针中减去4。
r14:lr(链接寄存器)。当一个函数被调用时,链接寄存器被更新为内存地址,引用函数启动的下一条指令。这样做允许程序在 子 函数完成后返回到启动 子 函数的 父 函数。
r15:pc(程序计数器)。程序计数器根据所执行的指令的大小自动递增。这个大小在arm状态下总是4字节,在thumb模式下是2字节。当一个分支指令被执行时,pc保存目标地址。在执行过程中,pc在arm状态下存储当前指令的地址加8(两条arm指令),在thumb(v1)状态下存储当前指令加4(两条thumb指令)。这与x86不同,x86的pc总是指向要执行的下一条指令。
让我们看看pc在调试器中是如何表现的。我们用下面的程序将pc的地址存入r0,并包括两条随机指令。让我们看看会发生什么。
在gdb中我们在_start处设定一个断点
如下是运行的结果:
我们可以看到,pc持有将被执行的下一条指令(mov r0, pc)的地址(0x8054)。现在让我们执行下一条指令,之后r0应该持有pc的地址(0x8054),对吗?
...对吗?错了。看看r0中的地址。当我们期望r0包含先前读取的pc值(0x8054)时,它却包含了比我们先前读取的pc值(0x805c)提前两条指令的值。从这个例子中你可以看到,当我们直接读取pc时,它遵循pc指向下一条指令的定义;但在调试时,pc指向当前pc值前面的两条指令(0x8054 + 8 = 0x805c)。这是因为较早的arm处理器总是在当前执行的指令之前获取两条指令。arm保留这一定义的原因是为了确保与早期处理器的兼容性。
当前程序状态寄存器当你用gdb调试一个arm二进制文件时,你会看到一个叫做flags的东西。
寄存器$cpsr显示了当前程序状态寄存器(cpsr)的值,在它下面可以看到flagsthumb, fast, interrupt, overflow, carry, zero, and negative。这些标志代表了cpsr寄存器中的某些位,并根据cpsr的值来设置,激活时变成粗体。n、z、c和v位与x86上eflag寄存器中的sf、zf、cf和of位相同。这些位被用来支持汇编级的条件和循环的条件执行。我们将在第6部分 条件执行和分支 中介绍使用的条件代码。
上图显示了一个32位寄存器(cpsr)的布局,左边()是最小的位。每一个单元(除了ge和m部分以及空白部分)都是一个比特的大小。这些一比特的部分定义了程序当前状态的各种属性。
让我们假设我们使用cmp指令来比较数字1和2。结果是 负,因为1-2=-1。当我们比较两个相等的数字时,比如2对2,z(零)标志被设置,因为2-2=0。请记住,cmp指令使用的寄存器不会被修改,只有cpsr会根据这些寄存器相互比较的结果被修改。
这是gdb中的情况(安装了gef)。在这个例子中,我们比较寄存器r1和r0,其中r1=4,r0=2。这是执行了cmp r1, r0操作后的标志的情况。
进位标志被设置,因为我们用cmp r1, r0来比较4和2(4-2)。相反,如果我们使用cmp r0, r1来比较一个较小的数字(2)和一个较大的数字(4),则负标志(n)被设置。
下面是arm信息中心的一段摘录:
apsr包含以下alu状态标志。
n - 当操作的结果为负数时设置。
z - 当操作的结果为零时设置。
c - 当操作的结果是carry时设置。
v--当操作引起溢出时设置。
carry在以下情况被设置:
如果加法的结果大于或等于2^32
如果减法的结果是正数或零
作为移动或逻辑指令中的内联移位操作的结果。
如果加法、减法或比较的结果大于或等于2^31,或小于2^31,则发生溢出。

人脸识别考勤门禁系统的应用
PLC的RS-485接口简介
世界芯片公司排名
德州仪器77GHz AWRL1432雷达传感器解决脚部姿势检测挑战
在人工智能大势推动下,芯片市场占到全球10%以上
汇编基础知识教程之数据类型与寄存器
未来五年国内传感器市场如何
微信、支付宝议和 今年的红包大战不会再见到!
幻夜派对夜景美照吸睛,华为畅享10首销日人气爆棚
三星首次展示旗下的AR计划 推出AR云服务以及一款AR头盔
无人机轻易的登入“伊丽莎白女王”号航母甲板上
OPPO、华为争抢年轻群体 谁才是老大
持续推进“三化”战略,国星光电业绩又向前迈进一步
三星Galaxy TabPro S二合一平板体验,媲美Surface Pro 4
详解纯电动汽车的CAN总线系统
MOSFET安全工作区和热插拔电路
中国移动花钱买世界杯版权只能是:竹篮打水一场空
先进封装市场第三季度将迎来23.8%强增长
荣耀9降临!华为Mate9、华为P10、荣耀V9四大旗舰!更钟爱哪一款?
至2025年,全球人工智能医疗市场的年复合增长率达到41.7%