我知道
ldrb r1,[r0]
将从r0指向的地址读取单个字节。但是,我仍然不知道如何读取r0 + 1字节,然后是r0 + 2,r0 + 3等等。将
ldrb r1,[r0,#1]
做我想要的?这是一样的吗?
添加r0,r0,#1
ldrb r1,[r0]
我的目标是将rev指令作为一个函数来实现,我正在做的是
lrdb r4,[r0]
lrdb r5,[r0,#1]
lrdb r6,[r0,#2]
lrdb r7,[r0,#3]
str r7,[r0]
str r6,[r0,#1]
str r5,[r0,#2]
str r4,[r0,#3]
但是,只有r7从数字中读取一个字节,所有其他寄存器读取0.我做错了什么?
答案 0 :(得分:2)
ldrb r1,[r0,#1]
表示将r0中的值加1,并从那里加载将字节(零填充)放入r1。
ldrb r1,[r0],#1
表示取r0中的值,将其用作读取字节的地址,将字节放入r1,然后将1加到r0。
ldrb r1,[r0],#1
与
相同ldrb r1,[r0]
add r0,r0,#1
只需一条指令而不是两条
我假设你想要一个使用
的循环ldrb r1,[r0],#1
唯一的缺点是你的指针移动就像做* p ++而不是数组[x ++]
另一种不破坏基础的解决方案是
ldrb r1,[r0,r2]
add r2,r2,#1
取r0和r2中的值,将它们加在一起,将其用作地址并读取一个字节并将其存储在r1中
可能更好
mov r2,r0
loop:
ldrb r1,[r0],#1
...
(end of loop)
mov r0,r2
如果您关心在寄存器中保留字符串地址的开头。
并非所有这些都记录在与arm文档中的每个指令和寻址模式相关联的伪代码中。 infocenter.arm.com
答案 1 :(得分:2)
我理解这可能是出于教育目的。但是,这通常很糟糕,因为内存带宽比CPU慢得多。最好读取整个32位,然后使用rotate和eor
进行字节交换(如果有的话,使用rev
)。这是memory addressing上的链接。您的错误是strb
,而不是str
。
这将是您正在尝试做的正确实现。
lrdb r4, [r0]
lrdb r5, [r0, #3]
strb r4, [r0, #3]
strb r5, [r0]
lrdb r4, [r0, #1]
lrdb r5, [r0, #2]
strb r4, [r0, #2]
strb r5, [r0, #1]
This question有 dwelch 关于如何执行eor
版本的优秀答案。它好多了。