我上过几门关于ARMv8汇编的课程,但两位老师都以不同的方式描述了LDUR/STUR指令,现在我已经完全迷失了方向。有人能帮我澄清一下吗?
如果我得到指示:
LDUR R3, [R1, #8]
我将把答案放在R3中,但是我从R1中得到了什么,偏移量是如何操作的?这是一种逻辑上的转变吗?ARM手册将其描述为“字节偏移量”,但没有描述该偏移量在R1上是如何工作的。我是将存储在R1中的值移位(假设R1的值为50 ),还是在R1之外有一个我需要考虑的内存地址?其他来源说,我需要以某种方式将R1视为一个数组?
发布于 2018-10-25 00:02:46
LDUR为加载(未缩放)寄存器。它将一个值(32位或64位)从一个地址加一个偏移量加载到一个寄存器。unscaled
意味着在机器代码中,偏移量将不会像ldr
使用的那样使用缩放偏移量进行编码,即不会将移位应用于立即偏移位。偏移量(simm带立即数)将被添加到基址寄存器Xn|SP。
因此,与** ldr
不同, ldur
**,可以使用不是4或8的倍数的位移
以下是LDUR的原型:
-- loads a 32-bit value
LDUR <Wt>, [<Xn|SP>{, #<simm>}]
-- loads a 64-bit value
LDUR <Xt>, [<Xn|SP>{, #<simm>}]
STUR是存储(未缩放)寄存器,工作方式与此相同,但它将寄存器中的值存储到内存中。
以下是STUR的原型:
-- stores a 32-bit register
STUR <Wt>, [<Xn|SP>{, #<simm>}]
-- stores a 64-bit register
STUR <Xt>, [<Xn|SP>{, #<simm>}]
LDUR/STUR允许访问32/64位值,当它们与操作数的大小不是对齐时。例如,存储在地址0x52的32位值。
在您的示例中,
LDUR R3, [R1, #8]
此指令将R1
加上8
字节所指向的值加载到R3
。这就是ARM参考手册中所说的byte offset
。因此,如果R1
包含值0x50
,则将加载存储在地址0x58
中的值。R1
的值不会被修改。
指令LDR R3, [R1, #8]
(LDR (immediate)无符号偏移变量)产生相同的操作,但是,原型是不同的:
-- loads a 32-bit value
LDR <Wt>, [<Xn|SP>{, #<pimm>}]
-- loads a 64-bit value
LDR <Xt>, [<Xn|SP>{, #<pimm>}]
立即偏移量pimm不同,LDUR使用simm。这意味着偏移量被以不同的方式解释。第一个(pimm)是一个正偏移量,它的范围对于32位变体和64位变体是不同的。
在32位版本中:
的倍数
在64位版本中:
的倍数
这意味着LDUR和LDR (立即)的一些偏移量组合将产生相同的操作。
发布于 2020-12-26 00:50:12
来自Arm® A64 Instruction Set Architecture: Armv8, for Armv8-A architecture profile
if HaveMTEExt() then
boolean is_load_store = MemOp_LOAD IN {MemOp_STORE, MemOp_LOAD};
SetNotTagCheckedInstruction(is_load_store && n == 31);
bits(64) address;
bits(datasize) data;
if n == 31 then
CheckSPAlignment();
address = SP[];
else
address = X[n];
address = address + offset;
data = Mem[address, datasize DIV 8, AccType_NORMAL];
X[t] = ZeroExtend(data, regsize);
此伪代码显示了如何应用偏移量操作。
发布于 2021-04-19 09:34:39
在无符号偏移模式下,LDR的imm应保持4字节或8字节对齐。
如果imm %4 == 0,stur Wt,Xn|SP,#imm等于A32中的字符串Wt,Xn|SP,#imm。
如果IMM%8 == 0,stur Xt,Xn|SP,#imm等于A64中字符串Xt,Xn|SP,#imm。
在保持基址寄存器不变的情况下,LDR不能逐字节寻址-256到255。这就是LDUR所做的。
https://stackoverflow.com/questions/52894765
复制相似问题