0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

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

jf_78858299 来源: zhangfann 作者: 张凡 2023-01-30 15:06 次阅读

数据类型

这是 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,则发生溢出。

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • ARM
    ARM
    +关注

    关注

    134

    文章

    9091

    浏览量

    367474
  • 寄存器
    +关注

    关注

    31

    文章

    5342

    浏览量

    120297
  • 汇编
    +关注

    关注

    2

    文章

    214

    浏览量

    25930
收藏 人收藏

    评论

    相关推荐

    芯片解密基础知识:串行端口的控制寄存器

    芯片解密基础知识:串行端口的控制寄存器 串行端口控制寄存器有哪些类型?各自的工作方式是什么?下面由IC解密工程师详解各类型的串行端口控制
    发表于 03-30 11:27

    MSP-ESP430G2常用数据类型及字节数值范围基础知识补充

    疯狂的大柚柚带你玩转MSP-ESP430G2(基础篇)(六)基础知识补充常用数据类型数据类型字节数值范围Char1-128~127Unsigned char10`255short2-32768
    发表于 02-15 07:25

    数据寄存器,数据寄存器是什么意思

    数据寄存器,数据寄存器是什么意思 数据寄存器数据
    发表于 03-08 14:38 1.3w次阅读

    汇编语言教程-段寄存器的说明语句

    汇编语言教程-段寄存器的说明语句   在汇编语言源程序中可以定义多个段,每个段都要与一个段寄存器建立一种对应关系。建立这
    发表于 03-27 17:17 1403次阅读

    汇编语言学习课件_微处理基础知识

    汇编语言学习课件 第二章 微处理基础知识 2.1 Intel公司80x86系列微处理简介 2.2 程序可见寄存器组 2.3 存储
    发表于 12-31 10:39 0次下载

    python教程之变量和简单数据类型

    本文档的主要内容详细介绍的是python教程之变量和简单数据类型
    发表于 04-26 08:00 7次下载
    python教<b class='flag-5'>程之</b>变量和简单<b class='flag-5'>数据类型</b>

    Windows编程之数据类型综述

    Windows编程之数据类型综述
    发表于 08-24 15:03 5次下载

    [从零学习汇编语言] -寄存器详解

    语言基础知识梳理一、 存储与通用寄存器1. 存储每一天清晨,当我们在梦中醒来的时候,记忆就会填充大脑的空白,我们会想起最近做过的一些重要的事情,当然也有些小的事情无法准确的记忆起,
    发表于 11-26 20:51 8次下载
    [从零学习<b class='flag-5'>汇编</b>语言] -<b class='flag-5'>寄存器</b>详解

    第二章(1) 初识P0,P1并口 数据类型,常量定义方法,特殊功能寄存器定义

    1.认识P0与P1,数据类型,常量定义方法,特殊功能寄存器定义2.P0和P1区别及介绍
    发表于 12-31 19:57 6次下载
    第二章(1) 初识P0,P1并口  <b class='flag-5'>数据类型</b>,常量定义方法,特殊功能<b class='flag-5'>寄存器</b>定义

    Verilog HDL语言的数据类型和运算符

    reg是寄存器数据类型的关键字,是数据存储单元的抽象,通过赋值语句可以改变寄存器存储的值。reg型数据常用来表示always模块内的指定信号
    的头像 发表于 05-18 10:34 2476次阅读

    四种类型的 JTAG 数据寄存器介绍

    本文将介绍四种类型的 JTAG 数据寄存器,分别是: Boundary Scan Register (BSR) 边界扫描寄存器 Bypass Register (BR) 旁路
    发表于 02-07 10:01 3632次阅读

    解析一些常见的寄存器

    数据寄存器(Data Register,DR)又称数据缓冲寄存器数据寄存器用于存放操作数,其位
    的头像 发表于 02-09 14:47 5505次阅读
    解析一些常见的<b class='flag-5'>寄存器</b>

    Go汇编基础知识

    不同体系结构的 CPU,其内部寄存器的数量、种类以及名称可能大不相同,这里我们只介绍 AMD64 的寄存器。AMD64 有 20 多个可以直接在汇编代码中使用的寄存器,其中有几个
    的头像 发表于 04-20 11:12 1091次阅读

    Verilog最常用的2种数据类型

    Verilog 最常用的 2 种数据类型就是线网(wire)与寄存器(reg),其余类型可以理解为这两种数据类型的扩展或辅助。
    的头像 发表于 05-29 16:27 2321次阅读
    Verilog最常用的2种<b class='flag-5'>数据类型</b>

    寄存器分为基本寄存器和什么两种

    寄存器是计算机中用于存储数据的高速存储单元,它们是CPU内部的重要组成部分。寄存器可以分为基本寄存器和扩展寄存器两种
    的头像 发表于 07-12 10:31 1344次阅读