1

I'm trying to compile a C program to the ARM Thumb-2 instruction set through GCC 6.2, using arm-linux-gnueabihf-gcc from the 6.2.0-5ubuntu12 package on Ubuntu GNU/Linux.

The problem is I'm getting the same binary as when I'm not using the "-mthumb" option:

$ arm-linux-gnueabihf-gcc -c hello.c
$ arm-linux-gnueabihf-objdump -S hello.o

hello.o:     file format elf32-littlearm    

Disassembly of section .text:

00000000 <main>:
   0:   b580        push    {r7, lr}
   2:   af00        add r7, sp, #0
   4:   f240 0000   movw    r0, #0
   8:   f2c0 0000   movt    r0, #0
   c:   f7ff fffe   bl  0 <puts>
  10:   2300        movs    r3, #0
  12:   4618        mov r0, r3
  14:   bd80        pop {r7, pc}

And:

$ arm-linux-gnueabihf-gcc -mthumb -c hello.c 
$ arm-linux-gnueabihf-objdump -S hello.o

hello.o:     file format elf32-littlearm    

Disassembly of section .text:

00000000 <main>:
   0:   b580        push    {r7, lr}
   2:   af00        add r7, sp, #0
   4:   f240 0000   movw    r0, #0
   8:   f2c0 0000   movt    r0, #0
   c:   f7ff fffe   bl  0 <puts>
  10:   2300        movs    r3, #0
  12:   4618        mov r0, r3
  14:   bd80        pop {r7, pc}

I'm getting the same code. I also tried with more complex code (computing the decimals of Pi), and still getting the same code.

I'm getting the same behavior with gcc-4.7-arm-linux-gnueabihf, so the issue is probably in the way I'm using the compiler...

It's hard to believe I'm the only one facing this issue. There must be a way to get GCC to do what's it's supposed to.

jww
  • 97,681
  • 90
  • 411
  • 885
  • 1
    Which arch does the compiler default to? What is your problem? This **is** Thumb2 code, as you seem to want. – too honest for this site Jan 20 '17 at 14:56
  • `-mthumb2`? Ah, no, this is just `-mthumb`. And @Olaf seems right. Thumb-2 doesn't prevent you to having 32 bit "commands" (instruction + operand). – 0andriy Jan 20 '17 at 15:48
  • @0andriy: Ehm, that's what Thumb2 added! To OP: maybe one should first read the instruction set before making assumptions? – too honest for this site Jan 20 '17 at 15:50
  • Indeed, if thumb2 is the default target, this would explain why I'm getting the same code with and without `-mthumb`. How can I know which is the default? However, https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html says that `arm` should be the default mode. Thank you for your first answers! – Michael Opdenacker Jan 20 '17 at 19:49
  • And by the way, can you identify thumb2 code by commands such as 'file' or 'objdump'? I'm not familiar with the arm and thumb assembly... – Michael Opdenacker Jan 20 '17 at 19:53
  • I tried with gcc with '-marm' and indeed I'm getting a different result (all with 32 bit instead of 16 bit as above), which seems to confirm that '-mthumb' is the default, which I still find surprising. – Michael Opdenacker Jan 20 '17 at 22:41
  • According to [3.17.2 ARM Options](https://gcc.gnu.org/onlinedocs/gcc-4.5.3/gcc/ARM-Options.html) in the GCC manual, you may also need `-Wa,-mthumb`. Here's the quote: *"This option [-mthumb] is not passed to the assembler. If you want to force assembler files to be interpreted as Thumb code, either add a `.thumb' directive to the source or pass the -mthumb option directly to the assembler by prefixing it with -Wa."* – jww Jan 21 '17 at 01:02
  • Thanks! Using `-Wa, mthumb` with gcc 6.2 doesn't seem to make any difference though. The [6.3 ARM Options](https://gcc.gnu.org/onlinedocs/gcc-6.3.0/gcc/ARM-Options.html#ARM-Options) in the GCC manual seem to indicate that this is no longer an issue. – Michael Opdenacker Jan 21 '17 at 07:23
  • If you want to control what the compiler is producing for a multi-target compiler setup like this (ARMv4T, ARMv5T, ARMv6, ARMv6m, ARMv7, ARMv7m, etc) you basically have to pick what instruction set you want, the compiler (gcc) may have been built with a default or otherwise has default settings, so if you explicitly want thumb2 you have to ask for it, also understanding there are more than one definition of thumb2 extensions armv6m and armv7m are different (one has over 100 more instructions), or if you dont want any then do some -mthumb armv4t thing. – old_timer Jan 21 '17 at 17:06
  • from the disassembly like the one you have above you can see the variable length instructions the ones that are more than one chunk of 16 bits. the bl is really two separate 16 bit instructions, that are pretty much always shown as a pair, certainly in a disassembly like this. so if you see two halfword instructions that are not BL, then it is using thumb2 extensions OR it is going back and forth between arm and thumb, in that case though the gnu disassembler would show the arm instructions as one 32 bit thing not two 16 bit things. – old_timer Jan 21 '17 at 17:17
  • Thanks a lot for sharing your experience. This really helps! – Michael Opdenacker Jan 23 '17 at 12:44

0 Answers0