This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Difference between thumb machine directives

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

  • 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

        .thumb_func

    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

         .thumb_func

    mySymbol:

    ... right before the functions I declare.