Hi Experts,
What is the key difference between the following directives
.thumb
.thumb_func
.force_thumb
.thumb_set
What is the exact use case where the above things can to be applied ?
Regards,
Techguyz
Let's take these one at a time:
1) .thumb
This directive is important when you want to tell the assembler to interpret instructions as Thumb (16-bit) as opposed to the 32-bit ARM instructions. This can also be done with the directive ".code 16" and is the same as a Thumb directive at the start of your source file. It is important for you to include either this directive or ".arm" / ".code 32" at the time of a branch or return: the processor doesn't automatically know which instruction set is used after a procedure call, a procedure return, or after a branch so it needs to be told ahead of time.
2) .thumb_func
The ".thumb_func" directive specifies that the following function is Thumb encoded and implies a ".thumb" directive. This declaration is necessary for the processor to allow the assembler and linker to generate correct code for inter-communication between Arm and Thumb instructions. Even if inter-working is not going to be performed for that particular case it should still be included or else you will have to set the least significant bit before branching which will add more code.
3) .force_thumb
The .force_thumb directive forces the processor to select of Thumb instructions regardless if the processor does not support thumb instructions. A use-case of this function is to switch the code to correct instruction set before a procedure return.
4) .thumb_set
The .thumb_set is the equivalent of calling the .set directive since it creates an alias symbol for another symbol. It also marks that alias as a thumb function in a similar way as the directive ".thumb_func". A good use of this directive is to provide weak aliases for exception handler to the default handler so any function with the exception name will override the default.
Example:
.weak SysTick_Handler
.thumb_set SysTick_Handler, Default_Handler
Sources:
https://www.sourceware.org/binutils/docs-2.12/as.info/ARM-Directives.html
ARM Information Center
assembly - When are ELF directives needed? - Stack Overflow
Intern Inquiry 9/19 - Difference between thumb machine directives
The latest version of the directives for as 2.24 is at
ARM Directives - Using as
a number of new ones have been added
In addition to the above excellent answers, you really should know that...
Put a .thumb_func right before each symbol in your code that you have a pointer to.
For instance, if you don't have a .thumb_func before your SysTick_Handler, the pointer in the exception vectors will be incorrect (it'll point to an even address instead of an odd address).
You may also have your own jump-table - or state machine table, or the like.. Those symbols that are placed in the table, should have the .thumb_func right before them.
You can...
find_end_l:
ldrb r0,[r1],#1
find_end:
cmp r0,#0
bne find_end_l
bx lr
-That means, the .thumb_func directive is 'transparent', it just serves as a way to mark the next symbol to be a thumb function symbol.
Normally I place both of these ...
.type mySymbol,%function
mySymbol:
... right before the functions I declare.