# // D test program div_mod_loop.d CSE413 6/99, rev 5/00, rev 11/07 # # // Software division and mod, using repeated subtraction. # // read two positive numbers x and y, then print x/y and x%y # # // Assumes that negative numbers will not be entered. # // Repeatedly loops, enter a zero for the dividend to stop. # # // = a%b # int mod(int a, int b){ .text .globl d$main mod: # BEGINNING OF FUNCTION # return a - div(a,b)*b; # Function Prolog - 3 instructions pushl %ebp # save ebp and set up frame pointer movl %esp, %ebp # set frame ptr to pt. to top of stack subl $0, %esp # allocate local vars movl 12(%ebp), %eax # Using a pushl %eax # push previous value onto stack movl 12(%ebp), %eax # Using a pushl %eax # Push a parameter movl 8(%ebp), %eax # Using b pushl %eax # Push a parameter call div addl $8, %esp # pop params off stack pushl %eax # push previous value onto stack movl 8(%ebp), %eax # Using b popl %ecx # pop left operand from stack imull %ecx, %eax # multiply, final product in eax popl %ecx # pop left operand from stack subl %eax, %ecx # subtract, final result in ecx movl %ecx, %eax # move result to eax # Function Eplilog - 3 instructions movl %ebp, %esp # free local vars popl %ebp # restore frame pointer (ebp) ret # return to caller # } # # // = a div b for positive integers a, b # int div(int a,int b){ div: # BEGINNING OF FUNCTION # int div; # # div = 0; # Function Prolog - 3 instructions pushl %ebp # save ebp and set up frame pointer movl %esp, %ebp # set frame ptr to pt. to top of stack subl $4, %esp # allocate local vars movl $0, %eax # Using 0 movl %eax, -4(%ebp) # Storing div # while (a>b) { while_L1_1: # Beginning of the while loop movl 12(%ebp), %eax # Using a pushl %eax # push first expression onto stack movl 8(%ebp), %eax # Using b popl %ecx # pop first expression into ecx cmpl %eax, %ecx # compare two expressions jle while_L2_2 # a=a-b; movl 12(%ebp), %eax # Using a pushl %eax # push previous value onto stack movl 8(%ebp), %eax # Using b popl %ecx # pop left operand from stack subl %eax, %ecx # subtract, final result in ecx movl %ecx, %eax # move result to eax movl %eax, 12(%ebp) # Storing a # div=div+1; movl -4(%ebp), %eax # Using div pushl %eax # push previous value onto stack movl $1, %eax # Using 1 popl %ecx # pop left operand from stack addl %ecx, %eax # add, final result in eax movl %eax, -4(%ebp) # Storing div # } # if (a==b) jmp while_L1_1 # jump to top of while loop while_L2_2: # After the while loop movl 12(%ebp), %eax # Using a pushl %eax # push first expression onto stack movl 8(%ebp), %eax # Using b popl %ecx # pop first expression into ecx cmpl %eax, %ecx # compare two expressions jne if_L1_3 # div = div + 1; movl -4(%ebp), %eax # Using div pushl %eax # push previous value onto stack movl $1, %eax # Using 1 popl %ecx # pop left operand from stack addl %ecx, %eax # add, final result in eax movl %eax, -4(%ebp) # Storing div # return(div); if_L1_3: # Jump here if cond is false, end of ifstmt movl -4(%ebp), %eax # Using div # Function Eplilog - 3 instructions movl %ebp, %esp # free local vars popl %ebp # restore frame pointer (ebp) ret # return to caller # } # # int main(){ d$main: # BEGINNING OF FUNCTION # # int a;int b; int c; # # c = 0; # Function Prolog - 3 instructions pushl %ebp # save ebp and set up frame pointer movl %esp, %ebp # set frame ptr to pt. to top of stack subl $12, %esp # allocate local vars movl $0, %eax # Using 0 movl %eax, -4(%ebp) # Storing c # a = get(); // Get dividend call get addl $0, %esp # pop params off stack movl %eax, -12(%ebp) # Storing a # while (!(a == 0)) { while_L1_4: # Beginning of the while loop movl -12(%ebp), %eax # Using a pushl %eax # push first expression onto stack movl $0, %eax # Using 0 popl %ecx # pop first expression into ecx cmpl %eax, %ecx # compare two expressions je while_L2_5 # b = get(); // Get divisor call get addl $0, %esp # pop params off stack movl %eax, -8(%ebp) # Storing b # c = put ( div(a,b) ); // print a / b movl -12(%ebp), %eax # Using a pushl %eax # Push a parameter movl -8(%ebp), %eax # Using b pushl %eax # Push a parameter call div addl $8, %esp # pop params off stack pushl %eax # Push a parameter call put addl $4, %esp # pop params off stack movl %eax, -4(%ebp) # Storing c # c = put ( mod(a,b) ); // print a % b movl -12(%ebp), %eax # Using a pushl %eax # Push a parameter movl -8(%ebp), %eax # Using b pushl %eax # Push a parameter call mod addl $8, %esp # pop params off stack pushl %eax # Push a parameter call put addl $4, %esp # pop params off stack movl %eax, -4(%ebp) # Storing c # a = get(); // Enter 0 to stop call get addl $0, %esp # pop params off stack movl %eax, -12(%ebp) # Storing a # } # # // Returns zero if the last remainder was zero # // otherwise return -1. # if (c == 0) jmp while_L1_4 # jump to top of while loop while_L2_5: # After the while loop movl -4(%ebp), %eax # Using c pushl %eax # push first expression onto stack movl $0, %eax # Using 0 popl %ecx # pop first expression into ecx cmpl %eax, %ecx # compare two expressions jne if_L1_6 # return 0; movl $0, %eax # Using 0 # Function Eplilog - 3 instructions movl %ebp, %esp # free local vars popl %ebp # restore frame pointer (ebp) ret # return to caller # else { jmp if_L2_7 # jump to end of ifstmt if_L1_6: # Jump here if cond is false, else part of ifstmt # return 0-1; movl $0, %eax # Using 0 pushl %eax # push previous value onto stack movl $1, %eax # Using 1 popl %ecx # pop left operand from stack subl %eax, %ecx # subtract, final result in ecx movl %ecx, %eax # move result to eax # Function Eplilog - 3 instructions movl %ebp, %esp # free local vars popl %ebp # restore frame pointer (ebp) ret # return to caller # } # # } if_L2_7: # End of ifstmt #