如何读取ARM中的单个字节序列?

时间:2014-05-14 19:29:13

标签: assembly arm

我知道

  

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.我做错了什么?

2 个答案:

答案 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版本的优秀答案。它好多了。