GP32 Assembly: What can i MOV ?


ConsoleTom

Member
Joined
Dec 4, 2003
Messages
106
Age
47
Location
Germany
Website
Visit site
Hi !

I am a beginner in assembly-programming but i managed to write some little routines. And what i don't understand is, which values are allowed to write to a register ?

For example:
MOV r0,#76800 this one works
MOV r0,#76799 this one not - the compiler quits with an error message (invalid constant)

Is the rule that it must be dividable by 2 ? Or what ?

Greetings

Tobias
 
the value must be a shifter operand..
which means, 8bits of data rotated by an even number of bits(0,2,4,8...30)

you can also do "mov, r0, =#0xXXXXXXXX"
which would be substituted to a PC relative load instruction, and the immediate would be stored
somewhere else.

You should check the ARM ARM for more information.

---
mithris
 
I hope mithris won't mind if I clarify his answer a little bit:

The immediate form of the mov instruction has an 8-bit data field and a 4-bit shift field, with the shift value being multiplied by two. The number that gets put in the register is (data value) shifted left by (shift value x 2). So 76800 can be encoded a couple of ways, either with data value = 75 and shift = 5 (75 << 10 = 76800) or with data value = 250 and shift = 4 (250 << 8 = 76800). You don't have to worry about that, the assembler does it for you.

There is also the mvn instruction, which is the same as mov but will load
the logical inverse of the immediate number.

Another way is to combine a couple of instructions, like:
Code:
mov r1, #76800
sub r1, r1, #1
which will get you 76799.

For other numbers, you could use a pc-relative literal move:
Code:
@ Enable interrupts.

  ldr r1, .Mmu_rINTMSK
  str r0, [r1]

  mov pc,lr  @ return from subroutine

.Mmu_rINTMSK:
  .word 0x14400008
This gets the value 0x14400008 and puts it into r1, then stores the value of r0 using r1 as a memory pointer.

I'm not sure what assembler mithris is using, but for gas or gcc you can do
Code:
@ Enable interrupts.

  ldr r1,  =0x14400008
  str r0, [r1]

  mov pc,lr  @ return from subroutine

.pool
With that instruction, the assembler will figure out if the number can be accommodated in a MOV instruction, and uses that if it can. Otherwise, it will put in a ldr instruction. The literal value will be stored where you put the .pool directive (it's called a literal pool). The code output from those last two examples will be exactly the same.

I'd really recommend that you read the S3C2400 data sheet programming section, and also the gas manual at Red Hat. Alternatively, if you're using linux you can get the same information by typing info as, or entering info:/as into the konqueror address bar if you use KDE.
 
Back
Top