assembly ARM的加载和存储字节和半字指令是如何工作的?有符号和无符号指令的作用是什么?

noj0wjuj  于 2022-11-13  发布在  其他
关注(0)|答案(3)|浏览(275)

我刚刚开始学习ARM,我很难理解加载和存储指令到底是做什么的。
加载说明:

ldrsb
ldrb
ldrsh
ldrh
ldr

商店说明:

strb
strh
str

有符号或无符号“加载半字”是什么意思?有符号或无符号“加载字节”是什么意思?有符号和无符号之间有什么区别?有些加载/存储指令在哪些特定的应用程序中实用?
总而言之,我在寻找对这些指令的直观理解,因为我仍然对它们是如何工作的以及它们的目的是什么感到困惑。

xesrikrc

xesrikrc1#

当谈到ARM时,一个“字”是32位,一个“半字”是16位,一个“字节”是8位。如果您阅读ARM架构参考手册中的指令集文档(如果您不知道要获取哪一个,请获取ARMv5的文档,infocenter.arm.com),您将看到ldrb将字节加载到目标寄存器的低8位,填充高24位到零。ldrsb将符号扩展而不是用零填充。半字也是如此。
如果您有这样代码:

char a,b,c;
...
c = a+b;
if(c<0)
{
}

在你需要做加法的时候,a或B或者两者都在内存中,那么你最好做一个符号扩展(假设你已经告诉你的编译器char是有符号的)加载,以保存对寄存器进行符号扩展的指令,这样你就可以执行数学运算,并为比较设置正确的标志。
来自ARM的ARM。
LDRSB(加载寄存器带符号字节)从内存加载一个字节,对其进行符号扩展以形成一个32位字,并将结果写入通用寄存器。
LDRB(加载寄存器字节)从内存加载一个字节,对其进行零扩展以形成一个32位字,并将结果写入通用寄存器。

7xzttuei

7xzttuei2#

ARM是一种RISC(精简指令集计算)架构,这意味着必须使用您所引用的指令(加载和存储指令)将内存移入和移出寄存器。
加载指令从内存中取出一个值并将其写入通用寄存器。存储指令从通用寄存器中读取一个值并将其存储到内存中。
Most Often Used Load/Store Instructions

Loads            Stores      Size and Type
LDR              STR         Word (32 bits)
LDRB             STRB        Byte (8 bits)
LDRH             STRH        Halfword (16 bits)
LDRSB                        Signed byte
LDRSH                        Signed halfword
LDM              STM         Multiple words
  • (摘自ARM汇编语言- William Hohl)*

加载和存储指令(通常)采用以下形式:

LDR | STR {type}{cond}    Rt, [Rn {, #offset}]
  • (虽然根据您希望使用的寻址模式类型,会有一些差异,但我不会在此详细说明,如果您想了解更多寻址模式,请查看**“ARM索引后和索引前寻址”**)*

“类型”是可选的,在上表中有描述,您可以选择处理半字、字节以及有符号或无符号字节或半字。您还可以选择加载或存储多个寄存器。
您还可以选择向指令添加条件代码(cond),该指令用于设置 * 当前程序状态寄存器(CPSR)* 中保存的条件标志-如果您想了解更多信息,可以搜索 “ARM条件执行”“条件代码”
在ARM中,您必须提供源/目标寄存器,并且还必须提供包含引用内存中某个位置的地址的寄存器。这是因为ARM指令是固定长度(32位)的,其中一些位需要用于指令本身,因此不可能在32位ARM指令中封装32位内存地址。
在上面的例子中,“Rt”是从内存加载的值所在的寄存器(如果执行存储操作,则为包含要存储到内存的值的寄存器)。“Rn”是包含地址的寄存器。方括号的作用是告诉处理器我们正在处理的寄存器包含地址,我们使用的是一个 * 指针 *。如果你想从基址寄存器偏移一个特定的量,这里有可选的偏移量(这在各种有用的应用程序中都很方便,但我不会在这里讨论)。
我希望这能让您对ARM的加载和存储指令的工作方式有一些了解!:)

gv8xihay

gv8xihay3#

当我们使用宽度小于一个字的load指令时,我们必须扩展比目标寄存器更短的值。因此,ldrhldrb必须与ldrshldrsb区分,告诉CPU如何“填充”寄存器。(零扩展与符号扩展。)
但当我们使用存储指令时,DRAM中的目标存储元素是一个字节或半字,存储值大小必须是字节的倍数,不需要扩展值来填充目标存储元素。没有选择存储什么,只是截断,即存储低8位或16位,这保留了有符号或无符号整数的值(因为ARM是一个2的补码机器)。

相关问题