Arm Asm Question


MadDog

Member
Joined
Mar 4, 2006
Messages
262
Age
55
Location
UK
Website
www.maddoggames.com
To do the opposite of bic i've done orr r0,r0,r1,lsl r2 where r0 is the register I want to set a bit with, r1 == 1 and r2 == the bit to set.

I'm doing a func to setup a region in the 940 Protection Unit. It seems to be working but all the regions seem to have the caching policy of the last region set. I have a few suspects, this is the first.
 
I have not looked at arm asm before. That looks like two instructions and four register references. Does that assemble down into one 32 bit code ? Is it possible to just set a bit using 'orr r0, #value ' ?
Sorry to ask questions in response to your question.
Could you recommend a guide for someone who is not new to assembler but is new to the arm ?
Also, what assembler do you use ?
Thanks in advance. There do not seem to be many who choose to use assembler anymore :(
 
MadDog posted on Jul 4 2006 at 11:48 PM said:
To do the opposite of bic i've done orr r0,r0,r1,lsl r2 where r0 is the register I want to set a bit with, r1 == 1 and r2 == the bit to set.

I'm doing a func to setup a region in the 940 Protection Unit. It seems to be working but all the regions seem to have the caching policy of the last region set. I have a few suspects, this is the first.

Orr should work as you wrote. I'm clueless why it couldn't??

Mr.Jabberwocky posted on Jul 5 2006 at 12:51 AM said:
I have not looked at arm asm before. That looks like two instructions and four register references. Does that assemble down into one 32 bit code ?

EDIT: YES and there is possibility to add conditional flag and S flag as well. Arm opcodes are very powerfull.
(sorry for my dumb mistake by not reading last sentence - I thought you asked about two instruction - it's just one Arm opcode)

Mr.Jabberwocky posted on Jul 5 2006 at 12:51 AM said:
Is it possible to just set a bit using 'orr r0, #value ' ?

If "value" is number of individual bit then no. The orr r0,r0,r1,lsl r2 should do it fine. Arm isn't like the Microchip. ;)

Mr.Jabberwocky posted on Jul 5 2006 at 12:51 AM said:
Sorry to ask questions in response to your question.
Could you recommend a guide for someone who is not new to assembler but is new to the arm ?

Not newest but still good:
http://www.heyrick.co.uk/assembler/
and
http://www.chiark.greenend.org.uk/~theom/r...y-cockerell.pdf

Mr.Jabberwocky posted on Jul 5 2006 at 12:51 AM said:
Also at what assembler do you use ?

There is one in every toolchain I think. Personally I code in C adding some inline asm routiness here and there.

Mr.Jabberwocky posted on Jul 5 2006 at 12:51 AM said:
Thanks in advance. There do not seem to be many who choose to use assembler anymore :(

I am and Arm is too nice to not too.
 
Last edited by a moderator:
That looks like two instructions and four register references. Does that assemble down into one 32 bit code ?
Yes.

In this case the single instruction does all of this (as MadDog desired):
r0=r0|(r1<<r2);

Is it possible to just set a bit using 'orr r0, #value ' ?
If it's always the same value, sure.
orr r0,r0,#value

(Though it does depend on the value. Any of 1<<n alone will be just fine. It gets more complicated with other values because the ARM can only load an immediate spanning 12-bits, rotated by an even number).

For an assembler, I use the gnu-assembler, which is part of the gp2x toolchain.
 
refractor posted on Jul 5 2006 at 08:01 AM said:
That looks like two instructions and four register references. Does that assemble down into one 32 bit code ?
Yes.

In this case the single instruction does all of this (as MadDog desired):
r0=r0|(r1<<r2);

I'm not sure if it's executed a single cycle thought?

refractor posted on Jul 5 2006 at 08:01 AM said:
Is it possible to just set a bit using 'orr r0, #value ' ?
If it's always the same value, sure.
orr r0,r0,#value

(Though it does depend on the value. Any of 1<<n alone will be just fine. It gets more complicated with other values because the ARM can only load an immediate spanning 12-bits, rotated by an even number).

Immediate operand has as whole 12 bits but 8 are for the value and 4 for the position. It's enough but sometimes a constant must be computed or orred by more opcodes. It'd be very nice to have an instruction what could load a full 32 bit constant into a register. But it's not big deal anyway and it'd need 2x32 bits (one of opcode and the next for the value).
 
Last edited by a moderator:
Mr.Jabberwocky posted on Jul 4 2006 at 11:51 PM said:
I have not looked at arm asm before. That looks like two instructions and four register references. Does that assemble down into one 32 bit code ?

All arm instructions are 32bit, its a core aspect of the design. Grab a copy of 'ARM system on chip architecture' by Steve Furber. ISBN 0-201-67519-6

For an absolute beginer to arm asm its good, very low level detail on how CPU's work and what drivers thier design. But your want to some coding experiance to read it. Its not the ideal book for someone who knows and understands CPU's and assember and wants to learn the ARM instruction set.

A better book for that is 'ARM Architecture Reference Manual' ISBN 0-201-73719-1



Thanks guys, just wanted to make sure I had interperated the code correctly. Mmm, bug must be some where else. :)
 
Last edited by a moderator:
I'm not sure if it's executed a single cycle though?
No, it's not, there's a register based shift there so you get an extra penalty in this case.

orr r0,r0,r1,lsl r2 <-- one cycle issue, one cycle penalty = two cycles... even if it's not actually run due to the condition.

orr r0,r0,r1,#1<<25 <-- one cycle

Immediate operand has as whole 12 bits but 8 are for the value and 4 for the position.
Ah yes, sorry, my mistake. 8 bits value, 4 bits rotation. :)

It'd be very nice to have an instruction what could load a full 32 bit constant into a register. But it's not big deal anyway and it'd need 2x32 bits (one of opcode and the next for the value).
Yeah, the gas assembler (and others) support(s) the:

ldr r1,=0x12345678

macro instruction, which decides on whether to use a couple of instructions to synthesize the constant or just loads it from a literal pool. If you need it a lot then it makes more sense to store it as data anyway so that it comes straight out of the cache instead of taking two or three cycles to make it everywhere.

A better book for that is 'ARM Architecture Reference Manual' ISBN 0-201-73719-1
Or just download it.
 
refractor posted on Jul 5 2006 at 01:11 PM said:
I'm not sure if it's executed a single cycle though?
No, it's not, there's a register based shift there so you get an extra penalty in this case.

orr r0,r0,r1,lsl r2 <-- one cycle issue, one cycle penalty = two cycles... even if it's not actually run due to the condition.

orr r0,r0,r1,#1<<25 <-- one cycle

Immediate operand has as whole 12 bits but 8 are for the value and 4 for the position.
Ah yes, sorry, my mistake. 8 bits value, 4 bits rotation. :)

