CS 301 Homework 4 Solutions


Problem 1:

NetRun Link
/* C function prototype (C++ requires 'extern "C"' here; otherwise the same) */
int mul_vcheck(int a,int b);

__asm__( // Assembly subroutine
"mul_vcheck:\n"
" mov 4(%esp),%eax\n" // Load a into eax
" mov 8(%esp),%ebx\n" // Load b into ebx
" mul %ebx\n"
" jb overflow\n" // Jumps if CF is set
" ret\n" /* Normal return -- returns product eax */
"overflow:\n"
" mov $-1,%eax\n"
" ret\n" /* Return -1 on overflow */
);

unsigned int fact(unsigned int n) {
if (n<=1) return 1; /* fact(1)==1 */
else return mul_vcheck(n,fact(n-1)); /* fact(n)==n*fact(n-1) */
}

int foo(void) {
int i;
for (i=1;i<=20;i++) print_int(fact(i));
return 0;
}


Problem 2:

NetRun Link
extern "C" void sort_ints(int *arr,int n);

/* qsort-compatible comparison routine */
extern "C" int compare(int *a,int *b)
{ return *a-*b; }

__asm__( /* Assembly function body */
"sort_ints:\n"
" push %ebp\n"
" mov %esp,%ebp\n"
" push $compare\n"
" push $4\n"
" push 12(%ebp)\n" /* n */
" push 8(%ebp)\n" /* Arr */
" # call print_stack\n"
" call qsort\n"
" leave\n"
" ret\n"
);

int foo(void) {
int i,n=read_input();
int *arr=new int[n];
for (i=0;i<n;i++)
arr[i]=rand()&0xf;
sort_ints(arr,n);
for (i=0;i<n;i++)
std::cout<<i<<" = "<<arr[i]<<std::endl;
delete[] arr;
return 0;
}


Problem 3:

NetRun Link

fooextern "C" void add_ints(int *arr,int n);

__asm__( /* Assembly function body */
"add_ints:\n"
" mov 4(%esp),%eax\n" /* arr */
" mov 8(%esp),%ecx\n" /* n */
" mov $0,%ebx\n" /* i=0 */
" jmp Lcompare\n"
"Lstart:\n"
" add $100,(%eax,%ebx,4)\n" /* adds 100 to memory at eax+ebx*4 */
" inc %ebx\n" /* i++ */
"Lcompare:\n"
" cmp %ecx,%ebx\n" /* if i<n goto start */
" jl Lstart\n"
" ret\n"
);

int foo(void) {
int i,n=read_input();
int *arr=new int[n];
for (i=0;i<n;i++)
arr[i]=rand()&0xf;
add_ints(arr,n);
for (i=0;i<n;i++)
std::cout<<i<<" = "<<arr[i]<<std::endl;
delete[] arr;
return 0;
}

Problem 4:

NetRun Link
extern "C" int call_rdtsc(void);

__asm__(
"call_rdtsc:\n"
" rdtsc\n" /* Returns tsc in %eax (low) and %edx (high, ignored) */
" ret\n"
);

int foo(void) {
int t1=call_rdtsc();
int t2=call_rdtsc();
return t2-t1;
}