Difference between revisions of "CSC231 Homework 8 Fall 2017"

From dftwiki3
Jump to: navigation, search
Line 165: Line 165:
 
<br />
 
<br />
 
<br />
 
<br />
 +
=Problem 2=
 +
<br />
 +
==Java Program==
 +
<br />
 +
::<source lang="java">
 +
/*
 +
Series.java
 +
Homework program with a recursive function.
 +
*/
 +
 +
class Series {
 +
 +
    /**
 +
      sumNSquared: returns the sum 1 + 2*2 + 3*3 + 4*4 +... + n*n
 +
      The computation is done recursively.
 +
    */
 +
    private static int sumNSquared( int n ) {
 +
 +
if ( n <= 1 ) return 1;
 +
return n*n + sumNSquared( n-1 );
 +
    }
 +
 +
    public static void main( String args[] ) {
 +
int n =  Integer.parseInt ( args[0] );
 +
System.out.print( "sumNSquared(" + n + ")=" + sumNSquared(n) +"\n\n" );
 +
    }
 +
}
 +
 +
</source>
 +
<br />
 +
==Example==
 +
<br />
 +
::<source lang="text">
 +
cs231a@aurora ~ $ javac Series.java
 +
cs231a@aurora ~ $ java Series 1
 +
sumNSquared(1)=1
 +
 +
cs231a@aurora ~ $ java Series 2
 +
sumNSquared(2)=5
 +
 +
cs231a@aurora ~ $ java Series 10
 +
sumNSquared(10)=385
 +
 +
cs231a@aurora ~ $ java Series 100
 +
sumNSquared(100)=338350
 +
 +
 +
</source>
 +
<br />
 +
==Questions==
 +
<br />
 +
Please answer the following questions on Moodle:
 +
<br />
 +
;Question 1
 +
:What number provided on the command line will generate an overflow of the result?
 +
 +
;Question 2
 +
:Will the Java Virtual Machine crash when an overflow of the result occurs in the program?
 +
 +
;Question 3
 +
: How many recursive calls will take place before a stack overflow error occurs?
 +
 +
 +
  
 
<!-- ==================================================================== -->
 
<!-- ==================================================================== -->

Revision as of 15:20, 27 November 2017

--D. Thiebaut (talk) 13:57, 27 November 2017 (EST)





Problem #1


Write an assembly program called hw8a.asm that contains several functions, but no main program. The main program will be in a separate file, that will be assembled separately, and linked to your program to create an executable file.

The functions should behave as follows:

  • f1( s ). Receives the address of a string s in the stack, and converts the string to uppercase, replacing all the alphabetic characters in the string to uppercase. We assume that the string, as in C, is terminated by a '\0' char. Here is an example of how to call the function:
s1          db       "Hello world!", 0
s1Len       equ      $-s1

 ...

             mov     eax, s1
             push    eax
             call    f1

             mov    ecx, s1
             mov    edx, s1Len-1    ; figure out why the -1!
             mov    eax, 4
             mov    ebx, 1
             int    0x80
The code above will print "HELLO WORLD!"


  • f2(a, b, c): f2 receives 3 integer parameters in the stack and computes 2a + 3b -c and returns this value in eax.
Here is an example of how to call the function:
a           dd       3
b           dd       5
c           dd       7

 ...
             push    dword[a]
             push    dword[b]
             push    dword[c]
             call    f2
             
; upon return from f2, eax will contain 2a + 3b - c = 2*3 + 3*5 - 7 = 14


  • f3( table, n ): this function receives in the stack the address of an array of ints, and the number of ints in the array. It returns in eax the number of even ints in the array. f3 should not modify any of the other registers, besides eax, of course!
Here is an example of how to call the function f3:
array     dd       3, 5, 0, 1, 2, 10, 100, 4, 1
arrayLen  equ      ($-array)/4                      ; figure out the /4 part.


 ...
             mov     eax, array
             push    eax
             mov     eax, arrayLen
             push    eax
             call    f3
             ; upon return from f3, eax contains 5, because there are 5 even numbers in array.


