我刚开始学习ARM技术,但对于负责载荷和存储指令的确切作用感到困惑。
负责载荷的指令:
ldrsb
ldrb
ldrsh
ldrh
ldr
存储指令:
strb
strh
str
“加载半字”有符号或无符号是什么意思?或者“加载字节”有符号或无符号是什么意思?有符号和无符号有什么区别,一些装载/存储指令在哪些特定应用中实用?
总的来说,我希望能直观地理解这些指令的作用,因为我仍然对它们如何工作以及它们的目的感到困惑。
我刚开始学习ARM技术,但对于负责载荷和存储指令的确切作用感到困惑。
负责载荷的指令:
ldrsb
ldrb
ldrsh
ldrh
ldr
存储指令:
strb
strh
str
“加载半字”有符号或无符号是什么意思?或者“加载字节”有符号或无符号是什么意思?有符号和无符号有什么区别,一些装载/存储指令在哪些特定应用中实用?
总的来说,我希望能直观地理解这些指令的作用,因为我仍然对它们如何工作以及它们的目的感到困惑。
当谈论ARM时,“字(word)”是32位,“半字(halfword)”是16位,“字节(byte)”是8位。如果您在ARM架构参考手册中阅读指令集文档(如果不知道要获取哪一个,可以使用 infocenter.arm.com 获取ARMv5),您将看到 ldrb 将字节加载到目标寄存器的低8位,填充上方的24位为零。ldrsb 将进行符号扩展而不是填充零位。半字同理。
如果您有如下代码:
char a,b,c;
...
c = a+b;
if(c<0)
{
}
如果在执行加法时,a、b或两者都在内存中,并且您想要进行符号扩展(假设您已告诉编译器char是有符号的),以保存指令符号扩展寄存器,从而可以执行数学运算并正确设置标志进行比较,则最好使用LDRSB(加载有符号字节寄存器)从内存加载一个字节,将其符号扩展为32位字,并将结果写入通用寄存器。而LDRB(加载字节寄存器)则会从内存加载一个字节将其零扩展为32位字,并将结果写入通用寄存器。Load instructions take a single value from memory and write it to a general purpose register. Store instructions read a value from a general purpose register and store it in to memory.
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的加载和存储指令的工作方式! :)
ldrsb
所做的那样-您必须决定要放入目标字中的上24位是什么。当将宽值转换为窄值时,只有一种明智的选择:移动源字的低位并忽略高位,这就是strb
所做的。 - Nate Eldredge