Difference between revisions of "CSC231 Homework 5 2014"
(→Problem #2) |
(→Problem #2) |
||
(16 intermediate revisions by the same user not shown) | |||
Line 106: | Line 106: | ||
add eax, eax | add eax, eax | ||
pop ebp | pop ebp | ||
− | ret | + | ret 4 |
</source> | </source> | ||
<br /> | <br /> | ||
+ | |||
==Assembly/Link Steps== | ==Assembly/Link Steps== | ||
<br /> | <br /> | ||
Line 129: | Line 130: | ||
The advantage of this setup is that if we put several functions in a separate file, they can become a nice collection of utility functions, and serve as a library. This is what we are doing with 231Lib.asm, containing _printDec, _println, and _printString. | The advantage of this setup is that if we put several functions in a separate file, they can become a nice collection of utility functions, and serve as a library. This is what we are doing with 231Lib.asm, containing _printDec, _println, and _printString. | ||
<br /> | <br /> | ||
− | The second advantage is that I can test your functions by linking them to my own test program. | + | The second advantage is that I can test your functions by linking them to my own test program. My test program can easily exercise your functions, and subject them to different conditions, and see whether the functions modify registers, and which ones. |
+ | <br /> | ||
+ | |||
+ | <br /> | ||
<br /> | <br /> | ||
=Problem #1= | =Problem #1= | ||
<br /> | <br /> | ||
− | Write a program called Hw5_1.asm that contains 1 function called | + | Write a program called Hw5_1.asm that contains 1 function called '''f1''' that will compute f1( x ) = (3 * x) - 1, and returns the result in eax. |
− | Use f.asm above as an example. Your program cannot contain a main program with a label _start. You have to create | + | Use f.asm above as an example. Your program cannot contain a main program with a label _start. You have to create your own main program to test your function. |
+ | |||
+ | Your function cannot modify any of the registers besides eax. | ||
You only submit Hw5_1.asm to Moodle, and keep your test program. | You only submit Hw5_1.asm to Moodle, and keep your test program. | ||
<br /> | <br /> | ||
+ | |||
=Problem #2= | =Problem #2= | ||
<br /> | <br /> | ||
Write a program called Hw5_2.asm that contains 1 function called '''f2''' that computes f2( x ) = x + (x-1) + (x-2) + ... + 2 + 1, and returns the result in eax. We assume that x will always be strictly positive, and your function does not have to deal with negative numbers. | Write a program called Hw5_2.asm that contains 1 function called '''f2''' that computes f2( x ) = x + (x-1) + (x-2) + ... + 2 + 1, and returns the result in eax. We assume that x will always be strictly positive, and your function does not have to deal with negative numbers. | ||
+ | <br /> | ||
+ | Examples: | ||
+ | |||
+ | f(1) = 1 | ||
+ | f(2) = 2+1 = 3 | ||
+ | f(3) = 3+2+1 = 6 | ||
+ | f(4) = 4+3+2+1 = 10 | ||
+ | f(5) = 5+4+3+2+1 = 15 | ||
+ | etc. | ||
− | Submit your program to Moodle, and keep your test program. | + | Your function cannot modify any of the registers besides eax. |
+ | |||
+ | Submit your Hw5_2.asm program to Moodle, and keep your test program. | ||
<br /> | <br /> | ||
Line 149: | Line 167: | ||
<br /> | <br /> | ||
Write a program called Hw5_3.asm that contains 2 functions, '''f3''' and '''f4''', defined as follows: | Write a program called Hw5_3.asm that contains 2 functions, '''f3''' and '''f4''', defined as follows: | ||
− | * f3( x ) = 2 x + | + | * f3( x, y ) = 2 x + 3 y |
− | * f4( x ) = 3 f3( x ) + f3( x-1 ) | + | * f4( x ) = 3 f3( x, 3 ) + f3( x-1, x+1 ) |
+ | |||
+ | Your functions cannot modify any of the registers besides eax. for f3, x is pushed first, then y, when the function is called | ||
Submit your program to Moodle, and keep your test program. | Submit your program to Moodle, and keep your test program. | ||
<br /> | <br /> | ||
+ | |||
=Problem #4= | =Problem #4= | ||
<br /> | <br /> | ||
Line 160: | Line 181: | ||
* f6( x ) = f5( x ) + f5( x-1 ) + f5( x-2 ) + ... + f5( 2 ) + f5( 1 ) | * f6( x ) = f5( x ) + f5( x-1 ) + f5( x-2 ) + ... + f5( 2 ) + f5( 1 ) | ||
+ | Your functions cannot modify any of the registers besides eax. | ||
− | Submit your program to Moodle, and keep your test program. | + | Submit your Hw5_4.asm program to Moodle, and keep your test program. |
+ | <br /> | ||
<br /> | <br /> | ||
+ | |||
+ | =Testing & Verifying with Python= | ||
<br /> | <br /> | ||
+ | If you implement the functions in Python and test them for specific values, this is what they output: | ||
<br /> | <br /> | ||
+ | ::<source lang="text"> | ||
+ | f1( 3 ) = 8 | ||
+ | f2( 10 ) = 55 | ||
+ | f3( 5, 7 ) = 31 | ||
+ | f4( 5 ) = 83 | ||
+ | f5( 10 ) = 55 | ||
+ | f6( 5 ) = 35 | ||
+ | </source> | ||
<br /> | <br /> | ||
+ | |||
+ | <!-- | ||
+ | =Python Version= | ||
<br /> | <br /> | ||
+ | ::<source lang="python"> | ||
+ | |||
+ | # f1( x ) = (3 * x) - 1 | ||
+ | def f1( x ): | ||
+ | return 3*x - 1 | ||
+ | |||
+ | # f2( x ) = x + (x-1) + (x-2) + ... + 2 + 1 | ||
+ | def f2( x ): | ||
+ | sum = 0 | ||
+ | for i in range( x ): | ||
+ | sum += i+1 | ||
+ | return sum | ||
+ | |||
+ | # f3( x, y ) = 2 x + 3 y | ||
+ | # f4( x ) = 3 f3( x, 3 ) + f3( x-1, x+1 ) | ||
+ | def f3( x, y ): | ||
+ | return 2*x + 3*y | ||
+ | |||
+ | def f4( x ): | ||
+ | return 3* f3( x, 3) + f3( x-1, x+1 ) | ||
+ | |||
+ | |||
+ | # f5( x ) = x + (x-1) + (x-2) + ... + 2 + 1 | ||
+ | # f6( x ) = f5( x ) + f5( x-1 ) + f5( x-2 ) + ... + f5( 2 ) + f5( 1 ) | ||
+ | def f5( x ): | ||
+ | return f2( x ) | ||
+ | |||
+ | def f6( x ): | ||
+ | sum = 0 | ||
+ | for i in range( x ): | ||
+ | sum += f5( i+1 ) | ||
+ | return sum | ||
+ | |||
+ | |||
+ | print( "f1( %d ) = %d" % ( 3, f1( 3 ) ) ) | ||
+ | print( "f2( %d ) = %d" % ( 10, f2( 10 ) ) ) | ||
+ | print( "f3( %d, %d ) = %d" % ( 5, 7, f3( 5, 7 ) ) ) | ||
+ | print( "f4( %d ) = %d" % ( 10, f4( 10 ) ) ) | ||
+ | print( "f5( %d ) = %d" % ( 10, f5( 10 ) ) ) | ||
+ | print( "f6( %d ) = %d" % ( 5, f6( 5 ) ) ) | ||
+ | |||
+ | </source> | ||
+ | <br /> | ||
+ | ==Output== | ||
+ | <br /> | ||
+ | |||
+ | f1( 3 ) = 8 | ||
+ | f2( 10 ) = 55 | ||
+ | f3( 5, 7 ) = 31 | ||
+ | f4( 10 ) = 138 | ||
+ | f5( 10 ) = 55 | ||
+ | f6( 5 ) = 35 | ||
+ | |||
<br /> | <br /> | ||
+ | --> | ||
<br /> | <br /> | ||
<br /> | <br /> |
Latest revision as of 20:02, 1 November 2014
--D. Thiebaut (talk) 07:30, 29 October 2014 (EDT)
Contents
Preparation
The two programs below illustrate how you would put a function, f(), in a separate file, and call it from a main() program kept in another file.
The specific details that are important and that make the system work:
- there is only one global _start label, and it is in main. The linker (ld) will complain if there are more than one _start label, as it is where Linux will start running your program.
- The label f in f.asm must be global, so that example.asm can access it.
- The label f in example.asm must be extern, so that nasm will not complain that it is not finding the label f used in the call instruction.
- Both example.asm and f.asm should be assembled separately, and linked together with the 231Lib library.
Example.asm
;;; ; example.asm ;;; ; D. Thiebaut ;;; ; ;;; ; A simple program to demonstrate how to link a main ;;; ; program and an extern function. ;;; ; ;;; ; to assemble and run: ;;; ; ;;; ; nasm -f elf -F stabs example.asm ;;; ; nasm -f elf -F stabs f.asm ;;; ; ld -melf_i3896 -o example example.o f.o 231Lib.o ;;; ; ./example ;;; ; ------------------------------------------------------------------- ;;; ------------------------------------------------------------ ;;; data areas ;;; ------------------------------------------------------------ section .data a dd 100 b dd 200 c dd 300 result dd 0 ;;; ------------------------------------------------------------ ;;; code area ;;; ------------------------------------------------------------ section .text global _start extern _printDec extern _println extern f _start: ;;; compute f( a ) = 2*a push dword[a] call f call _printDec call _println ;;; compute f( 3 ) = 2*3 = 6 push dword 3 call f call _printDec call _println ;;; compute f( b + f (c) + 1 ) push dword[c] call f inc eax add eax, dword[b] push eax call f call _printDec call _println ;;; exit() mov eax,1 mov ebx,0 int 0x80 ; final system call
f.asm
;;; ; f.asm
;;; ; D. Thiebaut
;;; ; A simple program with one global function that computes
;;; ; f(a) = 2*a
;;; ;
;;; ; -----------------------------------------------------------
section .text
global f
;;; ;------------------------------------------------------------
;;; ; f(x): a function that receives a parameter through
;;; ; the stack and that computes y = 2*x
;;; ; x is at [ebp+8]
;;; ; returns the result in eax.
;;; ; does not modify any of the other registers (besides eax)
;;; ;------------------------------------------------------------
f: push ebp
mov ebp, esp
mov eax, dword[ebp+8]
add eax, eax
pop ebp
ret 4
Assembly/Link Steps
nasm -f elf example.asm nasm -f elf f.asm nasm -f efl 231Lib.asm ld -melf_i386 example.o f.o 231Lib.o -o example
Output
200 6 1602
Advantages
The advantage of this setup is that if we put several functions in a separate file, they can become a nice collection of utility functions, and serve as a library. This is what we are doing with 231Lib.asm, containing _printDec, _println, and _printString.
The second advantage is that I can test your functions by linking them to my own test program. My test program can easily exercise your functions, and subject them to different conditions, and see whether the functions modify registers, and which ones.
Problem #1
Write a program called Hw5_1.asm that contains 1 function called f1 that will compute f1( x ) = (3 * x) - 1, and returns the result in eax.
Use f.asm above as an example. Your program cannot contain a main program with a label _start. You have to create your own main program to test your function.
Your function cannot modify any of the registers besides eax.
You only submit Hw5_1.asm to Moodle, and keep your test program.
Problem #2
Write a program called Hw5_2.asm that contains 1 function called f2 that computes f2( x ) = x + (x-1) + (x-2) + ... + 2 + 1, and returns the result in eax. We assume that x will always be strictly positive, and your function does not have to deal with negative numbers.
Examples:
f(1) = 1 f(2) = 2+1 = 3 f(3) = 3+2+1 = 6 f(4) = 4+3+2+1 = 10 f(5) = 5+4+3+2+1 = 15 etc.
Your function cannot modify any of the registers besides eax.
Submit your Hw5_2.asm program to Moodle, and keep your test program.
Problem #3
Write a program called Hw5_3.asm that contains 2 functions, f3 and f4, defined as follows:
- f3( x, y ) = 2 x + 3 y
- f4( x ) = 3 f3( x, 3 ) + f3( x-1, x+1 )
Your functions cannot modify any of the registers besides eax. for f3, x is pushed first, then y, when the function is called
Submit your program to Moodle, and keep your test program.
Problem #4
Write a program called Hw5_4.asm that contains 2 functions, f5, and f6, defined as follows:
- f5( x ) = x + (x-1) + (x-2) + ... + 2 + 1
- f6( x ) = f5( x ) + f5( x-1 ) + f5( x-2 ) + ... + f5( 2 ) + f5( 1 )
Your functions cannot modify any of the registers besides eax.
Submit your Hw5_4.asm program to Moodle, and keep your test program.
Testing & Verifying with Python
If you implement the functions in Python and test them for specific values, this is what they output:
f1( 3 ) = 8 f2( 10 ) = 55 f3( 5, 7 ) = 31 f4( 5 ) = 83 f5( 10 ) = 55 f6( 5 ) = 35