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.