It'd be very nice to have an instruction what could load a full 32 bit constant into a register. But it's not big deal anyway and it'd need 2x32 bits (one of opcode and the next for the value).
Yeah, the gas assembler (and others) support(s) the:

ldr r1,=0x12345678

macro instruction, which decides on whether to use a couple of instructions to synthesize the constant or just loads it from a literal pool. If you need it a lot then it makes more sense to store it as data anyway so that it comes straight out of the cache instead of taking two or three cycles to make it everywhere.

A better book for that is 'ARM Architecture Reference Manual' ISBN 0-201-73719-1
Or just download it.

The "ARM ARM" is absolutly required for ARM assembler. Note that you want to get your hands on as may revs of the ARM ARM as you can, not just rev E. I recommend rev B, the white covered one (in print only AFAIK)(not to be confused with the white covered rev E), or the blue covered one, you know actually both of these are rev B, hmmm. Anyway.

I started to ramble on about legal and patent games ARM has had to play and how that is reflected in the ARM ARM. The bottom line, if you are just going to write code in assembler, the different ARM ARM revs are good, newer is probably better. If you want to use it to write an arm emulator, then there are a lot more things you need to know, I will leave it at that.

Yes it is a joy to write in arm assembler, keep it up! You might as well just use the gnu assembler, one assembler is as good as another, if you use gnu at least you can share your code, if you use ARMs or one of the other high dollar ones then your code would have to be translated for use under gnu.

One note, since arm uses a semicolon to mark the end of the line and/or the start of comments, but gnu uses the @ sign I like to write my assembler like this:

MOV R1,R2 ;@ comment comment

Both gnu and arm would handle that line the same way. But a line like this:

MOV R2,R2 ; MOV R2,R3

Is treated as two instructions by gnu but only one by arm. If/when you move your asm from one assembler to another you can get in big trouble this way.

I think this is the only big fault with gas is the semicolon thing, traditionally it meant something else and when ARM came along and did its thing the two ran into this conflict. I guess some might say this is a fault of arms assembly language and not gas.

Gas has some other quirks related to thumb mode, getting it to produce thumb code vs arm code, which I assume you wont be messing with on the gp2x.

Ldr r1,=0x12345678 is the way to go.

I find the best way to learn a new architecture is to write a disassembler (Even if good ones are available, ESP if good ones are available as you can compare your disassebly to the good one). Also writing your own tool to pull apart elf files is a very good thing to have in your back pocket for platforms like this. (same goes for intel hex and motoroal s record, but that is a side discussion, stick to elf files for arm). The difficulty in loading a 32 bit register with a 32 bit value is because ARM strictly limits itself to exactly one word per instruction, you cannot have the opcode, destination register, and 32 bit value fit inside a single 32 bit word. (YES a "WORD" is 32 bits in ARM and a "HALF WORD" is 16 bits, put the word and double word of the x86 world behind you). So 32 bit immediates are not available...What is nice here though is that writing a dissassembler for ARM is as pleasurable as writing arm assembler....
 
Last edited by a moderator:
dwelch posted on Jul 7 2006 at 07:12 PM said:
I think this is the only big fault with gas is the semicolon thing, traditionally it meant something else and when ARM came along and did its thing the two ran into this conflict. I guess some might say this is a fault of arms assembly language and not gas.
I would imagine that ARM's assemblers and/or syntax predate the gnu assembler and that it was kept for historical reasons. I can't think of any other languages that use @ as a comment either.

Anyway, as you said, ';@' allows you to reasonably easily cross-compile for gnu/PocketPC (at least).
 
Last edited by a moderator:
Back
Top