Eigentlich sollte das schon gut auf C-Ebene gehen (wenn auch nicht so Effizient wie per asm).

z.B. eine fix-Mul, die 2 Werte (interpretiert als unsigned mit 8 Bit Vor- und Nachkomma) multipliziert:
Code:
/*static inline*/ uint16_t fmul (uint16_t a, uint16_t b)
{
	return (uint16_t) ((uint32_t) a*b >> 16);
}
Code:
.global	fmul
	.type	fmul, @function
fmul:
/* prologue: frame size=0 */
/* prologue end (size=0) */
	movw r18,r22	 ;  4	*movhi/1	[length = 1]
	clr r26	 ;  12	zero_extendhisi2/1	[length = 2]
	clr r27
	clr r20	 ;  13	zero_extendhisi2/1	[length = 2]
	clr r21
	movw r22,r24	 ;  14	*movsi/1	[length = 2]
	movw r24,r26
	rcall __mulsi3	 ;  16	*mulsi3_call	[length = 1]
	movw r26,r24	 ;  17	*movsi/1	[length = 2]
	movw r24,r22
	movw r24,r26	 ;  35	*lshrsi3_const/2	[length = 3]
	clr r26
	clr r27
/* epilogue: frame size=0 */
	ret
/* epilogue end (size=1) */
/* function fmul size 14 (13) */
	.size	fmul, .-fmul

00000094 <__mulsi3>:
  94:	62 9f       	mul	r22, r18
  96:	d0 01       	movw	r26, r0
  98:	73 9f       	mul	r23, r19
  9a:	f0 01       	movw	r30, r0
  9c:	82 9f       	mul	r24, r18
  9e:	e0 0d       	add	r30, r0
  a0:	f1 1d       	adc	r31, r1
  a2:	64 9f       	mul	r22, r20
  a4:	e0 0d       	add	r30, r0
  a6:	f1 1d       	adc	r31, r1
  a8:	92 9f       	mul	r25, r18
  aa:	f0 0d       	add	r31, r0
  ac:	83 9f       	mul	r24, r19
  ae:	f0 0d       	add	r31, r0
  b0:	74 9f       	mul	r23, r20
  b2:	f0 0d       	add	r31, r0
  b4:	65 9f       	mul	r22, r21
  b6:	f0 0d       	add	r31, r0
  b8:	99 27       	eor	r25, r25
  ba:	72 9f       	mul	r23, r18
  bc:	b0 0d       	add	r27, r0
  be:	e1 1d       	adc	r30, r1
  c0:	f9 1f       	adc	r31, r25
  c2:	63 9f       	mul	r22, r19
  c4:	b0 0d       	add	r27, r0
  c6:	e1 1d       	adc	r30, r1
  c8:	f9 1f       	adc	r31, r25
  ca:	bd 01       	movw	r22, r26
  cc:	cf 01       	movw	r24, r30
  ce:	11 24       	eor	r1, r1
  d0:	08 95       	ret
Das ist schon mal deutlich effizienter als float (aber natürlich auch was anderes )

Zum weiteren Optimieren kann man ja von dem Code ausgehen und weitere Kenntnise ausnutzen (z.B. welche Register in mulsi3 Anfangs 0 sind, das spart das Löschen, und man kann z.B. statt dessen __zero_reg__ draufaddieren.