Der Umstand, dass BASCOM-AVR nur eine math. Operation pro Basic-Statement erlaubt, ist sicher ein echter Schönheitsfehler welcher auch vom größten BASCOM-Fan störend empfunden wird. Wie aber schon in diesem Thread mehrfach erwähnt, zählt nicht nur ein Feature, sondern was eine Software insgesamt zu bieten hat und da ist BASCOM-AVR für mich eindeutig in der Führungsposition unter den Basic-Compilern für AVR.

Gerade bei der Mikrocontroller-Programmierung zählt nicht (nur) die Optik des Anwenderprogrammes, sondern der Maschinencode, welcher vom Compiler generiert wird und dann auf der Hardware läuft.

Dass ein Compiler (fastAVR), welcher mehrere math. Operationen in einem Befehl verarbeitet (mit Ablage von Zwischenergebnissen auf dem Stack) nicht unbedingt den besseren Code erzeugt (bzw. erzeugen kann) möchte ich an einem einfachen Beispiel zeigen:

Folgendes Programm auf einem AVR (Mega):

' Multiplikation von 2 Byte Variablen und Addition einer Konstanten Zahl
' B1 = B1 * B2 + 5

Dim B1 as Byte, B2 as Byte

B1 = B1 * B2 + 5

fastAVR erzeugt hier:

;-Line--0014----b1 = b1 * b2 + 5--
lds zl,b1
push zl
lds zl,b2
pop r24
mul zl,r24
movw zl,r0
push zl
ldi zl,Low(5)
pop r24
add zl,r24
sts b1,zl

(28 Byte Codegröße mit 20 Takte Ausführungszeit)

Es wird eine Variable (b1) zuerst in das zl-Register geladen und dann mit push und pop über den Stack in das register r24 verschoben, anstatt diese gleich in das register r24 zu laden. Um dann zum Ergebnis der Multiplikation (in r0) die Zahl 5 zu addieren wird dieses mit einem Word-Verschiebe Befehl in das zl-Register verschoben, dort kann es aber nicht bleiben, da die Konstante 5 auch in dieses Register geladen wird.
Daher das gleiche Spiel wie zu Beginn mit dem Verschieben in das r24-Register mit den Umweg über den Stack bevor die Addition vorgenommen wird. Das Ergebnis hätte aber ohnehin in r0 verbleiben können, anstatt es höchst ineffektiv zweimal weiter zu verschieben.
Nebenbei bemerkt: Auch die Verwendung von Pointer-Register (hier Z) zur Zwischenspeicherung von Variablen lässt meines Erachtens nicht auf ein durchdachtes durchgängiges Konzept schließen.

Ein effektiver Code könnte z.B. so aussehen:

lds r24, b1
lds r24, b2
mul r24, r25
ldi r24, 5
add r24, r0
sts b1, r24

(18 Byte Codegröße mit 10 Takte Ausführungszeit)

fastAVR hat einen um 56% größeren Code mit sogar doppelter
Ausführungszeit erzeugt.


Da bei Bascom durch die Einschränkung auf eine math. Operation pro Basic-Befehl die Zwischenergebnisse naturgemäß in das SRAM gespeichert werden, ist auch hier nicht der kürzest mögliche Code gegenüber einer händischen ASM-Programmierung möglich:

BASCOM-AVR erzeugt für:

B1 = B1 * B2 : B1 = B1 + 5

' B1 = B1 * B2
Lds R16,$0100 ' B1 in r16
Lds R20,$0101 ' B2 in R20
mul R16,R20
Ldi R26,$00 ' Addresse von B1
Ldi R27,$01
St X,R0
' B1 = B1 + 5
Ldi R26,$00 ' Adresse von B1
Ldi R27,$01
Ld r24,X
Subi r24,-5
St X,r24

(26 Byte Codegröße mit 17 Takte Ausführungszeit)

Damit ist aber der von BASCOM-AVR erzeugte Code kürzer und schneller als der fastAVR Code.