dpawson
Posts: 115
Joined: Mon Nov 14, 2011 5:05 pm
Contact: Website

Re: ldr (immediate)

Tue Nov 29, 2011 5:33 am

Am I right/wrong please?

for the rpi, ldr <label> has a max offset of 8 bits?

The GNU as is quite happy with a close to 4K offset

e59f8e5c ldr r8, [pc, #3676] ; 8f28 <fourk>

I think this would work on the ARMv7-M, but not on the rpi?

TIA Dave

User avatar
johnbeetem
Posts: 945
Joined: Mon Oct 17, 2011 11:18 pm
Location: The Mountains
Contact: Website

Re: ldr (immediate)

Tue Nov 29, 2011 6:50 am

I think this is right: the 32-bit ARM instruction has a +/- 4K offset. The 16-bit Thumb instruction has an 8-bit offset field, but it's quadrupled to give you a +256 word offset (+1K byte). These have been around since at least ARMv5.

You can get quick-reference charts from arm.com without registering. Or you can register and get the full ARM Architecture Reference Manual (ARM ARM). Look under TMI :-)

User avatar
johnbeetem
Posts: 945
Joined: Mon Oct 17, 2011 11:18 pm
Location: The Mountains
Contact: Website

Re: ldr (immediate)

Tue Nov 29, 2011 7:04 am

Quote from dpawson on November 29, 2011, 05:33
The GNU as is quite happy with a close to 4K offset

e59f8e5c ldr r8, [pc, #3676] ; 8f28 <fourk>

I think this would work on the ARMv7-M, but not on the rpi?


I think this is right as well: E59F.8E5C is a 32-bit ARM LDR instruction. It should work fine on the ARMv6 RasPi. But it won't work on ARMv7-M, since that architecture only supports Thumb and Thumb2 if I am not mistaken. 32-bit Thumb-2 instructions are encoded differently from 32-bit ARM.

dpawson
Posts: 115
Joined: Mon Nov 14, 2011 5:05 pm
Contact: Website

Re: ldr (immediate)

Tue Nov 29, 2011 7:36 am

Quote from johnbeetem on November 29, 2011, 06:50
I think this is right: the 32-bit ARM instruction has a +/- 4K offset. The 16-bit Thumb instruction has an 8-bit offset field, but it's quadrupled to give you a +256 word offset (+1K byte). These have been around since at least ARMv5.

You can get quick-reference charts from arm.com without registering. Or you can register and get the full ARM Architecture Reference Manual (ARM ARM). Look under TMI :-)


It was the 8 to 10 bit that got me, of course it's dealing in words.
And it doesn't say it's signed (clearly)
and the GNU system seems not to let me say I have processor X,
so any ARMv7 instructions slip through happily.

I have the 'arm arm', I thought it worth registering.
I also asked them if they'd do an asm for the rpi, at an appropriate cost.
No reply as yet :-)

Thanks John.

dpawson
Posts: 115
Joined: Mon Nov 14, 2011 5:05 pm
Contact: Website

Re: ldr (immediate)

Tue Nov 29, 2011 8:06 am

Quote from johnbeetem on November 29, 2011, 06:50
I think this is right: the 32-bit ARM instruction has a +/- 4K offset. The 16-bit Thumb instruction has an 8-bit offset field, but it's quadrupled to give you a +256 word offset (+1K byte). These have been around since at least ARMv5.



From arm arm.

<label> The label of the literal data item that is to be loaded into <Rt>. The assembler calculates the required value of the offset from the PC value of this instruction to the label. Permitted values of the offset are:
Encoding T1 multiples of four in the range 0 to 1020
T1 is All thumb.

I take that to be unsigned positive? Mainly since no mention of a signed addition is present.
For T2, it says Encoding T2 any value in the range -4095 to 4095.
I.e. it is clearly signed.

So the range is 0..1024 bytes rel to pc.

I think I've got it.

Dave

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: ldr (immediate)

Tue Nov 29, 2011 8:40 am

Quote from dpawson on November 29, 2011, 07:36
and the GNU system seems not to let me say I have processor X,
so any ARMv7 instructions slip through happily.
Of course it does. I'd say "RTFM", but given that it has the same state of GNU documentation as the rest of the tools, I'll let you off. You'll find the docs in the source tree, IIRC, or here : http://sourceware.org/binutils.....RM-Options

So. Setting a given processor (examples for Raspberry Pi).
-mcpu=arm1176jzf-s
Full list of supported processors and extensions given in the link above.

You could get less specific and give a particular architecture:
-march=armv6
Again, see the doc for a full list.

If you're using floating point at all, you'll also want -mfpu:
-mfpu=vfpv2
I'm fairly certain the Pi is vfpv2, but check.

There's a load of other ARM-specific options, see the docs.

Simon

dpawson
Posts: 115
Joined: Mon Nov 14, 2011 5:05 pm
Contact: Website

Re: ldr (immediate)

Tue Nov 29, 2011 9:00 am

Thanks Simon.
DP goes to read the docs...

Sorry to waste bandwidth.

Aside... How to obtain the address of a data area labelled longway:
which is ... a long way away? E.g. 250Kb away?
adr longway and
ldr seem lacking this one?
Seems wrong to do it in tiny steps?
What am I missing please?

TIA Dave

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: ldr (immediate)

Tue Nov 29, 2011 1:27 pm

Usually you do something like this.

