gbadev.org forum archive

This is a read-only mirror of the content originally found on forum.gbadev.org (now offline), salvaged from Wayback machine copies. A new forum can be found here.

ASM > Inconsequent "as" behaviour on infix operators

#390 - anli - Tue Jan 07, 2003 9:08 am

I have some problems using infix operators together with numbers expressed in other forms than decimal. For instance, I am trying to use hexadecimal in the example below.

Technical data:
Version of as: 2.11.2
Command line: as -marm7tdmi file.S -o demo.o

@This works ok
mov r1, #0x400

@This to
mov r1, #400

@This also works, results in 404
mov r1, #400 + 4

@This gives me the error message: Invalid constant!
mov r1, #0x400 + 4

@This also gives me the error message: Invalid constant!
mov r1, #0x400 + 0x4

@So does this
mov r1, #0x0400 + 0x0004

The problem description has been sent to bugs@gnu.org, but I have not yet got a response.

Anyone that understands why this happens?

/anli

#406 - thehive - Tue Jan 07, 2003 2:23 pm

That's not a compiler bug.
It's a bug in your code.
You can only load ARM registers with 8 sequentilal bits at a time.
Of course these bits can be shifted left/right.

#0x400 = 10000000000 = 1 lsl #10 = OK
#400 = 110010000 = 11001 lsl #4 = OK
#404 = 110010100 = 110101 lsl #2 = OK
#0x404 = 10000000100 = 100000001 lsl #2 = NOT OK, too large a number to shift.

#426 - anli - Tue Jan 07, 2003 5:35 pm

Oh, now I see what you mean!

I had to read again and again to really grasp what you were saying!

How can this limitation be possible?
Is it only to keep the instruction length down?

Do I need to use the orr instruction then?

And is there a way to tell the assembler to do this multi instruction stuff automatically?

#428 - Touchstone - Tue Jan 07, 2003 5:49 pm

This limitation (probably) is because instructions have a fixed size of 16 or 32 bits depending on if you use Thumb or ARM. The simplest way of assigning any kind of value in a register is to load it from a symbol. Like so:
Code:
ldr r1, =MyVal
MyVal: .word 0x404

_________________
You can't beat our meat

#437 - pulstar_3 - Tue Jan 07, 2003 6:32 pm

Or you could add 4 to the register after you move the 400 in, like this:

mov r1,$400
add r1,r1,$4

which would end up in the same result. The main difference between the 2 instructions id that MOV is faster than an LDR instruction.