-1

I have been assigned a university project to make sound/audio responsive LED using assembly language. I have already made a C++ code in arduino which uses Fastled library. How do I write a working code for this project in assembly (not restricted to arduino IDE, but preferable). I've already tried converting my code to assembly using an online converter, but it is useless.

5

The Arduino IDE is quite idiosyncratic. It won't let you work on a project that doesn't have a file with the extension “.ino”. On the other hand, it doesn't care about how much code is in that file, and you can keep it happy by creating an empty .ino file. I recommend however that you put at least a comment block in that file, in order to make things less confusing for other people who could see your project. Then you can put your assembly code alongside this empty file, in files of their own ending with the “.S” extension. These files will be preprocessed before being assembled, so you can #include <avr/io.h> and use the macros defined therein for the IO ports, bits, etc.

The project would look like this:

my_project/         # containing directory
├── my_project.ino  # comments only, to keep the IDE happy
├── my_project.S    # main assembly file
└── some_extras.S   # possibly more assembly files...

If the whole project is pure assembly, one of your assembly files should define a symbol called main, which is the entry point of the program:

.global main
main:
    ; code starts here

If you are going to mix assembly and C++, then you can define main() in the .ino file, and call from there your assembly routines, which should be declared as extern "C":

extern "C" void my_assembly_routine();

int main()
{
    my_assembly_routine();
}

Mind the calling conventions when mixing asm and C++ though.

If you are going to use the Arduino core library, then you should define setup() and loop() instead of main(). The Arduino core will then provide it's own main(), which takes care of its initialization.

If you are going to write mostly C++, with only some assembly sprinkled here and there, inline assembly could be a better option. C.f. Michel Keijzers' answer.

  • Upvoted, much new info for me too. – Michel Keijzers Nov 20 '19 at 10:51
0

You have to use the asm keyword, like:

asm("sei \n")

In your case it is advised to use defines, e.g.

#define CLI()          asm("cli \n")
#define noInterrupts() cli()

#define SEI()          asm("sei \n")
#define interrupts()   sei()

See more info at arduino-inline-assembly-tutorial-1.

  • Which IDE do we have to use for this? Also, are these definitions for inline assembly? We are restricted to have the main working code of our program in assembly language. – COAL Nov 20 '19 at 10:14
  • Afaik the default Arduino IDE can be used for this. You probably have to put the code inside the setup and loop functions. Note however, the Arduino IDE creates some code around the setup and loop (like interrupt handling). – Michel Keijzers Nov 20 '19 at 10:49
0

Sorry.

The main learning effect of this exercise is "Don't do it". You won't beat the c++ compiler regarding performance (speed). But you will run into more errors than you can imagine.

The only purpose of manual assembler language inside c/c++ is to add nanosecond timing by adding some asm("nop"); statements to wait a controlled small number of cpu clock cycles. @Michel Keijzers' examples are already implemented. Even in Arduino's convenience environment.

IMO it's more challenging to get beyond Arduino programming by going directly to the MCU's hardware level, dealing with Timers, other MCU components, Registers etc. directly. In C/C++ of course. There you learn that there's much more that can be done beyond the Arduino environment.

Or: Look at compiled results via avr-objdump to learn how C++ is compiled to machine code by experts. Very eventually, you might notice how you could help the compiler optimizing.

  • 1
    1. By learning assembly, you learn a lot more than “don't do it”: you get an intimate understanding of what the compiler and the hardware do, and you learn what kind C/C++ constructs compile to efficient machine code. Also, you must have written at least a little bit of assembly to really appreciate the compiler's job (the output of avr-objdump). 2. It is not rare that avr-gcc produces sub-optimal code, easily beaten by hand-crafted assembly. I guess this flavor of gcc has not been fine-tuned as much as the ARM or x86_64... – Edgar Bonet Nov 20 '19 at 19:34
  • @Edgar Bonet : Sure, you learn a lot more. And only after you've learnt that you can 1. appreciate what the compiler is doing for you 2. interpret its results 3. decide whether you'll continue with assembly programming. BTW: I came from assembly programming, because FORTRAN was not really optimal for small machines, and I'm happy since someone invented C and others built cross-compilers. – DataFiddler Nov 21 '19 at 9:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.