I am trying to do some bare-metal programming in ARM with GCC and testing on QEMU. Whenever I call into an ARM label from C, my program hangs. I have a simple example of code
To eliminate the confusion:
The problem was that Ubuntu's GCC cross-compiler for ARM generates thumb (16-bit) instructions by default. As other answers here show, calling between the two is possible, but while the GNU assembler detected that the C code was generating thumb instructions and so happily generated shims using bx to set the mode correctly for calling into C, I have no control over what GCC itself generates for calling functions, and it was calling them with just bl, which broke because my assembly code needs to be ARM instructions (32-bit).
The solution (which is poorly documented) is to send gcc -marm, which will at least make all the code the same type.
If there is a switch to get gcc to generate bx calls for functions, that would probably work as well.