#10128 - wasiliy - Wed Aug 27, 2003 6:50 pm
hi,
when i write :
ldr r1,=0x0404
the assembler seems to store the value 0x0404 somewhere in memory and on runtime the CPU loads the value from memory to the register.
my question is: can i load the value directly and not from memory?
#10129 - torne - Wed Aug 27, 2003 6:56 pm
You can't *load* a value directly, as loading implies 'from memory'. You can use mov to put a constant into a register, however, you can only use constants that are an 8-bit constant shifted left by an even number of bits. 0x0404 cannot be represented in this form, so there is no way to put it into a register except by loading it from memory.
GAS will automatically detect if the number in an ldr instruction using = is of a suitable form (try doing ldr r1,=0x7 or something) and use a mov instruction instead of a memory load. Your best bet is just to use ldr with = all the time, and let the assembler work it out.
#10136 - wasiliy - Wed Aug 27, 2003 7:31 pm
hmm this sucks ...
i try to copy my code from 0x08000000 to 0x03000000 and when i do it, all ldr instructions become useless because they use adresses which start with 0x03000000 but the values are stored at 0x08000000 =(
#10138 - FluBBa - Wed Aug 27, 2003 7:47 pm
Isn't the LDR instruction PC relative?
_________________
I probably suck, my not is a programmer.
#10139 - DekuTree64 - Wed Aug 27, 2003 8:08 pm
ldr r, =constant does a pc-relative load, so it shouldn't matter wether pc is in 0x3000000 or 0x8000000, the pool is the same distance from the pc either way. Try putting a .pool just after your ASM function so you know exactly where it will store all the things you're loading with ldr, and copy the size of your function plus some extra for the pool. The constants should be 4 bytes each, so you should be able to count the number of different things you loaded throughout your function, multiply that by 4 and add it to the size of the function, but I usually copy a little extra just to be sure.
You can also do it more specifically by doing something like
Code: |
.global funcName
@yada yada, do stuff
ldr r0, value @r0 should now be 0x2345
bx lr
value:
.word 0x2345
|
And then you know that right after you return, there's a 4 byte value that you need to copy. That should compile to an ldr r0, [pc] (pc points to 2 instructions ahead, and there's that bx lr, and then the constant, so just load from pc), so as you can see, it doesn't matter what pc is, it just knows that the value it's looking for is 8 bytes ahead.
Be sure to .align those constants if you're using THUMB though, but then you might have 2 unused bytes, so be sure to copy a little extra incase of that. Generally it's only worth using IWRAM for ARM code though, so it should be 4-byte aligned already.
_________________
___________
The best optimization is to do nothing at all.
Therefore a fully optimized program doesn't exist.
-Deku
#10153 - wasiliy - Thu Aug 28, 2003 11:40 am
thank you very much for you help guys!!! my fire runs really fast now on emu and on hardware since it is in iwram.