# How to decode ARMv7 instructions?

I'm trying to understand ARM instruction encoding.

The following image shows C code along with its corresponding assembly instructions:

I looked at the ARMv7 reference manual. However, I couldn't find the relationship between the machine code and the corresponding assembly instruction.

For example,

I couldn't relate the machine code

F1AD0D08


to the assembly instruction

sub.w sp, sp, #8


Could you help me with this?

======================================================

Based on the answers and after looking at the reference manual, I added the following information.

The processor name is Cortex-M4F.

The processor architecture of the microcontroller I use is ARMv7.

Specifically, the microcontroller profile employed is ARMv7-M.

From the manual:

ARMv7-M The microcontroller profile for systems supporting only the Thumb instruction set, and where overall size and deterministic operation for an implementation are more important than absolute performance.

• ARM version numbering is horrendously confusing. The number on the chip (no V) is completely unrelated to the version of the instruction set (with a V). e.g. "ARM926EJ-S" chips use the "ARMv5TE" archite3cture. My "not ARM7" comment left out the V and should in any case have said "not 32-bit ARM". dwelch is correct. – pjc50 Jun 14 '16 at 11:33
• arm7 is the marketing name that uses armv4, arm9 uses armv5, arm11 uses armv6, then you get into the cortex-a and cortex-r which use armv7 (or armv8). armv7 != arm7. one term is the architectural numbering the other is a product name – old_timer Jun 14 '16 at 13:34
• and there is enough of a difference between armv7(-ar) and armv7-m that if you are talking about the armv7-m it is a good idea to put the m out there. – old_timer Jun 14 '16 at 13:34
• yes confusing, painful, detailed, etc. the alternative is to generically say x86 to cover a myriad of processors that are different internally (or to use their code names, ivy bridge, sandy bridge, etc, which is even confusing as some are the same architecture on a different technology 14nm instead of 22) – old_timer Jun 14 '16 at 13:36
• for this particular question, the decoding of these instructions is covered in both the armv7-m and armv7-ar architectural reference manuals as thumb2 is supported in both. – old_timer Jun 14 '16 at 13:38

The ARMv7-M reference manual does not have a decode lookup table, but the encoding for each instruction is listed.

In the specific manual you have linked, you will find this in the section A6.7 - Alphabetical list of ARMv7-M Thumb instruction.

This contains - as stated - a list of every instruction, and their corresponding binary encoding. For example, page A6-16 has the binary encoding for the ADC (immediate) instruction. We can see that it starts with 11110... and spans two words.

The problem is going "backwards". The manual does indeed contain all the necessary information, but it is difficult to search. The disassembler has the data structures in place to do that for you, and if you want a table and do it manually, I suggest looking at the source code files for an ARM disassembler, for example GNU binutils.

• Worth noting, as the 68000-architecture fanboy I am, is that the M68000PM/AD reference manual for the 68000 instruction set do contain this reverse table, ordered in binary order, making this lookup trivial. – pipe Jun 13 '16 at 10:01
• A quick look through the binutils sources shows, that the code for the ARM disassembler can be found here – erebos Jun 13 '16 at 11:15

In the ARMv7-m ARM that I am looking at encoding T3 for subtract immediate which is supported by ARMv7-M architecture is in the form

SUB{S}<c>.W <Rd>,<Rn>,#<const>


the bit pattern 11110i01101S.... which matches with the 0xF1A of the instruction, sp is 13 and the two instances of 0XD in the encoding line up with that along with the immediate #8.

If you look at LDR (literal) the encoding is 0x4800 with a register and immediate. this instruction as documented does a pc relative load, so the pc is implied. likewise this is a 32 bit load, so when we assume 32 bit alignment the offset makes sense 0x34 is 110100, being 32 bit aligned we dont need the lower two bits they burn instruction space so 1101 which is a 0x0D giving 0x490D as the encoding.

It is all right there in the document you are looking at.

http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0210c/CACCCHGF.html

490D : the '4' = 0100 and '9' = 1001, so the top five bits are 01001. Looking down the table shows that as "PC relative load". The next three bits are 001 for 'Rd', the destination register. The operand is 'D', which multiplied by 4 to count words is 0x34.

F1AD0D08 is a bit strange. Someone else can try that one.