Stimmt, da war was mit "=0"... hab grad keinen Compiler hier.

Dito mit "=w" bzw. "=&w"

Was mit nicht gefällt sind Konstrukte wie
Code:
		: "=w" (result), "=w" (op1)
		: "0" (op1), ...
Hier wüde ich lieber destruktiv auf op1 arbeiten, was ja auch dem Inhalt das asm entspricht.

Wenn man das so hinschreibt wie bisher, hat man zwar ne schönere C-Quelle, aber Magendrücken macht das schon.

Ausserdem belegt das unnötig eines der wertvollen w-Regs, von denen man nur 4 hat. Für deine Anwendung bleiben dann nur noch 2 Regs, Y wird vermutlich für den Frame verbraucht, so daß nur eines überbleibt.

zu -mcall-prologues:

Aus gcc-Sicht teilen sich die Register in (mindestens) 3 Gruppen:

-- fixed (wird nicht allokiert, zB r0, r1)
-- call saved (wird durch f() nicht zerstört, zB Y)
-- call clobbered (aka call used, f() hinterlässt nen Schweinestall, zB X, Z)

Falls eine Funktion ein call used Register verwendet, so muss sie dieses im Prolog sichern (push) und im Epilog wieder herstellen (pop).

Wenn das bei recht vielen Funktionen recht viele Register sind, dann kann man mit -mcall-prologues Platz sparen, weil Epilog und Prolog in eigene Funktionen ausgelagert werden. Diese Sicher-/Herstellfunktionen dauern aber recht lange, weil sie den Rundumschlag machen (müssen) und alle call clobbered register sichern und nicht nur die, welche die Funktion tatsächlich benutzt. -mcall-prologues wirkt also auf callees (aufgerufene) Funktionen.

Aus Sicht des Callers (Aufrufer) sieht das etwas anders aus. Hier bringt die Option nichts (ausser wenn die Funktion selber nen großen Prolog/Epilog hat und wir sie als callee betrachten).
Wenn der Caller eine Variable verwendet, die über einen Funktionsaufruf hinweg lebt, dann muss diese notwendigerweise call saved sein, trägt also u.U. zur Größe des Prolog/Epilog bei oder muss ständig zwischen call saved oder gar Frame (da lebt das Reg) und call used (parameter/ret-val) hin- und herkopiert werden.

Falls die Hardregs (GPRs) der Maschine nicht ausreichen, dann wird für die Funktion ein Frame angelegt und die überschüssigen Variablen leben im Frame. Von der Laufzeit her ist das übel, weil für jeden Zugriff ein Speicherzugriff notwendig ist. Zudem muss ein Framepointer (Y-Reg) angelegt werden, um in den Frame greifen zu können.

Man tut also gut daran, nicht allzu viele lokale Variablen zu haben. Wenn man zB ein lokales Array braucht, dann sollte man das als local static anlegen und nicht als local auto!

Ausserdem ist es günstig, möglichst viele leaf-Functions (Blätter) zu haben, also Funktionen, die keine andere Funktion aufrufen (nur callee sind, aber kein caller). Das kann dadurch gegeben sein, daß die Funktion keine Funktionen aufruft oder aller aufgerufenen Funktionen geinlinet werden oder dead Code sind, etc.