cancel
Showing results for 
Search instead for 
Did you mean: 

Question regarding ARM assembler's LDR instruction and address rounding

oys_mo
Associate II
Posted on December 13, 2010 at 05:12

Question regarding ARM assembler's LDR instruction and address rounding

13 REPLIES 13
oys_mo
Associate II
Posted on May 17, 2011 at 14:18

Also - a separate, but related question - the same page says that in the case of LDR

''The loaded data is rotated right by one, two or three bytes according to bits [1:0] of the address.''

What's up with that?

EDIT: Okay, look at this:

Say we got the same exact program as above, except there is a

.byte 0x77

in the .data segment, just before the .word - giving us the following in memory (accounting for endianness):

77 BE BA FE CA

Assume that the 77-byte is word aligned. Now, the address of var1 surely will be the same as before + 1. If we follow what the page I linked to said, we would now round this address down so that we read the 4 bytes

77 BE BA FE

Note that I am talking about the first LDR here, I have not mixed in offsets yet.

Now the page says that we ought to rotate this right, a set amount of bytes according to the two least significant bits. Since the address we requested (the BE byte) is word aligned + 1, we know that its two least significant bits must be 10 (little endian). So we are going to rotate our data 1 byte to the right. Doing this, accounting for endianness, I get

BE BA FE 77

And as the page said,

''For a little-endian memory system, this causes the addressed byte to occupy the least significant byte of the register.''

But that is not what my debugger tells me. I get a nice 0xFEBABE77 in my register. So it seems like there has been no rotation... I am thoroughly confused.
Posted on May 17, 2011 at 14:18

Unaligned memory accesses will typically cause the processor to fault in most ARM implementations.

So you shouldn't do 32-bit or 16-bit access from ODD addresses. And 32-bit access should have (A0=A1=0)

Tips, buy me a coffee, or three.. PayPal Venmo Up vote any posts that you find helpful, it shows what's working..
oys_mo
Associate II
Posted on May 17, 2011 at 14:18

Hmm according to the docs on keils website unaligned access is available - and on by default - on ARMv7. I use GNU's assembler, though, so there might be differences. Guess I'll just keep my data aligned. 

damh
Associate II
Posted on May 17, 2011 at 14:18

In startup mode the mcus (STM32F103xx) support unaligned memory accesses, BUT they use much more cycles than aligned accesses (about factor 3-6). Accesses to flash can have higher factors because of waitstates!

In normal user mode unaligned access can fault. I think this can be disabled but with the same costs!

oys_mo
Associate II
Posted on May 17, 2011 at 14:18

I was in privileged mode, and it kind of worked, it just gave me slightly unexpected results...

It's not that I'm going to use unaligned memory access, I was just testing it 🙂 Knowledge is power, as they say.

stforum2
Associate II
Posted on May 17, 2011 at 14:18

Cortex-M3 LDR is different to ARM7 LDR.  There is no rotation on Cortex-M3.

For Cortex-M3 alignment behaviour see document ARM DDI 0405B section A3.2.

(Maybe there is a later edition of this document).

oys_mo
Associate II
Posted on May 17, 2011 at 14:18

Are you sure? The document you mentioned didn't say anything about rounding at all, not that I could find at least. Still, it's a useful resource.

stforum2
Associate II
Posted on May 17, 2011 at 14:18

Section A6.7.42 shows the encodings for LDR (immediate).

What code bytes is your assembler generating?

stforum2
Associate II
Posted on May 17, 2011 at 14:18

You need to include ldr r1,[r0,#3] in your assembly code.

After all, that is the instruction that was not doing what you expected.

01 68 is ldr r1,[r0]