Making Your Functions Known to Other Programs


Your hw8a.asm program should contain only the 3 functions described above. No need for a data segment or for a _Start label. However, you need to make your functions known to the main program that is in a different file, and that will be linked with your program. So you need to add these 3 lines at the top of your program:

           global f1
           global f2
           global f3


Testing Your Code


Create the following program and call it test.asm. It will be the test program for your hw8b.asm program:

;;;------------------------------------------------------------
;;; test.asm     
;;; tests the functions in hw8_2.asm by calling each one
;;; and printing its result.
;;;------------------------------------------------------------
	extern	_printString
	extern	_println
	extern 	_printDec

	extern	f1        ; f1, f2, and f3 are declared somewhere else
	extern  f2
	extern	f3

;;;------------------------------------------------------------
;;; some variables to pass to the functions
;;;------------------------------------------------------------
	 section .data
s1	 db	 "Hello there! 12345", 0
s1Len	 equ	 $-s1
Table	 dd	 1, 2, 3, 30, 100, 200
TableLen equ	 ($-Table)/4
x1	 dd	 10
x2	 dd	 20
x3	 dd	 -1

;;;------------------------------------------------------------
;;; main program
;;;------------------------------------------------------------
	 section .text
	 global	 _start
_start:
;;; test f1
	 mov	 eax, s1	; pass s1 to f1
	 push	 eax
	 call	 f1
	 mov	 ecx, s1
	 mov	 edx, s1Len
	 call	 _printString
	 call	 _println
	
;;; test f2
	 push	dword[x1]	; pass x1, x2, x3 to f2
	 push	dword[x2]
	 push	dword[x3]
	 call	f2
	 call	_printDec
	 call	_println

;;; test f3
	 mov	eax, Table	; pass Table and length to f3
	 push	eax
	 mov	eax, TableLen
	 push	eax
	 call	f3
	 call	_printDec
	 call	_println
	
;;; ; exit
	mov     ebx, 0
	mov     eax, 1
	int     0x80


  • Assemble, link, and run as follows:
231b@aurora ~ nasm -f elf test.asm
231b@aurora ~ nasm -f elf hw8a.asm
231b@aurora ~ nasm -f elf 231Lib.asm
231b@aurora ~ ld -melf_i386  -o test test.o hw8a.o 231Lib.o
231b@aurora ~ ./test
HELLO THERE! 12345
81
4

Note
The test program above does not check whether f3 modifies the ebx, ecx, edx, esi, or edi registers. You can verify this yourself (maybe by printing the registers before and after the call to f3)!



Problem 2


Java Program


/*
Series.java
Homework program with a recursive function.
*/

class Series {

    /**
       sumNSquared: returns the sum 1 + 2*2 + 3*3 + 4*4 +... + n*n
       The computation is done recursively.
     */
    private static int sumNSquared( int n ) {
	
	if ( n <= 1 ) return 1;
	return n*n + sumNSquared( n-1 );
    }

    public static void main( String args[] ) {
	int n =  Integer.parseInt ( args[0] );
	System.out.print( "sumNSquared(" + n + ")=" + sumNSquared(n) +"\n\n" );
    }
}


Example


cs231a@aurora ~ $ javac Series.java 
cs231a@aurora ~ $ java Series 1
sumNSquared(1)=1

cs231a@aurora ~ $ java Series 2
sumNSquared(2)=5

cs231a@aurora ~ $ java Series 10
sumNSquared(10)=385

cs231a@aurora ~ $ java Series 100
sumNSquared(100)=338350


Questions


Please answer the following questions on Moodle:

Question 1
What number provided on the command line will generate an overflow of the result?
Question 2
Will the Java Virtual Machine crash when an overflow of the result occurs in the program?
Question 3
How many recursive calls will take place before a stack overflow error occurs?




...