CSC231 Homework 8 Fall 2017
--D. Thiebaut (talk) 13:57, 27 November 2017 (EST)
Contents
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?