3

I know that

ldrb r1, [r0]

will read a single byte from the address pointed by r0. However, I still don't know how to read r0 + 1 byte, then r0 + 2, r0 + 3 and so on. will

ldrb r1, [r0, #1]

do what I want? And is that the same as this?

add r0, r0, #1

ldrb r1, [r0]

My aim was to implement the rev instruction as a function, and what I was doing was

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]

However, only r7 read a byte from the number, all other registers read 0. What am I doing wrong?

drakenation
  • 195
  • 2
  • 13

2 Answers2

4
ldrb r1,[r0,#1]

means take the value in r0 add 1 to it and load from there put the byte (zero padded) into r1.

ldrb r1,[r0],#1

means take the value in r0, use it as an address to read a byte from, put the byte in r1 and then add 1 to r0.

ldrb r1,[r0],#1 

is the same as

ldrb r1,[r0]
add r0,r0,#1

just in one instruction instead of two

I assume you want to have a loop that uses

ldrb r1,[r0],#1 

the only drawback is your pointer moves it is like doing *p++ instead rather than array[x++]

Another solution that does not destroy the base is

ldrb r1,[r0,r2]
add r2,r2,#1

take the values in r0 and r2, add them together, use that as an address and read a byte and store it in r1

probably better to just

mov r2,r0
loop:
   ldrb r1,[r0],#1
... 
(end of loop)
mov r0,r2

if you care about preserving the start of string address in a register.

Not this is all documented in the pseudo code that is associated with every instruction and addressing mode in the arm documentation. infocenter.arm.com

old_timer
  • 69,149
  • 8
  • 89
  • 168
2

I understand this maybe for educational purposes. However, this is generally bad as memory bandwidth is much slower than a CPU. It is better to read the whole 32bits and then use rotates and eor to byte swap (or use rev if you have it). Here is a link on memory addressing. Your error is you need strb, not str.

This would be a correct implementation of what you are trying to do.

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 has an excellent answer by dwelch on how to do the eor version. It is much better.

Community
  • 1
  • 1
artless noise
  • 21,212
  • 6
  • 68
  • 105
  • Prototyping with a compiler is always good. Use `objdump` to see what the compiler has done. Your byte version does have the benefit of handling unaligned values, but usually you convert to operate on the data in the natural endian of the CPU and wouldn't want un-aligned data. – artless noise May 14 '14 at 21:40