//****************** Multiplikation ******************************************* //Routine multipliziert Z[R31:R30] mit X[R27:R26] Ergebnis in R25:R24:R23:R22 MUL: PUSH R0 IN R0, SREG PUSH R0 PUSH R16 PUSH R28 PUSH R29 // ------------- LDI R22, 0x00 LDI R23, 0x00 LDI R24, 0x00 LDI R25, 0x00 // Ergebnis löschen LDI R16, 0x00 // Merker auf Null // ------------- LDI R29, 0x00 LDI R28, 0x00 // zweiten Faktor auf 4Byte erweitern R29:R28:R27:R26 // ------------- MUL2: CLC ROR R31 ROR R30 // ersten Faktor eins nach rechts-> LSB in Carry BRCC MUL1 // wenn Carry gesetzt [Bit=1], dann ADD R22, R26 // addiere ADC R23, R27 // den zweiten Faktor ADC R24, R28 // zum (Teil)Ergebnis ADC R25, R29 // dazu MUL1: INC R16 CPI R16, 16 BREQ MUL3 // 16mal geschoben, dann fertig CLC ROL R26 ROL R27 ROL R28 ROL R29 // verschiebe zweiten Faktor 1Bit nach links RJMP MUL2 // ------------- MUL3: POP R29 POP R28 POP R16 POP R0 OUT SREG, R0 POP R0 RET //****************** Division ************************************************* // Routine teilt Z[R31:R30] durch Y[R29:R28] Ergebnis in X[R27:R26] Rest in Z(R31:R30) // bei Division durch Null entsteht eine Endlosschleife bei DIV1 !!! DIV: PUSH R0 IN R0, SREG PUSH R0 PUSH R25 // R25 retten // ------------- LDI R25, 0x00 // Merker auf Null LDI R26, 0x00 LDI R27, 0x00 // Ergebnis auf Null DIV1: INC R25 // Merker+1 CLC ROL R28 ROL R29 // R29:R28 ein Bit nach links BRCC DIV5 ROR R29 ROR R28 // R29:R28 ein Bit nach rechts [zurück] RJMP DIV2 DIV5: CP R29, R31 BRLO DIV1 // wenn R31[Z] größer R29[Y] ist, dann zu DIV1 BRNE DIV6 // wenn R31[Z] nicht gleich (also kleiner) R29[Y], dann zu DIV6 CP R30, R28 BRSH DIV1 // wenn R30[Z] größer/gleich R28[Y], dann zu DIV1 DIV6: CLC ROR R29 ROR R28 // R29:R28 ein Bit nach rechts. // ------------- Division DIV2: CP R31, R29 BRLO DIV3 // wenn R31[Z] kleiner R29[Y], dann DIV3 BRNE DIV7 // wenn R31[Z] nicht gleich (also größer), dann DIV7 CP R30, R28 BRLO DIV3 DIV7: SUB R30, R28 SBC R31, R29 // subtrahiere Divident minus Divisor (R31:R30 - R29:R28) ORI R26, 0x01 // Bit0 in Ergebnis (R27:R26) setzen DIV3: DEC R25 BREQ DIV8 // wenn Merker=0 (R25) dann fertig CLC ROL R26 ROL R27 // Ergebnis ein Bit nach links CLC ROR R29 ROR R28 // Divisor (R29:R28) ein Bit nach rechts RJMP DIV2 // ------------- DIV8: POP R25 // R25 zurückholen POP R0 OUT SREG, R0 POP R0 RET