Ich habe für meinen MP3-Player den Code auch komplett in Assembler
geschrieben (umfangreich kommentiert natürlich), das sind bis jetzt
etwa 130kB in .asm-Files bzw. 7000 Byte Maschinencode.
Ich würde behaupten, noch einen sehr guten Überblick zu haben (auch
über länger nicht benutzte Code-Teile), da ich für jede Aufgabe eine
eigene inlude-Datei verwende (z.B. lcd.asm, ide.asm, sram.asm...), und
die dort enthalten Routinen entsprechend benenne (lcd_init, fat32_init,
ide_readsector, sram_write etc.).
Ich weiß also, in welcher Datei ich was finde.
Und natürlich ist jede Routine "gekapselt", d.h. die verwendeten
Register werden gesichert, und mögliche Eingabe-/Rückgabewerte sind im
Header dokumentiert. Somit hat man dann eine Art Funktion, die man
separat betrachten kann.
Außerdem verwende ich sinnvolle Variablennamen und Sprungmarken, und
auch achte ich darauf, dass bei Hardwarezugriffen nur die Pins und
Ports geändert werden, die dieser Aufgabe zustehen.
Um weitere Seiteneffekte zu verhindern, kann man auch festlegen, dass
jede Routine am Anfang einen definierten Zustand herstellt, falls das
nicht immer gewährleitstet ist. Bei einem Bus mit Latches hat sich das
als sinnvoll erwiesen.
Meine main.asm fällt dann immer entsprechend kurz aus. Dort stehen nur
ein Header mit Projektstatus, ein paar Konstanten, Interruptverktoren,
Includes und die Initialisierung aller Programmteile.
Man muss halt ein kleines Maß an Disziplin mitbringen, um diesen Stil
beizubehalten. Ich plane für weitere Projekte, den einzelnen Routinen
Versionsnummern zu geben, um Kompatibilitätsprobleme zu vermeiden.