First off, you need the ARM Architectural Reference Manual (ARM ARM) at infocenter.arm.com, reference manuals, get the oldest one (armv5 or whatever). the instruction set is well defined in there.
Second, why dont you just assemble some instructions and see what happens?
;@test.s
cmp r1, r0
add r0, #0x1a
whatever cross assembler you have (see http://github.com/dwelch67/raspberrypi in the build gcc directory for a script, just run up thru binutils in that script)
arm-none-linux-gnueabi-as test.s -o test.o
arm-none-linux-gnueabi-objdump -D test.o
arm-none-linux-gnueabi vs arm-none-elf vs arm-elf, etc dont matter for this, all do the same
Disassembly of section .text:
00000000 <.text>:
0: e1510000 cmp r1, r0
4: e280001a add r0, r0, #26
The top four bits of a full 32 bit arm instruction (not thumb) are the condition code, see the condition field section in the ARM ARM. an 0xE means always, always execute this instruction. 0b0000 is eq only execute if the z flag is set, 0b0001 ne only execute if z is clear, etc.
In the ARM ARM push into the arm instruction set, then alphabetical list of arm instructions, then find cmp It starts with cond 00I10101 rn sbz shifter
From our cmp instruction above we see 1110 000101010001 ... so I is a zero bits 15:12 are zero bits 27:26 are zero and 24:21 are 1010 so this is a cmp instruction
bits 19 to 16 above are 0b001 which is rn so rn = 1 (r1) for the shifter operand in the ARM ARM it tells you to look at Addressing Mode 1 Data Processing operands and has a link in the pdf to the page
we know we want the second operand to simply be a register, that is called data processing operands - register, and a page number, go to that page on that page 15:12 is rd 11:4 are zeros and 3:0 is rm. we know from the cmp instruction it says 15:12 should be zero, I wonder if it cares, a cmp does not store a result to a register so rd is not used. rm is used and in this case we want r0, so 0b0000 goes in 3:0 also note that it shows bits 27:25 as zeros, in the cmp instruction 25 is I, we now know that we want a zero there so
between the cmp page and this data processing - register page we have the whole picture
1110 condition
000
1010 opcode
1 S (store flags, that is a 1 for a cmp to be useful)
0001 rn
0000 rd/dont care/sbz
00000
000
0000 rm
cmp rn,rm
cmp r1,r0
the add is similar but uses an immediate, so go to the add instruction in the alpha list of instructions. we now know from the cmp that 24:21 for this class of instruction is the opcode, we can pretty much go straight to the shifter operand stuff to continue from there
this time we are doing add rd,rn,#immediate
so look for the page for #immediate
and the encoding is
1110 condition, always
001 (note the immediate bit is set)
0100 (opcode for add for this type of instruction)
0 (S not saving the flags, it would be adds r0,r0,#26 for that)
0000 (rn = r0)
0000 (rd = r0)
now comes the interesting part, we can encode the 26 different ways. bits 7:0 are the immediate and bits 11:8 allow that immediate to be rotated, 26 is 0x1A, we could just simply put 0x1A in the lower 8 bits and set the rotate to 0, and that is what gnu assembler did. could probably put a 0x68 in the lower 8 bits and a 1 in the rotate_imm field 1101000 rotated right 1*2 bits is 11010 = 0x1A = 26.