#8194 - funkeejeffou - Fri Jul 04, 2003 5:35 am
Can't get to compile a load instructiun indexed and shifted :
Code: |
ldr r0, [r1, r2, lsl#1] |
Is it a syntax problem, or is it unimplemented in Goldroad?
thanks to anyone who will help.
#8204 - TurboHz - Fri Jul 04, 2003 12:27 pm
That must be a syntax problem. I've used that kind of adressing ... try replacing the "#" character with a " " (space).,
#8205 - Lupin - Fri Jul 04, 2003 12:34 pm
ldr r0, [r1, r2, lsl #1]!
I think that's it
#8208 - funkeejeffou - Fri Jul 04, 2003 2:33 pm
Hum... Neither works.
Please TurboHz, if you've used that kind of adressing, could you just check the syntax in your code?
#8222 - GbaGuy - Fri Jul 04, 2003 7:18 pm
Goldroad can be wierd sometimes...
Maybe put the ", lsl#1" outside of the []s?
#8257 - funkeejeffou - Sat Jul 05, 2003 10:10 pm
Nope, it's still not working...
#8259 - Dev - Sun Jul 06, 2003 3:19 am
Try using all caps on LSL and have a space between the , and #
i.e. LDR R0,[R1,R2,LSL #1]
It's always possible that the assembler is looking for case-specific "LSL" ?
Either way, you're using a valid opcode format, and if it doesn't work, it's a bug...
Have you checked Goldroad's home page to see if it's a known issue?
(I don't use GR myself, so I can't offer any advice on where to contact the author, sorry).
#8266 - funkeejeffou - Sun Jul 06, 2003 2:19 pm
Ok; found what it is by looking at some source codes :
Code: |
ldr r0,[r1,r2,lsl #1] |
There is only one space after the lsl(so before the #1).
This works for ldr and ldrb, but not for ldrh(and of course, it was the opcode that I used in my code).
Is it normal that loading or storing a halfword with a shifted address doesn't work on the ARM processor?
By the way, let's say I load a 4 bytes value like this :
Code: |
ldr r0,[r1,r2,lsl #1] |
then I store it
Will only the less significant bytes will be copied, or should I mask my value before storing it:
Code: |
and r0, r0, 0x0000FFFF |
Thanks for all of you for helping me out
#8274 - torne - Sun Jul 06, 2003 7:51 pm
This is normal. The ldrh, lrdsh, ldrsb, and the corresponding str instructions use a different addressing mode to normal load/store instructions, which only allows the following 6 addressing modes:
Immediate offset: [<Rn>, #+/-<offset_8>]
Register offset: [<Rn>, +/-<Rm>]
Immediate preindexed: [<Rn>, #+/-<offset_8>]!
Register preindexed: [<Rn>], +/-<Rm>
Immediate postindexed: [<Rn>], #+/-<offset_8>
Register postindexed: [<Rn>], +/-<Rm>
The normal ldr/str instructions have all the above addressing modes, and also three more:
Scaled register offset: [<Rn>, #+/-<offset_8>, <shift> #<shift_imm>]
Scaled register preindexed: [<Rn>, #+/-<offset_8>, <shift> #<shift_imm>]!
Scaled register postindexed: [<Rn>], #+/-<offset_8>, <shift> #<shift_imm>
Get a copy of the ARM Architectural Reference Manual from here: http://www.altera.com/literature/third-party/ddi0100e_arm_arm.pdf as it contains exact details of the ARM instruction set, from the official source. =)
As for your second question, if you store a halfword from a register, the bottom 16 bits will be stored, as if you had masked it. If the value is signed, use strsh, as otherwise the sign will be destroyed.
Torne
Last edited by torne on Wed Aug 06, 2003 12:34 pm; edited 1 time in total
#9458 - hzx - Tue Aug 05, 2003 1:27 pm
I think I met with an error in GoldRoad. Please, report if I am wrong.
I have 3 files, main.asm, library.asm and predef.asm. Main.asm contains the main code, the library.asm contains the functions like PutPixel, etc., and predef.asm the predefined variable data.
predef.asm:
variable1 @DCD 5, 5, 6, 6
variable2 @DCD ...
main.asm:
...
@textarea 0x08000000 ; it seems to be necessary for defining data in the ROM space
...
ldr r0, =variable1
...
@include library.asm
@include predef.asm
@pool
@endarea
When I load this code into the emulator and disassemble it, it gives:
...
08000014 ldr r0, [$080001ac] (=$08000178)
...
08000178 mov pc, lr ; the last line of code in the library asm
0800017c 00000005
08000180 00000005
08000184 00000006
08000188 00000006
...
So. As you can see in the 08000014 line, the ldr loads a constant from the pool. The constant should has the address of the first byte of variable1, thought, it hasn't. It contains a lower (illegal) address . Is it a bug or a feature?
_________________
.hzx
#9461 - funkeejeffou - Tue Aug 05, 2003 2:19 pm
Could you please put your entire code of the main.asm file?
#9470 - momo - Tue Aug 05, 2003 4:42 pm
@hzx
I have the the same problem with goldroad. If use the @pool keyword,
goldroad get any adressproblems. So, I use no ldr xx,=xx Commands.
The main problem is (I think), the goldroad development is stopped (no update since more then a year). There are much more problems, for example incbin and folders, wrong thumbcode check (add r0,r0,r9 is not possible but goldroad assemble it to sub r0,r0,r1), ....
I hope it comes a new Version of goldroad, because I dont like the gas/armasm Syntax.
Please forgive me, my bad English X)
#9490 - hzx - Wed Aug 06, 2003 9:52 am
@arm
@fsize 32
@include gba.asm
@textarea 0x02000000
stack @DCD
@endarea
@textarea 0x08000000
ldr r13, =stack ; setting up stack
ldr r1, =REG_DISPCNT
ldr r2, =(BG2_ENABLE | MODE_3)
str r2, [r1] ; init video mode
ldr r0, =linenumber
add r0, r0, #4 ; necessary because of goldroad bug
ldr r12, [r0]+4
.loop
cmp r12, #0
beq labx
sub r12, r12, #1
ldr r1, [r0]+4
ldr r2, [r0]+4
ldr r3, [r0]+4
ldr r4, [r0]+4
mov r5, #255
bl DrawLine
b loop
.labx:
b labx
@include predefs.asm
@include library.asm
@pool
@endarea
_________________
.hzx
#9491 - hzx - Wed Aug 06, 2003 9:53 am
Sorry,
@include library.asm
@include predefs.asm
is the right order
_________________
.hzx
#9510 - hzx - Wed Aug 06, 2003 9:29 pm
It seems the misaddressing can be triggered variously:
subroutine1
...
subroutine2
...
sub2data @DCD 0,0,0,0
and
subroutine1
...
sub2data @DCD 0,0,0,0
subroutine2
...
codes has the same problem, if they are present in an included file.
_________________
.hzx
#9516 - funkeejeffou - Thu Aug 07, 2003 11:25 am
I don't really understand your code organization, but some things seems wrong.
When you do not put a textarea in goldroad, it will assume your code or data will be in ROM, so it will assume a "@textarea 0x8000000". The first instruction of your code in ROM must be a branch to your start label, it is the address of the first line of code that will be executed.
In your code, there is not such a label.
Secondly, you include gba.asm in ROM, then you redefine some other code in ROM after the "textarea 0x2000000". This code will overwrite gba.asm.
When you use a "textarea", always spill the litteral pool at the end of its definition then put "@endarea". When your data is not in ROM (ie in IWRAM), you must copy it manually in its location by using a loop of ldr and str(there are some previous posts on this topic).
I'm using goldroad 1.7 and coded more than 3000 lines for a 3D engine. It works perfectly, so I doubt that golroad is so buggy. Your code presented like you did cannot work, try changing the things said below and tell me if it works. I'll try to help you as much as I can.
Cheers
#9523 - hzx - Thu Aug 07, 2003 5:02 pm
Hm, let me see.
When I use include files, I assume that the compiler will copy all sources into the main file and will process it as a whole. So if I have a main.asm
Code: |
@textarea 0x08000000
mov r0, #0
@include library.asm
@pool
@endarea
|
and a library.asm
the compiler will create a big file to work on
Code: |
@textarea
mov r0, #0
sub r0, r0, #1
@pool
@endarea
|
and compile it as a whole. In this case the mov r0, #0 instruction it the first instr. of my code, since the execution of the code will begin at 0x08000000. Thus, no label is necessary. When I define @textarea 0x02000000 and a label in it, IMHO it is nothing more then a label I can address later. My problem is, that if you use include files, the GoldRoad sometimes misses addresses of code and data. Let me show you an example. Library.asm:
Code: |
subroutine1:
<stack stuff>
ldr r0, =subroutine_data
ldr r1, [r0]+4
<more code>
<stack stuff>
mov r15, r14
subroutine_data @DCD 0,0,10,10,100,100,1000,1000
subroutine2:
<stack stuff>
...
|
then you include this file into main.asm, just right before the @pool keyword. Compile it, disassemble and watch, as the =subroutine_data constant on the constant pool will be illegal, and pointing to the mov r15, r14 line, not to the data. The difference is always on line of code, 4 bytes.
_________________
.hzx
#9524 - momo - Thu Aug 07, 2003 5:08 pm
I think I have found the Problem, if the @pool is more then 2kByte away from a ldr rx,=xxx Comand, the Address is set to 2k, because there is no higher adress possible (11Bit). But Goldroad dont notice that, and will generate confuse addresses. According to circumstances goldroad print a "pool out of range" Message, but NOT always!!
->hzx
Replace your @pool, with this:
poolstart @pool
poolend
@echo "Poolentrys = $",(poolend-poolstart)/4
If goldroad print out an Poolentrys = $0, then the pool is to far away and goldroad dont notice that.
#9525 - funkeejeffou - Thu Aug 07, 2003 5:51 pm
I don't know what your code is supposed to do but try this as your main file :
b start
@ltorg
@textarea 0x02000000
stack @DCD 0 ;this is a dummy value
@ltorg
@endarea
start
;this will copy stack in EWRAM
mov r0, stack
mov r1, 0x2000000
ldr r2, [r0]
str r2, [r1]
ldr r13, =stack ; setting up stack
ldr r1, =REG_DISPCNT
ldr r2, =(BG2_ENABLE | MODE_3)
strh r2, [r1] ; init video mode ;this is a 16bit register, not a 32
ldr r0, =linenumber
ldr r12, [r0]+4! ;if there is no "!", r0 won't be modified
loop
cmp r12, #0
beq labx
sub r12, r12, #1
ldr r1, [r0]+4!
ldr r2, [r0]+4!
ldr r3, [r0]+4!
ldr r4, [r0]+4!
mov r5, #255
bl DrawLine
b loop
labx
b labx
@include gba.asm
@include predefs.asm
@include library.asm
@ltorg
@endarea
#9536 - hzx - Thu Aug 07, 2003 9:22 pm
What is @ltorg?
The GbaGuy tutorial states that you have to place your code between @textarea and @endarea labels. It seems to be missing from your code. The @textarea 0x08000000 will place your code to the beginning of the ROM memory, so defining a textarea for 03000000 is ony for convenience. By the way, it seems that the pool & include illegal memory addressing problem exists anyway: looking around some GoldRoad forums a lot of people have noticed it already. It is a luck that you have not.
_________________
.hzx
#9541 - funkeejeffou - Fri Aug 08, 2003 12:32 am
@ltorg is the same as @pool, it spills the litteral. Many other people have done great code with goldroad, and believe me, the code was more complicated than the one you show.
I think the error you got comes from the fact that you don't put a @ltorg before your @endarea of EWRAM.
By the way, when you do not put any @textarea, goldroad considers it as if it was in ROM, so the @textarea 0x8000000 is implicit(look at the manual).
Your code cannot work, too many details are ommited. Why don't you try what I said?
#9549 - hzx - Fri Aug 08, 2003 7:50 am
I will try it :) Thx for helping me. I think I will have some more questions later :)
First of all, you said, you have to use ! for writeback. But I used a simple ldr r1, [r0]+#4, and it worked, and the official ARM docs used it on the same way.
_________________
.hzx
#9550 - momo - Fri Aug 08, 2003 9:27 am
ldr r0,[r1]+#4! is a wrong syntax!! Because you add 4 to r1 after transfer and auto-index it too?
-------------
ldr r0,[r1,#4] ;r0 = mem[r1 + 4]
"auto-indexing"
ldr r0,[r1,#4]! ;r0 = mem[r1 + 4]
;r1 = r1 + 4
"post-indexed"
ldr r0,[r1],#4 ;r0 = mem[r1]
;r1 = r1 + 4
--------------
I have found another bug in pool addressing, under any circumstances goldroad set a ldr r0,=anyvariable is assembled to ldr r0,0. But if I use a mov r0,anyvariable, goldroad change it internally to ldr r0,=anyvariable, so the bug is no more. Now I use, only mov r0,anyvariable for Addressloading and if use constants I write ldr r0,=$12345 (this works ever in goldroad). And I guarantee that is no pool outside a 2k Space. I hope goldroad will be fixed sometimes.
#9553 - funkeejeffou - Fri Aug 08, 2003 11:32 am
Momo is right.
For post indexed load/store instructiuns, goldroad uses :
Code: |
ldr r0, [r1]+4!
or
ldr r0, [r1],#4 |
this will store in r0 the value contained at the adress contained in r1. After the affectation of r0, r1 is incremented by 4 bytes.
I use the first syntax and it always worked.
For preindexed, if you do not put a "!", r1 won't be modified after the allocation.
#9862 - hzx - Wed Aug 20, 2003 2:24 pm
So, let's see.
The ldr reg, =label illegal address problem seems to be exist, and I can not figure out how could I workaround it with organizing code, data and the constant pool. Momo's solution worked perfectly: using mov r0, #label compiles to legal ldr reg, =label assembler code, and it seems that the author of GoldRoad prefers this way of coding in his documentation too.
The
@textarea 0x03000000
variable @DCD 0
@endarea
@textarea 0x08000000
...code...
though seems logical, the GoldRoad assemlies the variable at the 0x08000000 address, and code begins with 0x08000004 position. It is not a bug, just a bit confusing IMHO.
_________________
.hzx
#9867 - torne - Wed Aug 20, 2003 4:12 pm
If you mean it assembles the VALUE of the variable at 0x80000000 that's definately a bug, as that clearly is not what the section directives specify. If you mean it puts the ADDRESS of the varaible at 0x80000000, then that's a plausible but uncommon place to put a literal pool. =)
Torne
#9902 - hzx - Thu Aug 21, 2003 1:21 pm
Yes, it assembles the value of the variable. So
@textarea 0x03000000
variable @DCD 0xff
@endarea
@textarea 0x08000000
...code...
@endarea
gives you a code
08000000 000000ff
08000004 <code>
But if you do an ldr r0, =variable, then it loads the proper 0x03000000 value into r0 :)
_________________
.hzx
#12611 - jdxpolygon - Wed Nov 19, 2003 4:37 pm
torne wrote: |
If you mean it assembles the VALUE of the variable at 0x80000000 that's definately a bug, as that clearly is not what the section directives specify. If you mean it puts the ADDRESS of the varaible at 0x80000000, then that's a plausible but uncommon place to put a literal pool. =)
Torne |
It's not a bug. It's doing what the @textarea directive is supposed to do. It's purpose is to change the way labels are defined in the assembly by offsetting them. For example, if @textarea 0x03000000 was used, any labels (and possibly other aspects of the code) will be generated as if they were in the range specified, but the instructions or data bytes will still go into the 'cartridge' at the same place as they would have without the @textarea directive, presumably somewhere above 0x08000000. I think the main point of @textarea directives is so you can write, for example, an assembly routine, which obviously has to be stored on the cartridge (above 0x08000000) but can be transfered to IWRAM once the program is running, and everything will be set up right.
If you actually want to change where on the cartridge the next instructions or data will be positioned, you need to use the @org directive. For example:
@org 0x08001000
I don't know if you can use something like @org 0x03000000 but that would be handy for creating label definitions there without having to store blank space on the cartridge at the same time.
JD
#12614 - torne - Wed Nov 19, 2003 5:33 pm
OK, that's rather silly. In 'real' assembly we let the linker handle relocation =)
Makes sense now. Not that it was me who had the problem to begin with.