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....