I could not find an answer to this question. Can you tell me when the ARM architecture switches from arm mode to thumb mode ? Explain all the ways in whi开发者_如何转开发ch the switching works.
The answers are in the ARM ARM (ARM Architectural Reference Manual). Look at BX both in the ARM instructions and Thumb instructions, for example. There are more instructions in case this is a homework question.
Also look at the pseudo code for what happens when an exception occurs:
R14_ = return link SPSR_ = CPSR CPSR[4:0] = exception mode number CPSR[5] = 0 if == Reset or FIQ then CPSR[6] = 1 CPSR[7] = 1 if != UNDEF or SWI then CPSR[8] = 1 CPSR[9] = CP15_reg1_EEbit PC = exception vector address
The comments for the pseudo code above (in the ARM ARM) describe another answer to your question.
Now what is not obvious, and possibly misleading in the BX and other instruction descriptions is bx rm does not always switch states. The thumb BX description says "branches between ARM code and Thumb code". As if thumb using it would take you to arm code all the time. The pseudo code paints a slightly better picture though, the lsbit of the address in the register tells you if you are branching to thumb or arm code. The PC pseudo code in the thumb description is misleading though. Thumb instructions are 16 bits and the pc moves forward 16 bits at a time 0x00, 0x02, 0x04, etc. In arm mode the instructions are 32 bits and the pc goes 0x00, 0x04, 0x08, etc. (look at the branch instructions ARM the branch is signed_immed<<2, 0,4,8, etc. thumb branch is signed_immed<<1, 0,2,4,6, etc)
Basically if you have a mixed mode program you want to use BX instead of B, in particular when returning bx lr instead of mov pc,lr. So both thumb and arm functions would use bx lr to return. All four cases are covered, arm calling arm, arm calling thumb, thumb calling arm and thumb calling thumb.
So look for instructions that affect the T bit of the cpsr and/or affect the program counter in a way that causes the program counter to branch somewhere. Also be careful to limit yourself to the specific family/core you are interested in (when reading the ARM ARM), armv4t, armv6, armv6, etc. You probably want to get the TRM (Technical Reference Manual) for the specific core you are using as well. The ARM ARM is very generic and as the number of cores increases over time the specific differences are not clear in the ARM ARM. You need the TRM.
I have many revs of the ARM ARM and all of them contain bugs/errors. Intentional or not I don't know, so some hacking is always required to find out how the core you are using really works.
Edit in 2018
I am not going to make a list for every core, etc, etc. That is what the arm documentation is for.
But, again the answer lies in the architectural reference manuals available at ARM's website. You may have to sacrifice an email address, but well worth it.
The key word you are looking for is interwork
or interworking. The old/original arm arm is now called the armv5 architectural reference manual
you look for a T Flag
and see what instructions change that flag. For the armv7-m and maybe armv8-m ARM you can look for interworking support or interworking address. And it shows a list of instructions that affect the PC but do or do not support interworking.
For the armv7-a/r, I am still looking for interworking branch, so far I don't see a section. Look for changing between Thumb state
and ARM state
and there is a section that shows a list of instructions to get from thumb state to arm state and a list to get from arm state to thumb state.
ARMv6(not -M) is straddles the armv5 and armv7 ARMs, but each instruction/encoding shows the architecture that supports it, so you may have to walk through each of the interworking branch instructions and see if they have armv6 support (armv4 and armv5 are also shown). The armv7 manuals are not the whole story though there is a blx
thumb encoding in armv4T/armv5T that is not part of armv6-m/armv7-m what used to be that blx
encoding is now part of the thumb2 extensions.
The primary instruction supported across all of this is BX
, other instructions vary based on architecture as to whether or not you can use them to switch states. If you are writing an emulator, good luck, if you are programming you can try to tune for architecture, but when it doubt just use bx
. Note there is an undocumented bug in the arm11-mpcore (not the older arm11s like the one in the Raspberry Pi) that does a prefetch on data after a pop pc
or ldr pc
if that data resembles a branch instruction.
My recommendation is not to use those instructions on an arm11 mpcore, but to instead do an armv4t style pop or load to a volatile register and bx with that. pop {r3}; bx r3
rather than pop {pc}
. The side effects are hard to see, a read cycle can happen against a peripheral that acts on a read, reading from the data register on a uart and losing a character for example. Just FYI, took us a while to find and confirm this.
精彩评论