/* * Write a subroutine named Div8 to divide a 16-bit number by an 8-bit number. * Next, write a program named Div8_test to test the subroutine Div8 * by dividing the 16-bit-number: 0xAAAA by the 8-bit-number 0x55 * * Q = N/D Divide a 16-bit-number NH:NL by an 8-bit-number Q * * Source: * 1. Binary division in AVR Assembler * http://www.avr-asm-tutorial.net/avr_en/calc/DIVISION.html * 2. Integer division (unsigned) with remainder * http://en.wikipedia.org/wiki/Division_algorithm */ .DEF NL = r0 ; LSB 16-bit-number to be divided .DEF NH = r1 ; MSB 16-bit-number to be divided .DEF DIV = r3 ; 8-bit-number to divide with .DEF QL = r4 ; LSB result .DEF QH = r5 ; MSB result Div8_test: ldi r16,0xAA ; 0xAAAA to be divided mov NH,r16 mov NL,r16 ldi r16,0x55 ; 0x55 to be divided with mov DIV,r16 rcall Div8 rjmp Div8_test /* Div8 * Q = N/D Divide a 16-bit-number NH:NL by an 8-bit-number Q * input * N = Numerator (dividend) * D = Denominator (divisor) * output * Q = Quotient */ Div8: push r0 push r1 push r2 clr r2 ; clear interim register clr QH ; QH:QL = 0b0000 0000 0000 0001 clr QL inc QL div8a: ; start of the division loop clc ; clear carry-bit rol NL ; rotate the next-upper bit of the numerator rol NH ; to the interim register (multiply by 2) rol r2 brcs div8b ; a one has rolled left, so subtract cp r2,DIV ; Division result 1 or 0? brcs div8c ; jump over subtraction, if smaller div8b: sub r2,DIV ; subtract number to divide with sec ; set carry-bit, result is a 1 rjmp div8d ; jump to shift of the result bit div8c: clc ; clear carry-bit, resulting bit is a 0 div8d: rol QL ; rotate carry-bit into result registers rol QH brcc div8a ; as long as zero rotate out of the result ; registers QH:QL go on with the division loop pop r2 pop r1 pop r0 ret ; End of the division reached program8: