//----------------------------------------------------------------- // gcd.s // // This is an assembly language implementation for a function // that can be called from a high-level language to calculate // the Greatest Common Divisor for a pair of 32-bit integers. // Following the C/C++ calling conventions, the two function- // arguments are transmitted via the stack and the function's // value is returned in the accumulator register (i.e., EAX). // // assemble using: $ as gcd.s -o gcd.o // // programmer: ALLAN CRUSE // written on: 04 MAR 2006 //----------------------------------------------------------------- # equates for stackframe offsets .equ y, 12 .equ x, 8 .equ p, -4 .equ q, -8 .equ r, -12 .global gcd # make entry-point visible .section .text #------------------------------------------------------------------ gcd: # function's prototype: extern int gcd( int x, int y ); push %ebp mov %esp, %ebp sub $12, %esp push %edx # assignment: p = abs( x ); mov x(%ebp), %eax cdq xor %edx, %eax sub %edx, %eax mov %eax, p(%ebp) # assignment: q = abs( y ); mov y(%ebp), %eax cdq xor %edx, %eax sub %edx, %eax mov %eax, q(%ebp) # loop: while ( q != 0 ) again: cmpl $0, q(%ebp) je finis # assignment: r = p % q; mov p(%ebp), %eax xor %edx, %edx divl q(%ebp) mov %edx, r(%ebp) # assignment: p = q; mov q(%ebp), %eax mov %eax, p(%ebp) # assignment: q = r; mov r(%ebp), %eax mov %eax, q(%ebp) jmp again finis: mov p(%ebp), %eax pop %edx mov %ebp, %esp pop %ebp ret #------------------------------------------------------------------ .end