//---------------------------------------------------------------------- // euclidopt.s // Author: Bob Dondero //---------------------------------------------------------------------- .section .rodata promptStr: .string "Enter an integer: " scanfFormatStr: .string "%ld" printfFormatStr: .string "The gcd is %ld\n" //---------------------------------------------------------------------- .section .text //-------------------------------------------------------------- // Return the greatest common divisor of lFirst and lSecond. // long gcd(long lFirst, long lSecond) //-------------------------------------------------------------- // Must be a multiple of 16 .equ GCD_STACK_BYTECOUNT, 48 // Local variable registers: LABSSECOND .req x23 // Callee-saved LABSFIRST .req x22 // Callee-saved LTEMP .req x21 // Callee-saved // Parameter registers: LSECOND .req x20 // Callee-saved LFIRST .req x19 // Callee-saved gcd: // Prolog sub sp, sp, GCD_STACK_BYTECOUNT str x30, [sp] str x19, [sp, 8] str x20, [sp, 16] str x21, [sp, 24] str x22, [sp, 32] str x23, [sp, 40] // Store parameters in registers mov LFIRST, x0 mov LSECOND, x1 // long lTemp // long lAbsFirst // long lAbsSecond // lAbsFirst = labs(lFirst) mov x0, LFIRST // unnecessary bl labs mov LABSFIRST, x0 // lAbsSecond = labs(lSecond) mov x0, LSECOND bl labs mov LABSSECOND, x0 gcdLoop: // if (lAbsSecond == 0) goto gcdLoopEnd cmp LABSSECOND, 0 beq gcdLoopEnd // lTemp = lAbsFirst % lAbsSecond // remainder = (dividend - (quotient * divisor)) sdiv LTEMP, LABSFIRST, LABSSECOND mul x3, LTEMP, LABSSECOND sub LTEMP, LABSFIRST, x3 // lAbsFirst = lAbsSecond mov LABSFIRST, LABSSECOND // lAbsSecond = lTemp mov LABSSECOND, LTEMP // goto gcdLoop b gcdLoop gcdLoopEnd: // Epilog and return lAbsFirst mov x0, LABSFIRST ldr x30, [sp] ldr x19, [sp, 8] ldr x20, [sp, 16] ldr x21, [sp, 24] ldr x22, [sp, 32] ldr x23, [sp, 40] add sp, sp, GCD_STACK_BYTECOUNT ret .size gcd, (. - gcd) // ------------------------------------------------------------- // Read two integers from stdin. Compute their greatest common // divisor, and write it to stdout. Return 0. // int main(void) // ------------------------------------------------------------- // Must be a multiple of 16 .equ MAIN_STACK_BYTECOUNT, 32 // Local variable stack offsets: .equ LGCD, 8 .equ L2, 16 .equ L1, 24 .global main main: // Prolog sub sp, sp, MAIN_STACK_BYTECOUNT str x30, [sp] // long l1 // long l2 // long lGcd // printf("Enter an integer: ") adr x0, promptStr bl printf // scanf("%ld", &l1) adr x0, scanfFormatStr add x1, sp, L1 bl scanf // printf("Enter an integer: ") adr x0, promptStr bl printf // scanf("%ld", &l2) adr x0, scanfFormatStr add x1, sp, L2 bl scanf // lGcd = gcd(l1, l2) ldr x0, [sp, L1] ldr x1, [sp, L2] bl gcd str x0, [sp, LGCD] // printf("The gcd is %ld\n", lGcd) adr x0, printfFormatStr ldr x1, [sp, LGCD] bl printf // Epilog and return 0 mov w0, 0 ldr x30, [sp] add sp, sp, MAIN_STACK_BYTECOUNT ret .size main, (. - main)