Write an assembly code ARM7TDMI that multiplies two 64bit nu
Write an assembly code (ARM7TDMI) that multiplies two 64-bit numbers
Please add comments to each line
Solution
Our 64-bit numbers are two 32-bit integers,
so a 64-bit x is denoted as x = 232 × x1 + x0, where x1 and x0 are two 32-bit numbers.
In same way, another 64-bit number y is denoted as y = 232 × y1 + y0.
Multiplying x and y will give z where z = 264 × x1 × y1 + 232 × (x0 × y1 + x1 × y0) + x0 × y0.
We will multiply below two numbers as an example.
11266401246 (this is 2×232 + 2676466654)
and 12345678
and print the result.
The code for to perform this is as follows:
/*Code starts here*/
/* -- mult64.s */
.data
.align 4
message : .asciz \"Multiplication of %lld by %lld is %lld\ \"
.align 8
number_a_low: .word 2676466654
number_a_high: .word 2
.align 8
number_b_low: .word 12345678
number_b_high: .word 0
.text
mult64:
/* The argument will be passed in r0, r1 and r2, r3 and returned in r0, r1 */
/* keeping the registers which we are going to write */
push {r4, r5, r6, r7, r8, lr}
/* For sake of simplicity, move {r0,r1} into {r4,r5} */
mov r4, r0 /* r0 r4 */
mov r5, r1 /* r5 r1 */
umull r0, r6, r2, r4 /* {r0,r6} r2 * r4 */
umull r7, r8, r3, r4 /* {r7,r8} r3 * r4 */
umull r4, r5, r2, r5 /* {r4,r5} r2 * r5 */
adds r2, r7, r4 /* r2 r7 + r4 and update cpsr */
adc r1, r2, r6 /* r1 r2 + r6 + C */
/* Restore the registers */
pop {r4, r5, r6, r7, r8, lr}
bx lr /* Leave mult64 */
.global main
main:
push {r4, r5, r6, r7, r8, lr} /* keeping the registers which we are going to modify */
/* we are not actually using r8 here but this waythe stack is already 8-bit aligned*/
/* Loading the numbers from memory */
/* {r4,r5} a */
ldr r4, addr_number_a_low /* r4 &a_low */
ldr r4, [r4] /* r4 *r4 */
ldr r5, addr_number_a_high /* r5 &a_high */
ldr r5, [r5] /* r5 *r5 */
/* {r6,r7} b */
ldr r6, addr_number_b_low /* r6 &b_low */
ldr r6, [r6] /* r6 *r6 */
ldr r7, addr_number_b_high /* r7 &b_high */
ldr r7, [r7] /* r7 *r7 */
/* Getting ready to call mult64
/*
The first number is passed in
registers {r0,r1} and the second one in {r2,r3}
*/
mov r0, r4 /* r0 r4 */
mov r1, r5 /* r1 r5 */
mov r2, r6 /* r2 r6 */
mov r3, r7 /* r3 r7 */
bl mult64 /* call mult64 function */
/* The result of the multiplication is in r0,r1 */
/* Now prepare the call to printf */
/* We have to pass &message, {r4,r5}, {r6,r7} and {r0,r1} */
push {r1} /* Push r1 onto the stack. 4th (higher) parameter */
push {r0} /* Push r0 onto the stack. 4th (lower) parameter */
push {r7} /* Push r7 onto the stack. 3rd (higher) parameter */
push {r6} /* Push r6 onto the stack. 3rd (lower) parameter */
mov r3, r5 /* r3 r5. 2rd (higher) parameter */
mov r2, r4 /* r2 r4. 2nd (lower) parameter */
ldr r0, addr_of_message /* r0 &message 1st parameter */
bl printf /* Call printf */
add sp, sp, #16 /* sp sp + 16 */
/* Pop the two registers we pushed above */
mov r0, #0 /* r0 0 */
pop {r4, r5, r6, r7, r8, lr} /* Restore the registers we kept */
bx lr /* Leave main */
addr_of_message : .word message
addr_number_a_low: .word number_a_low
addr_number_a_high: .word number_a_high
addr_number_b_low: .word number_b_low
addr_number_b_high: .word number_b_high
If we execute the program, we should get this output


