Difference between revisions of "CSC231 Homework 8 Fall 2017"
(→Problem #1: Programming in C) |
|||
Line 11: | Line 11: | ||
<br /> | <br /> | ||
<br /> | <br /> | ||
− | =Problem # | + | =Problem #1= |
<br /> | <br /> | ||
− | Write an assembly program called ''' | + | 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: | The functions should behave as follows: | ||
Line 49: | Line 49: | ||
call f2 | call f2 | ||
− | ; upon return from f2, eax | + | ; upon return from f2, eax will contain 2a + 3b - c = 2*3 + 3*5 - 7 = 14 |
</source> | </source> | ||
Line 72: | Line 72: | ||
==Making Your Functions Known to Other Programs== | ==Making Your Functions Known to Other Programs== | ||
<br /> | <br /> | ||
− | Your ''' | + | 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: |
<br /> | <br /> | ||
<br /> | <br /> | ||
Line 84: | Line 84: | ||
==Testing Your Code== | ==Testing Your Code== | ||
<br /> | <br /> | ||
− | Create the following program and call it test.asm. It will be the test program for your | + | Create the following program and call it test.asm. It will be the test program for your hw8b.asm program: |
<br /> | <br /> | ||
::<source lang="asm"> | ::<source lang="asm"> | ||
Line 153: | Line 153: | ||
231b@aurora ~ '''nasm -f elf test.asm''' | 231b@aurora ~ '''nasm -f elf test.asm''' | ||
− | 231b@aurora ~ '''nasm -f elf | + | 231b@aurora ~ '''nasm -f elf hw8a.asm''' |
231b@aurora ~ '''nasm -f elf 231Lib.asm''' | 231b@aurora ~ '''nasm -f elf 231Lib.asm''' | ||
− | 231b@aurora ~ '''ld -melf_i386 -o test test.o | + | 231b@aurora ~ '''ld -melf_i386 -o test test.o hw8a.o 231Lib.o''' |
231b@aurora ~ '''./test''' | 231b@aurora ~ '''./test''' | ||
HELLO THERE! 12345 | HELLO THERE! 12345 | ||
Line 162: | Line 162: | ||
;Note: | ;Note: | ||
− | : The test program above does not check | + | : 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'')! |
<br /> | <br /> | ||
<br /> | <br /> | ||
Line 188: | Line 188: | ||
<br /> | <br /> | ||
=Solution Program= | =Solution Program= | ||
+ | |||
==Problem 1== | ==Problem 1== | ||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
− | |||
<br /> | <br /> | ||
::<source lang="asm"> | ::<source lang="asm"> |
Revision as of 15:03, 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)!