As other answers state, you want to use arm-none-eabi-gcc
to compile your code.
However, compiled code (by itself) doesn't do much good! You need to convert it to an .elf or .hex format. You need to be able to load it to the microcontroller. You probably want to be able to debug the code on the target.
I recommend using the free GNU ARM Embedded Toolchain. It is only the toolchain; it doesn't provide an IDE. It's a single install, and includes:
- arm-none-eabi-gcc (to compile code)
- arm-none-eabi-gdb (to debug)
- arm-none-eabi-objcopy (to translate to .hex)
- arm-none-eabi-size (to get a readout on your code's memory utilization)
- (more)
It's maintained by ARM developers and is available for Windows/MacOS/Linux.
There is a separate project for ARM development using Eclipse IDE, called GNU ARM Eclipse. Even if you don't want to use Eclipse, I recommend scanning their website. They explain how to install the GNU ARM Embedded Toolchain, how to set up different debuggers, etc.
By the way, GNU ARM Eclipse is particularly good for ST ARM development. It has built-in linker scripts for the different ST families, has ties to ST's Standard Peripheral Libraries, etc.
Finally, I realize that this bypasses the custom USB programming interface presented by the Nucleo. My personal opinion is that you should use these standard tools instead, mostly because you will end up using them when you want to port your code to a non-Nucleo board.
Responding to your comment, I've never seen a.out ("assembler output") used for ARM microcontrollers. In my projects, I generally have many c files, each which compile to an object file. Then the objects are combined with the linker, which outputs a hex or elf file.
Here's some extra info in case it helps:
My compile commands are complicated, but they are handled by my IDE so it's transparent to me. Here is an example for main.c
:
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -Wunused -Wuninitialized -Wall -Wextra -Wmissing-declarations -Wpointer-arith -Wshadow -Wlogical-op -Waggregate-return -Wfloat-equal -g3 -DUSE_FULL_ASSERT -DDEBUG -DTRACE -DSTM32F10X_CL -DUSE_STDPERIPH_DRIVER -DHSE_VALUE=12000000 -UOS_USE_SEMIHOSTING -UOS_USE_TRACE_SEMIHOSTING_STDOUT -I"../include" -I"../include/usb" -I"../system/include" -I"../system/include/cmsis" -I"../system/include/stm32f1-stdperiph" -I"../system/STM32_USB_Device_Library/Core/inc" -I"../system/STM32_USB_Device_Library/Class/cdc/inc" -I"../system/STM32_USB_OTG_Driver/inc" -std=gnu11 -Wmissing-prototypes -Wstrict-prototypes -Wbad-function-cast -MMD -MP -MF"src/main.d" -MT"src/main.o" -c -o "src/main.o" "../src/main.c"
This includes hook into the Standard Peripheral Libraries ("SPL"), options to allow debugging, etc. If you stripped out all the includes, warnings, and SPL stuff (but you shouldn't actually strip out the warnings!), you are still left with:
arm-none-eabi-gcc -mcpu=cortex-m3 -mthumb -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -g3 -std=gnu11 -MMD -MP -MF"src/main.d" -MT"src/main.o" -c -o "src/main.o" "../src/main.c"
Some of these may still be unnecessary, but it gives you an idea of what is required.
Then, after all the object files are created, they are linked like so:
(I've simplified the following command)
Invoking: Cross ARM C++ Linker
arm-none-eabi-g++ -mcpu=cortex-m3 -mthumb -Og -fmessage-length=0 -fsigned-char -ffunction-sections -fdata-sections -ffreestanding -g3 -T mem.ld -T libs.ld -T sections.ld -nostartfiles -Xlinker --gc-sections -L"../ldscripts" -Wl,-Map,"AP.map" --specs=nano.specs -o "AP.elf" ./src/main.o ./{my other object files}.o
Finished building target: AP.elf
Some of the command options are duplicated, and so might me unnecessary to pass into both the compiler and the linker. Again, since my IDE handles it, I haven't really paid attention :)
These complexities in ARM development are one of the reasons that I started using an IDE (Eclipse, in my case).