ARM/Thumb interworking confusion regarding Thumb-2
Asked Answered
G

2

1

I've been going through ARM ISA related documentation since a while and so far I believe that I've got a good understanding for the basics of ARM/Thumb interworking. I'll quickly summarize that in the following:

  • Instructions can be either 4 byte aligned (ARM) or 2 byte aligned (Thumb).
  • Thumb and ARM instructions reside in separate regions i.e. they are not intermixed without explicit processor state change.
  • State change can happen upon executing either of bx, blx, ldm, ldr. Choosing between ARM or Thumb depends on the value of the least significant bit in the address which can be 0 or 1 respectively.
  • The current state of the processor can be either ARM or thumb. That depends on the state of bit 5 of CPSR.

Rules for state change can be summarized in the following figure taken from this paper:

thumb state change rules]

However, Thumb-2 instructions have confused me a bit. For instance, let's inspect the encoding of instruction ADC which can be found in section A8.8.2 of the ARMv7-A/R reference manual. Basically, the same instruction has 3 distinct encodings 16 bit (Thumb), 32 bit (Thumb2), and 32 bit (ARM).

Here are my questions:

  • Does the 32-bit Thumb-2 instructions execute in ARM or Thumb mode of the processor? (I'm assuming its the latter but not sure)

  • Some resources mention that ARM/Thumb instructions can be "freely" intermixed in thumb-2. Does that mean explicit state change using bx, blx, ldm or ldr doesn't need to happen?

Final note, this is the closest question to mine, however, I'm focusing on interworking.

Gefell answered 28/7, 2015 at 8:51 Comment(3)
32-bit Thumb instructions are still Thumb instructions, so nothing changes in that respect; as explained in the link Thumb-2 is just the name of the feature set that introduced the capability for 32-bit encodings in the first place. Can you give an example of "Some resources..."? They may be referring to the unified assembly language rather than the actual machine code, and/or the fact that Thumb-2 also introduced Thumb versions of most of the instructions which were previously only availible in ARM.Sumpter
@Sumpter For instance, this question on disassembly (reverseengineering.stackexchange.com/questions/6080/…) is mixing ARM and Thumb in the same object file without explicit call to bx or blx to change state. In that case I guess, the assembler(or linker) should automatically generate state changing instructions between ARM and Thumb?Gefell
You can assemble pretty much anything you like (it's just bytes after all); whether it would actually execute correctly is an entirely different matter. (That said, with the revised behaviour of PC writes in ARMv7, there is more scope for wonderfully silly in-line interworking - I reckon sub pc, pc, #3 is the most evil). I'm pretty sure the "freely intermixed" notion is in the context of e.g. you can now use rrx (previously only an "ARM instruction") in your Thumb code without having to branch to a separate function written in a different syntax, by virtue of the new Thumb-2 technologySumpter
W
3

Choicing a mode

so far I believe that I've got a good understanding for the basics of ARM/Thumb interworking.

Well, that is useful, it is really part of an older story. Originally, there was only ARM 32-bit instructions (1980-mid 1990s). Then ARM made a mode that was like a compression front-end that expanded a strictly 16bit opcodes to 32 bits. This was thumb mode (mid 1990s to ~2005). Then ARM came out with thumb2 (which is somewhat nebulous) mainly typified by a mix of both 16bit and 32bit instructions (~2005 to current).

The concept of interworking is only useful for a CPU with thumb (old) and ARM functions. If you have a thumb2 CPU and a good compiler with normal memory (1+ wait states), then the thumb2 is almost always the best choice.

Thumb2 intermixing

In a thumb2 capable processor, you do not need interworking! Ie, you don't change modes. You can use the thumb 16bit encodings and if you ask for a mnemonic where this is not possible, the assembler emits a 32bit version. The Cortex-M CPUs only have a thumb2 mode (really thumb mode with instruction extensions).

Disassembling

There are not really three types of opcodes but two with one extension.

  • Original 32 bit ARM opcodes.
  • 16 bit only thumb encodings.
  • the thumb2 extension with all thumb opcodes plus more.

As the thumb opcodes are more dense, it is not possible to do all types of operations. So the thumb ADC is limited compared to the ARM. However, for most instructions ARM Holding updated the thumb2 (the only mode in the CPU is thumb; thumb2 is extra instructions/opcodes) to have all the capabilities of the ARM mode ADC.

There are discussions on recognizing the mode in a binary elsewhere. Assuming the code is not trying to obfuscate and people made rational choices, you will only have a two types of disassembly.

  1. ARM 32 bit
  2. thumb2

A thumb2 disassembler should work with pure thumb code. Most people do not use interworking. If they do, a large part of the binary will be thumb mode, with a small performance critical section in ARM mode.

A difficulty with thumb2 is the mixed 16/32 bit can lead a disassembler to mis-interpret an instruction stream if it decodes a 32bit encoding mid stream.

Final note, this is the closest question to mine, however, I'm focusing on interworking.

Interworking makes no sense on a thumb2 CPU. Since you question is tagged disassembling, I tried to answer with that focus versus the other questions that is mainly about what the modes are. For elf disassembly, the disassembler should have no trouble to locate major function entry points and should be able to disassemble without much issues.

Wyandotte answered 28/7, 2015 at 14:16 Comment(3)
I think ARM holding thinks of thumb2 as a different beast as the CPU implementation is probably much more tricky with both 16/32bit opcodes (at least the instruction stream decoder). However, for any programmer thumb2 is sort of a fiction. Thinking of thumb2 as an enhanced thumb mode that can do everything the ARM mode can is probably most useful. Since it can do everything, interworking is useless.Wyandotte
Thanks for pointing out that nowadays "interworking is useless". Hence, there is no need to support it in the disassembly tool I'm working on. Supporting thumb2 should be then sufficient to experiment with the whole range of ARMv7.Gefell
dont forget there is more than one definition of thumb2 extensions, armv6m has only a small number of thumb2 extensions, armv7m added something like 100 to 150 instructions. and I have not looked at armv8 nor have I looked at any nuances with a non-cortex-m armv7 thumb2 support.(cortex a/r). they are most definitely extensions to thumb (which itself has potentially armv4, armv5, armv6, armv7, armv8 differences)Programmer
R
2

Does the 32-bit Thumb-2 instructions execute in ARM or Thumb mode of the processor?

Thumb-2 instructions are accessible as were Thumb instructions when the processor is in Thumb state, that is, the T bit in the CPSR is 1 and the J bit in the CPSR is 0. (source)


Some resources mention that ARM/Thumb instructions can be "freely" intermixed in thumb-2. Does that mean explicit state change using bx, blx, ldm or ldr doesn't need to happen?

No state change needs to happen, since Thumb-2 instructions and ordinary Thumb instructions execute in the same state. As for how this fits with the instruction encoding, the ARM Architecture Reference Manual : Thumb-2 Supplement says this:

The new 32-bit Thumb instructions are added in the space previously occupied by the Thumb BL and BLX instructions. This is made possible by treating the BL and BLX instructions as 32-bit instructions, instead of treating them as two 16-bit instructions.

Raincoat answered 28/7, 2015 at 9:22 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.