//---------------------------------------------------------------- // gcd.s // // Here are our hand-crafted assembly language instructions // for an alternative version of the 'gcd' function that is // more efficient than the code generated via compiler gcc. // // assemble using: $ as gcd.s -o gcd.o // // programmer: ALLAN CRUSE // written on: 29 MAR 2006 //---------------------------------------------------------------- .section .text gcd: # C language prototype: int gcd( int m, int n ); push %ebp # preserve frame-pointer mov %esp, %ebp # setup stackframe acess sub $12, %esp # allocate local storage push %edx # save clobbered register mov 8(%ebp), %eax # get the value of m cdq # sign-extend value xor %edx, %eax # maybe flip the bits sub %edx, %eax # and maybe add 1 mov %eax, -4(%ebp) # store p = abs( m ) mov 12(%ebp), %eax # get the value of n cdq # sign-extend value xor %edx, %eax # maybe flip the bits sub %edx, %eax # and maybe add 1 mov %eax, -8(%ebp) # store q = abs( n ) while: cmpl $0, -8(%ebp) # does q equal zero? je until # yes, skip loop body mov -4(%ebp), %eax # setup p as numerator xor %edx, %edx # zero-extend p to quad divl -8(%ebp) # divide by value of q mov %edx, -12(%ebp) # save remainder as r mov -8(%ebp), %eax # fetch from q mov %eax, -4(%ebp) # store into p mov -12(%ebp), %eax # fetch from r mov %eax, -8(%ebp) # store into q jmp while # go back to while until: mov -4(%ebp), %eax # setup p as return-value pop %edx # restore clobbered register leave # discard local storage ret # return to caller .global gcd # make entry-point visible .end # nothing more to assemble