How to make .S file?

IDE 1.8.10, and AS 7.0 if relevant

I have inherited an existing project that includes a .S file. I now want to make a new .S file. How do I do that? For various reasons using a plain .cpp file is unfortunately not an option.

I have found pages that talk about .a and .so files but they don't take me anywhere near a solution.

TIA

a .S file is assembly language source code, for code written with the Gnu assembler that is part of gcc.
You just create it with whichever editor you're using "new tab" will work fine - just create "foo.S" or whatever. in AS7, use a C or C++ project and "new file"/"assembly."

Note that you do NOT want to create an AS7 "AVR Assembler Project", since that uses a somewhat different syntax of source code, usually with a ".ASM" type

Hi westfw

OK about writing the assembler manually into the .S file.

However, I was probably a bit vague in what I want to do. I want to write the C/C++ code in the Arduino IDE, alternatively AS, and then have the compiler to make the .S file if at all possible. I don't know much about the details of the compilation process but doesn't the compiler make the assembler first and then "hex" it? It is a matter writing the .S file(s) and not having the compiler delete them again?

MikD

Ahh. In that case, you want to run "avr-objdump" on the .elf file that the IDE produces.
See How to view assembler, is it possible? - #12 by westfw - Programming Questions - Arduino Forum
This will give you a listing with the hex code and assembler instructions, so it's usually named something other than ".S" - if you want something that you can actually be run through the assembler again instead of something to just look at.

AS7 can generate this automatically. It appears in the "output files" area and has a ".lss" file type.
This is controlled with the ProjectConfiguration/AVR/GNU Common/OutputFiles tab.

(obviously, this is for AVR. For ARM you'd use arm-none-eabi-objdump)

It is an ARM M0+ so I made use of the arm-none-eabi-objdump.exe program. Playing with the switched I am closer but still not in the same format as the .S file I compare it with.

Here is the format I aim for:

	.cpu cortex-m0plus
	.text
	.section	.text._ZN18LoadStuffC2Ev,"ax",%progbits
	.align	1
	.global	_ZN18LoadStuffC2Ev
	.syntax unified
	.code	16
	.thumb_func
	.fpu softvfp
	.type	_ZN18LoadStuffC2Ev, %function
_ZN18LoadStuffC2Ev:
	@ args = 0, pretend = 0, frame = 0
	@ frame_needed = 0, uses_anonymous_args = 0
	@ link register save eliminated.
	movs	r3, #0
	strb	r3, [r0]
	strb	r3, [r0, #1]
	strb	r3, [r0, #2]
	strb	r3, [r0, #3]
	strb	r3, [r0, #4]
	strb	r3, [r0, #5]
	strb	r3, [r0, #6]
	strb	r3, [r0, #7]
	@ sp needed
	bx	lr
	.size	_ZN18LoadStuffC2Ev, .-_ZN18LoadStuffC2Ev
	.global	_ZN18LoadStuffC1Ev
	.thumb_set _ZN18LoadStuffC1Ev,_ZN18LoadStuffC2Ev
	.section	.text._ZN18LoadStuffC2EPh,"ax",%progbits
	.align	1
	.global	_ZN18LoadStuffC2EPh
	.syntax unified
	.code	16
	.thumb_func
	.fpu softvfp
	.type	_ZN18LoadStuffC2EPh, %function
_ZN18LoadStuffC2EPh:
	@ args = 0, pretend = 0, frame = 0 
...

But this is the closest format I have managed to get:

C:\Users\<User>\AppData\Local\Temp\arduino_build_000007\libraries\Loader\ldr.cpp.o:     file format elf32-littlearm

Disassembly of section .text._ZN18LoadStuffC2Ev:

00000000 <_ZN18LoadStuffC1Ev>:
   0:	2300      	movs	r3, #0
   2:	2200      	movs	r2, #0
   4:	54c2      	strb	r2, [r0, r3]
   6:	3301      	adds	r3, #1
   8:	2b08      	cmp	r3, #8
   a:	d1fa      	bne.n	2 <_ZN18LoadStuffC1Ev+0x2>
   c:	4770      	bx	lr

Disassembly of section .text._ZN18LoadStuffC2EPh:

00000000 <_ZN18LoadStuffC1EPh>:
   0:	2300      	movs	r3, #0
   2:	5cca      	ldrb	r2, [r1, r3]
   4:	54c2      	strb	r2, [r0, r3]
...

Please don't pay attention to the actual code it is just some test code. It is more about the format/style.

I have tried to process both the individual file "loader.cpp.o" and also the overall program file Loader.ino.elf but in vain.

Any ideas what switches I have to set? Do I have to do some post processing myself?

I'm pretty sure that some of that info is long gone by the time you get to the binary. (perhaps it is still there as part of debugging info, but I don't know how to get it.)

You can get closer, for individual source files, but providing the "-S" switch to the compile command.
But:

  • this works "oddly" with -flto (link time optimization) used by Arduino. At best, the output won't match the eventual object code.
  • one file at a time.
  • won't have the final values of symbols that will be resolved at link time. Perhaps it'll have actual symbols instead, so this won't matter.
  • usually contains a huge amount of additional "debugging information that clutters things up,, and doesn't look much like actual source code.

What are you actually trying to accomplish?

This is what setup() from Blink.ino ends up looking like:

        .cpu cortex-m0plus
        .fpu softvfp
        .eabi_attribute 20, 1
        .eabi_attribute 21, 1
        .eabi_attribute 23, 3
        .eabi_attribute 24, 1
        .eabi_attribute 25, 1
        .eabi_attribute 26, 1
        .eabi_attribute 30, 4
        .eabi_attribute 34, 0
        .eabi_attribute 18, 4
        .code   16
        .file   "Blink.ino.cpp"
        .text
.Ltext0:
        .cfi_sections   .debug_frame
        .section        .text.setup,"ax",%progbits
        .align  1
        .global setup
        .code   16
        .thumb_func
        .type   setup, %function
setup:
.LFB146:
        .file 1 "/Applications/Arduino-1.8.9 copy.app/Contents/Java/examples/01.Basics/Blink/Blink.ino"
        .loc 1 26 0
        .cfi_startproc
        push    {r3, lr}
        .cfi_def_cfa_offset 8
        .cfi_offset 3, -8
        .cfi_offset 14, -4
        .loc 1 28 0
        mov     r0, #13
        mov     r1, #1
        bl      pinMode
.LVL0:
        .loc 1 29 0
        @ sp needed
        pop     {r3, pc}
        .cfi_endproc
.LFE146:
        .size   setup, .-setup

(the easiest way to add the -S file in the Arduino world is probably to cut&paste the compile command from the (verbose-mode) Arduino message window into a CLI shell, and them change the -o , remove -flto (if present) and add -S.)

Hi westfw,

I tried your -flto on the arm-none-eabi-objdump but the result is much like the other attempts I have made. However, your dump of Blink setup() is the closest I have seen.

All I really want is to convert the .cpp file to .S so the .S file can be used instead of the .cpp file 1:1. I have no need to do it on the MainProgram.ino file.

So if the IDE can make this without having to handle it afterwards it will definitely be easier.

All I really want is to convert the .cpp file to .S so the .S file can be used instead of the .cpp file 1:1

I don't understand why you'd want to do this.

So if the IDE can make this without having to handle it afterwards it will definitely be easier.

AFAICT, getting the IDE to do this (only on SOME files?) would be significantly more difficult that doing it outside of the IDE.

I only need to get the .S file for one particular .cpp file due to the fact that the functionality may only be distributed as a .S file. The rest will stay as plain C++ files.