Difference between revisions of "CSC231 Homework 4 2012"

From dftwiki3
Jump to: navigation, search
(Created page with "--~~~~ ---- =Preparation for the Homework= <Font color="magenta">Important Note: this problem must be done on '''grendel.csc.smith.edu''', as it requires a 32-bit machine, while...")
 
(Ingrendient #2: A Mini Library in Assembly)
 
(8 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
--[[User:Thiebaut|D. Thiebaut]] 12:51, 26 September 2012 (EDT)
 
--[[User:Thiebaut|D. Thiebaut]] 12:51, 26 September 2012 (EDT)
 
----
 
----
 +
<br />
 +
<tanbox>
 +
This assignment is due on October 3rd, in the evening, at midnight.
 +
</tanbox>
 +
<br />
 +
__TOC__
 +
<br />
 
=Preparation for the Homework=
 
=Preparation for the Homework=
  
Line 32: Line 39:
 
* All it does is have a main program that calls a function '''asm_main()''', which will be the entry point of our assembly language program.
 
* All it does is have a main program that calls a function '''asm_main()''', which will be the entry point of our assembly language program.
  
==Ingrendient #2: A Mini Library in Assembly==
+
==Ingredient #2: A Mini Library in Assembly==
 
* Next get a small library that will provide a simple interface between this C program and our assembly language program.<br /><br />
 
* Next get a small library that will provide a simple interface between this C program and our assembly language program.<br /><br />
 
** [[CSC231_asm_io.asm | asm_io.asm]]<br /><br />
 
** [[CSC231_asm_io.asm | asm_io.asm]]<br /><br />
Line 41: Line 48:
 
   
 
   
 
       nasm -f elf -F stabs asm_io.asm
 
       nasm -f elf -F stabs asm_io.asm
 
  
 
==Ingredient #3: Your Assembly Program that uses the new Library==
 
==Ingredient #3: Your Assembly Program that uses the new Library==
* Now enter the test program below in assembly. Call it '''hw5test.asm'''. Be careful that it is slightly different from the ones we have been writing so far in that''' the starting label and the last instructions are not the standard ones'''.
+
* Now enter the test program below in assembly. Call it '''hwtest.asm'''. Be careful that it is slightly different from the ones we have been writing so far in that''' the starting label and the last instructions are not the standard ones'''.
  
       ;;; hw5test.asm
+
       ;;; hwtest.asm
 
       ;;; a simple demo program to test I/O with
 
       ;;; a simple demo program to test I/O with
 
       ;;; a C "wrapper" program
 
       ;;; a C "wrapper" program
Line 105: Line 111:
 
* To assemble and run your program just follow these steps:
 
* To assemble and run your program just follow these steps:
  
             nasm -f elf -F stabs hw5test.asm
+
             nasm -f elf -F stabs hwtest.asm
             gcc -o hw5test driver.c asm_io.o hw5test.o  
+
             gcc -m32 -o hwtest driver.c asm_io.o hwtest.o  
             ./hw5test
+
             ./hwtest
 
   
 
   
 
             Hello! Please enter an integer number: 1234
 
             Hello! Please enter an integer number: 1234
Line 113: Line 119:
  
  
* The first line assembles hw5test.asm. The second line asks the C compiler '''gcc''' to compile '''driver.c''' and to link it with the object files '''asm_io.o''' and '''hw2test.o''', and to store the executable in a file called '''hw5test'''. The last line executes the program.
+
* The first line assembles hwtest.asm. The second line asks the C compiler '''gcc''' to compile '''driver.c''' and to link it with the object files '''asm_io.o''' and '''hwtest.o''', and to store the executable in a file called '''hwtest'''. The '''-m32''' switch instructs the compiler to keep all the executable compatible with 32-bit processors.  The last line executes the program.
  
* The functions provided by the asm_io.o library are described now:<br /><br />
+
* The functions provided by the '''asm_io.o''' library are described now:<br /><br />
 
** '''read_int''': reads an integer from the keyboard and stores it into the EAX register.<br /><br />
 
** '''read_int''': reads an integer from the keyboard and stores it into the EAX register.<br /><br />
 
** '''print_int''': prints out in 2's complement the value of the integer stored in EAX on the screen.<br /><br />
 
** '''print_int''': prints out in 2's complement the value of the integer stored in EAX on the screen.<br /><br />
Line 122: Line 128:
 
** '''read_char''': reads a single character from the keyboard and stores its ASCII code into the EAX register.<br /><br />
 
** '''read_char''': reads a single character from the keyboard and stores its ASCII code into the EAX register.<br /><br />
 
** '''print_nl''': prints out to the screen a new line character. <br /><br />
 
** '''print_nl''': prints out to the screen a new line character. <br /><br />
** The '''asm_io''' library supports also two ''macros'' that you may find useful: ''dump_regs'' and ''dump_mem''. They can be used to display the contents of the registers and the contents of memory. Try adding these two lines at the end of your '''hw5test.asm''' program:
+
** The '''asm_io''' library supports also two ''macros'' that you may find useful: ''dump_regs'' and ''dump_mem''. They can be used to display the contents of the registers and the contents of memory. Try adding these two lines at the end of your '''hwtest.asm''' program:
  
 
   
 
   
Line 140: Line 146:
 
<br />
 
<br />
  
=Exercise=
+
=Problem #1=
  
* Create a new program called '''lab5.asm''' and make it compute the first 8 fibonacci terms using a loop.  Make it store the terms in an array of words.
+
Write a program called hw4a.asm that computes and prints the first 10 32-bit Fibonacci terms.
  
* Link your assembly code to the '''asm_io''' library the same way you did above, and make it display all the registers and the contents of the array in memory at every step of the loop.
+
Use the method above to link your program with the driver.c, asm_io.inc and asm_io.asm programs.
 +
 
 +
You need to store the 10 Fibonacci terms in an array of ints that is initially filled with 0 when the program starts.
 +
 
 +
The output of your program should be something like this:
 +
 
 +
1
 +
1
 +
2
 +
3
 +
5
 +
8
 +
13
 +
21
 +
34
 +
55
 +
 
 +
Don't use loops (unless you are too tempted to do so!)
 +
 
 +
==Submission==
 +
 
 +
  rsubmit hw4 hw4a.asm
 +
 
 +
You do not need to submit the other programs (driver.c, asm_io.asm, or asm_io.inc).
 +
 
 +
=Problem #2=
 +
 
 +
Same problem, but with a twist.  Now the integers are 16-bit words, stored in an array of words.
 +
 
 +
Your program, called hw4b.asm, will have the same output as shown above.
 +
 
 +
==Submission ==
 +
 
 +
  rsubmit hw4 hw4b.asm
 +
 
 +
=Problem #3=
 +
 
 +
Let's modify the Fibonacci series and make it a bit more convoluted:
 +
 
 +
  F<sub>1</sub> = 1
 +
 +
  F<sub>2</sub> = 1
 +
 +
  F<sub>n</sub> = F<sub>n-1</sub> * 2 + F<sub>n-2</sub> - 1
 +
 
 +
Write a program called '''hw4c.asm''' that computes and prints the first 10 terms of this series.
 +
 
 +
==Requirements==
 +
 
 +
The numbers are coded as 16-bit words.
 +
 
 +
The numbers are not stored in memory and are computed only in registers.
 +
 
 +
Your program will use driver.c, asm_io.asm, and asm_io.inc.
 +
 
 +
The output of your program should be:
 +
 
 +
1 1
 +
2 1
 +
3 2
 +
4 4
 +
5 9
 +
6 21
 +
7 50
 +
8 120
 +
9 289
 +
10 697
 +
 
 +
==Submission==
 +
 
 +
Submit your program as follows:
 +
 
 +
rsubmit hw4 hw4c.asm
 +
 
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 +
[[Category:CSC231]][[Category:Homework]]
 
<br />
 
<br />
  

Latest revision as of 18:04, 9 October 2012

--D. Thiebaut 12:51, 26 September 2012 (EDT)



This assignment is due on October 3rd, in the evening, at midnight.



Preparation for the Homework

Important Note: this problem must be done on grendel.csc.smith.edu, as it requires a 32-bit machine, while beowulf is a 64-bit machine. This has to do with mixing assembly (generated in 32-bit mode) and C-programs (compiled in 64-bit on beowulf, and in 32-bit on grendel).

While printing strings of characters on the screen is relatively easy in assembly, as you saw in the previous assignment and exercises, inputing numbers and printing numbers is more difficult in assembly (we'll see why in class later).

So, for the time being, to deal with the input/output of integers we will use a trick: we will link our assembly language program to a C program, and make the C program handle the input and output of information for us.

Don't worry if you don't know C. We will not write a single line of C code except for the small C program which will never change.

When we want to print a number from our assembly program, or when we want to get a number from the keyboard, we simply call the appropriate C function from our assembly program. Because the linker will link our program with the C program, we can call functions written in another language from assembly. This is a useful programming trick!

It sounds complicated, but you'll see that it isn't that bad.

Ingredient #1: A C Program

  • Let's try this concept with a simple example:
  • First use your favorite editor to write the following C program and call it driver.c
     #include <stdio.h>

     extern int asm_main( void );

     int main() {
       asm_main();
     }


  • All it does is have a main program that calls a function asm_main(), which will be the entry point of our assembly language program.

Ingredient #2: A Mini Library in Assembly

  • Next get a small library that will provide a simple interface between this C program and our assembly language program.

  • Create the object file for the library:


     nasm -f elf -F stabs asm_io.asm

Ingredient #3: Your Assembly Program that uses the new Library

  • Now enter the test program below in assembly. Call it hwtest.asm. Be careful that it is slightly different from the ones we have been writing so far in that the starting label and the last instructions are not the standard ones.
     ;;; hwtest.asm
     ;;; a simple demo program to test I/O with
     ;;; a C "wrapper" program

     %include "asm_io.inc"

             ;; -------------------------
             ;; data segment
             ;; -------------------------
             section .data
     msg     db      "Hello! Please enter an integer number: ",0x00
     msg2    db      "You have entered ",0x00
     x       dd      0

             ;; -------------------------
             ;; code area
             ;; -------------------------
             section .text
             global  asm_main
     asm_main:       

             mov     eax,msg               ; pass address of the string msg in eax
             call    print_string          ; call a function in asm_io library
                                           ; that will print the string msg

             call    read_int              ; call a function that reads an
             mov     [x], eax              ; integer from the keyboard and
                                           ; returns it in eax.  Save returned
                                           ; value in variable x

             mov     eax,msg2              ; print the string msg2
             call    print_string          ; ("you have entered")

             mov     eax,[x]               ; get integer user entered
             call    print_int             ; pass it via eax and call the
                                           ; function specialized in printing
                                           ; integer numbers

             call    print_nl              ; call the function that prints
                                           ; a new blank line

             ;; return to C program

             ret
Note 1: The beginning of the program is not labeled _start any longer, but asm_main. The reason is that the start of the program is in the driver.c program, not in our assembly program. Also, the program does not end with an int 0x80 instruction any longer, but by a ret instruction, so that it can return to the C program which will end with its own (hidden) int 0x80.




Note 2: in C all strings of characters must be terminated by a 0 (0x00) byte. Because here we have used a C function to print the strings of characters, we added a 0x00 byte at the end of each string. Make sure that you add 0x00 at the end of all your strings of characters if you are going to use the method shown above to print your strings.



Compile and Link all the Parts Together!

  • To assemble and run your program just follow these steps:
            nasm -f elf -F stabs hwtest.asm
            gcc -m32 -o hwtest driver.c asm_io.o hwtest.o 
            ./hwtest

            Hello! Please enter an integer number: 1234
            You have entered 1234


  • The first line assembles hwtest.asm. The second line asks the C compiler gcc to compile driver.c and to link it with the object files asm_io.o and hwtest.o, and to store the executable in a file called hwtest. The -m32 switch instructs the compiler to keep all the executable compatible with 32-bit processors. The last line executes the program.
  • The functions provided by the asm_io.o library are described now:

    • read_int: reads an integer from the keyboard and stores it into the EAX register.

    • print_int: prints out in 2's complement the value of the integer stored in EAX on the screen.

    • print_string: prints out to the screen the contents of the string at the address stored in EAX. The string must be terminated by a 0x00 byte (C-string).

    • print_char: prints out to the screen the character whose ASCII value is stored in AL

    • read_char: reads a single character from the keyboard and stores its ASCII code into the EAX register.

    • print_nl: prints out to the screen a new line character.

    • The asm_io library supports also two macros that you may find useful: dump_regs and dump_mem. They can be used to display the contents of the registers and the contents of memory. Try adding these two lines at the end of your hwtest.asm program:


             call    print_nl              ; call the function that prints
                                           ; a new blank line

             dump_regs 1                   ; display registers, and use marker "1"
             dump_mem  1, msg, 3           ; display variable 'msg', mark it as "1"
                                           ; and display 3 lines of 16 bytes
              
             ;; return to C program
             ret
  • The first of the new lines dump_regs 1 dumps the registers and uses 1 as a label, so that if you use this macro several times in your program, you can label each one with a different number so that you can figure out from the output which macro actually output what. The second of the new lines dump_mem 1, msg, 3 output 3 lines of 16 bytes starting at the address corresponding to the variable msg, and uses 1 as the label for this output.



Problem #1

Write a program called hw4a.asm that computes and prints the first 10 32-bit Fibonacci terms.

Use the method above to link your program with the driver.c, asm_io.inc and asm_io.asm programs.

You need to store the 10 Fibonacci terms in an array of ints that is initially filled with 0 when the program starts.

The output of your program should be something like this:

1	
1	
2	
3	
5	
8	
13	 
21	
34	
55

Don't use loops (unless you are too tempted to do so!)

Submission

  rsubmit hw4 hw4a.asm

You do not need to submit the other programs (driver.c, asm_io.asm, or asm_io.inc).

Problem #2

Same problem, but with a twist. Now the integers are 16-bit words, stored in an array of words.

Your program, called hw4b.asm, will have the same output as shown above.

Submission

 rsubmit hw4 hw4b.asm

Problem #3

Let's modify the Fibonacci series and make it a bit more convoluted:

  F1 = 1

  F2 = 1

  Fn = Fn-1 * 2 + Fn-2 - 1

Write a program called hw4c.asm that computes and prints the first 10 terms of this series.

Requirements

The numbers are coded as 16-bit words.

The numbers are not stored in memory and are computed only in registers.

Your program will use driver.c, asm_io.asm, and asm_io.inc.

The output of your program should be:

1 1
2 1
3 2
4 4
5 9
6 21
7 50
8 120
9 289
10 697

Submission

Submit your program as follows:

rsubmit hw4 hw4c.asm