...
ldr r0, =.Ldistant_target
ldr r0, [r0]
...
.extern distant_target
@ The linker will fill in the actual value of distant_target
.Ldistant_target: .word distant_target

Basically, you have a "local" variable containing the address of the possibly-far-away-thing, and you use it indirectly

It also adds the possibility of data / code that's not necessarily defined, as shown by the following conditional branch to a potentially defined symbol:

...
ldr r0, =.Ldistant_target
ldr r0, [r0]
cmp r0, #0
blxne r0
...
.extern distant_target
.weak distant_target
@ The weak definition means that the linker will default this to zero if the symbol distant_target isn't defined
.Ldistant_target: .word distant_target


If you want a defaulted value that's guaranteed to be set, you can use the following (useful for startup vectors, this):

.weak distant_target
.set distant_target, default_target
.Ldistant_target: .word distant_target

This gives you a value which is guaranteed to point somewhere (usually at some default handler that does nothing, or even direct at a `bx lr`) and means you can call the code unconditionally.

Simon

User avatar
johnbeetem
Posts: 945
Joined: Mon Oct 17, 2011 11:18 pm
Location: The Mountains
Contact: Website

Re: ldr (immediate)

Tue Nov 29, 2011 3:04 pm

Quote from dpawson on November 29, 2011, 08:06
From arm arm.

<label> The label of the literal data item that is to be loaded into <Rt>. The assembler calculates the required value of the offset from the PC value of this instruction to the label. Permitted values of the offset are:
Encoding T1 multiples of four in the range 0 to 1020
T1 is All thumb.

I take that to be unsigned positive? Mainly since no mention of a signed addition is present.
For T2, it says Encoding T2 any value in the range -4095 to 4095.
I.e. it is clearly signed.


The ARM11 (ARMv6 architecture) in RasPi does not have 32-bit Thumb-2 instructions. It has 16-bit Thumb instructions, like T1 in this case. For 32-bit instructions, you need ARM format instructions like A1. For RasPi, you need the ARMv7-AR version of ARM ARM. There is an ARMv7-M version of ARM ARM, but it's only for Cortex-M processors.

dpawson
Posts: 115
Joined: Mon Nov 14, 2011 5:05 pm
Contact: Website

Re: ldr (immediate)

Tue Nov 29, 2011 3:33 pm

Quote from tufty on November 29, 2011, 13:27
Usually you do something like this.

...
ldr r0, =.Ldistant_target
ldr r0, [r0]
...
.extern distant_target
@ The linker will fill in the actual value of distant_target
.Ldistant_target: .word distant_target

Simon

Not having much success Simon?

.global _start
_start:
.arm
ldr r0, =.Ldistant_target
ldr r0, [r0]
.extern distant_target
.align 8,0
.space 100000
@ The linker will fill in the actual value of distant_target
.Ldistant_target: .word distant_target
end:

Is the sequence right, i.e. the .space 'gap'?

currently reports

Error: invalid literal constant: pool needs to be closer

Dave

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: ldr (immediate)

Tue Nov 29, 2011 7:23 pm

Nope, sequence wrong.

Try it this way around:
.global _start
_start:
.arm
ldr r0, =.Ldistant_target @ r0 now is a pointer to .Ldistant_target
ldr r0, [r0] @ r0 is now a pointer to distant_target
ldr r0, [r0] @ r0 is now 0xfeedface
.extern distant_target
@ This is a *local* variable containing the address of variable_target
.Ldistant_target: .word distant_target
.align 8,0
.space 100000
@ this is distant_target that lives a bloody long way away
distant_target: .word 0xfeedface
end:

dpawson
Posts: 115
Joined: Mon Nov 14, 2011 5:05 pm
Contact: Website

Re: ldr (immediate)

Wed Nov 30, 2011 6:39 am

I think we must have different assembler versions Simon?

Assembler messages:
second.asm:4: Error: invalid literal constant: pool needs to be closer

where line 4 is
ldr r0, =.Ldistant_target

code as below

regards

> Try it this way around:
> .global _start
> _start:
> .arm
> ldr r0, =.Ldistant_target
> ldr r0, [r0]
> .extern distant_target
> @ This is a *local* variable containing the address of variable_target
> .Ldistant_target: .word distant_target
> .align 8,0
> .space 100000
> @ this is distant_target that lives a bloody long way away
> distant_target: .word 0xfeedface
> end:

tufty
Posts: 1456
Joined: Sun Sep 11, 2011 2:32 pm

Re: ldr (immediate)

Wed Nov 30, 2011 8:10 am

No, I have a bad habit of typing untested code direct into the browser.

The problem is caused by the assembler massing the literals at the end of the current assembly. And, as your current assembly has a honking great 100K gap in it, that means "100K away". It's not a problem you normally hit, as stuff is normally assembled in small files, so literal pools are generally pretty damn close.

To fix it, put a .ltorg directive (just '.ltorg' on a line by itself) between the code and the space. That will case the assembler to dump its literals there, and all will be well.

dpawson
Posts: 115
Joined: Mon Nov 14, 2011 5:05 pm
Contact: Website

Re: ldr (immediate)

Wed Nov 30, 2011 11:52 am

thanks, that's the one.
Found a list of arm directives

http://sourceware.org/binutils.....ndent.html
which seems incorrect in other places though.
Odd.

Anyway, I can now isolate data a long way from code.
Thanks again Simon.

Dave

Return to “Other projects”