Difference between revisions of "CSC231 Homework 4 2014"

From dftwiki3
Jump to: navigation, search
(Helper Program 2)
 
(20 intermediate revisions by the same user not shown)
Line 26: Line 26:
 
'''N''' represents the total number of words in the string '''msg'''.
 
'''N''' represents the total number of words in the string '''msg'''.
  
Your assignment is to write a program that uses one or several loops that go ''N'' times and that print all the words on separate lines, one after the other, such that each word is '''capitalized''', i.e. its first letter is uppercase, and the others are lowercase.
+
Your assignment is to write a program, called '''Hw4_1.asm''', that uses one or several loops that go ''N'' times and that print all the words on separate lines, one after the other, such that each word is '''capitalized''', i.e. its first letter is uppercase, and the others are lowercase.
  
 +
If you observe the ASCII table, the difference between upper- and lower-case letters is always the same: 32.  So, if you have an uppercase character in '''al''' and want to make it lowercase, you can do this:
 
<br />
 
<br />
 +
<source lang="asm">
 +
          sub      al, 32
 +
</source>
 +
<br />
 +
Better yet, you can write this instruction in a much more self-documenting fashion:
 +
<br />
 +
<source lang="asm">
 +
          sub      al, 'a'-'A'         
 +
</source>
 +
<br />
 +
In this case you ask nasm to figure out the difference between lower and uppercase letters, and subtract that difference from al.  If al contained 'f', for example, then, after the sub instruction, it will contain 'F'.
 +
<br />
 +
Feel free to use the 231Lib.asm library for printing strings.
 +
<br />
 +
 
==Submission==
 
==Submission==
 
<br />
 
<br />
 
Submit your program in Moodle's '''Homework 4, Problem 1''' section.
 
Submit your program in Moodle's '''Homework 4, Problem 1''' section.
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 
<br />
 
<br />
  
Line 62: Line 82:
 
<br />
 
<br />
  
 +
<br />
 +
<br />
 +
<br />
 
=Problem #3=
 
=Problem #3=
 
<br />
 
<br />
Take your solution program (or my solution program) for [[CSC231_Homework_3_2014#Problem_.235| Homework 3, Problem  5]], and rewrite it so that it uses functions.
+
Take your solution program (or my solution program) for [[CSC231_Homework_3_2014#Problem_.235| Homework 3, Problem  5]], and rewrite it (call it '''Hw4_3.asm'''), and this time make it use functions.
 
<br />
 
<br />
 
Your solution program should have several functions:
 
Your solution program should have several functions:
Line 70: Line 93:
 
* One function called '''printLn''' that prints a new-line character (0x0a).  It will replace our ''_println'' function.  Your function must use '''int 0x80''' to print the 0x0a char.  Your function '''should not''' call _println!  ''printLn'' does not receive any parameter through registers, and must save all the registers it uses.  In other words, when we return from printLn, all the registers will contain the same values they had before we called the function.
 
* One function called '''printLn''' that prints a new-line character (0x0a).  It will replace our ''_println'' function.  Your function must use '''int 0x80''' to print the 0x0a char.  Your function '''should not''' call _println!  ''printLn'' does not receive any parameter through registers, and must save all the registers it uses.  In other words, when we return from printLn, all the registers will contain the same values they had before we called the function.
 
* One function called '''printMsg''' that prints a string on the screen.  ''printMsg'' will replace our ''_printString'' function.  Your function must use '''int 0x80''' to print the string.  It will get the address of the string to print in ''ecx'' and the number of characters in the string in ''edx''.  This function should '''not''' call ''_printString''.  It must use the ''int 0x80'' instruction.
 
* One function called '''printMsg''' that prints a string on the screen.  ''printMsg'' will replace our ''_printString'' function.  Your function must use '''int 0x80''' to print the string.  It will get the address of the string to print in ''ecx'' and the number of characters in the string in ''edx''.  This function should '''not''' call ''_printString''.  It must use the ''int 0x80'' instruction.
* One function called '''printFibMsg''' that gets a number in eax and prints the string  ''Fibonacci(###)'' where ''###'' is the decimal value of the number in eax.  You should call '''_printDec''' inside ''printFibMsg'' to print the number passed in eax.
+
* One function called '''printFibMsg''' that gets a number in eax and prints the string  ''Fibonacci(###) = '' where ''###'' is the decimal value of the number in eax.  You should call '''_printDec''' inside ''printFibMsg'' to print the number passed in eax.
 
Your ''printFibMsg'' function should save all the registers it modifies and should return them to their original values.
 
Your ''printFibMsg'' function should save all the registers it modifies and should return them to their original values.
 +
<br />
 +
==Restrictions==
 +
<br />
 +
* You can only use the _printDec library function in your program.  No other function from the 231Lib.asm library should be used.
 
<br />
 
<br />
 
==Submission==
 
==Submission==
Line 77: Line 104:
 
Submit your program to the '''Homework 4 Problem 3''' section in Moodle.
 
Submit your program to the '''Homework 4 Problem 3''' section in Moodle.
 
<br />
 
<br />
 +
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 +
<br />
 +
 
=Problem #4=
 
=Problem #4=
 
<br />
 
<br />
Will be provided later on 10/21/14...
+
Your assignment is to write a program in assembly that contains functions, one of which will display the contents of eax in hexadecimal.  This function will be called repeatedly from a test program, and given dwords through eax.  Your function will print the contents of eax in hexadecimal.
 +
 
 +
In order to get you started, you are given two helper programs.  '''Program 1''' shows you how to take a 4-bit value (i.e. a number between 0 and 15 decimal) and transform it into a character representing its hexadecimal equivalent.  For example, 4 decimal, which is also 0x04, will get converted to the ASCII character '4'.  8, which is also 0x08, will be converted to '8', and 10, which is 0x0A, will be converted to the character 'A'. 
 +
 
 +
'''Program 2''' shows you how to '''shift''' the bits inside a register.  We haven't covered shifts yet, but they are relatively easy to get.  They are covered in [http://cs.smith.edu/~dthiebaut/ArtOfAssembly/CH06/CH06-3.html#HEADING3-1 Randy Hyde's e-text] as well.
 +
 
 +
<br />
 +
==Helper Program 1==
 +
<br />
 +
<source lang="asm">
 +
;;; ; hw4Prep.asm
 +
;;; ; D. Thiebaut
 +
;;; ;
 +
;;; ; Takes a 4-bit value in al and find the ASCII char that represents
 +
;;; ; the hex digit associated with this value.
 +
;;; ;
 +
;;; ; to assemble and run:
 +
;;; ;
 +
;;; ;    nasm -f elf -F  stabs hw4Prep.asm
 +
;;; ;    ld -melf_i386 -o hw4Prep hw4Prep.o
 +
;;; ;    ./hw4Prep
 +
;;; ; -------------------------------------------------------------------
 +
 +
 
 +
 
 +
;;;  ------------------------------------------------------------
 +
;;;  data areas
 +
;;;  ------------------------------------------------------------
 +
 
 +
                section .data
 +
 
 +
bin2hex        db      "0123456789ABCDEF"
 +
                                ;table of all the hex characters from 0 to F
 +
 
 +
counter        db      0      ;counter incremented from 0 to 15
 +
 
 +
;;;  ------------------------------------------------------------
 +
;;;  code area
 +
;;;  ------------------------------------------------------------
 +
 
 +
                section .text
 +
                global  _start
 +
 
 +
;;;  ------------------------------------------------------------
 +
;;; printChar: prints the character in al.  Does not modify any
 +
;;; of the registers.
 +
;;;  ------------------------------------------------------------
 +
printChar:     
 +
                section .data
 +
char            db      0          ;temporary string holding char to print
 +
       
 +
                section .text
 +
                push    eax        ;save data regs
 +
                push    ebx
 +
                push    ecx
 +
                push    edx
 +
 
 +
                mov    byte[char],al
 +
                                  ;save char in string
 +
 
 +
                mov    ecx, char  ;print string using int 0x80
 +
                mov    edx, 1
 +
                mov    eax, 4
 +
                mov    ebx, 1
 +
                int    0x80
 +
 
 +
                pop    edx        ;restore data regs
 +
                pop    ecx
 +
                pop    ebx
 +
                pop    eax
 +
                ret
 +
 
 +
;;;  ------------------------------------------------------------
 +
;;;  main program.
 +
;;;  ------------------------------------------------------------       
 +
_start:
 +
                mov    ecx, 16
 +
 
 +
for:            mov    ebx, bin2hex            ;make ebx point to array of char
 +
       
 +
                mov    edx, 0                  ;put counter into edx
 +
                mov    dl, byte[counter]
 +
 
 +
                mov    al, byte[ebx+edx]      ;get char at index edx from table
 +
                call    printChar              ;print it
 +
                mov    al, 0x0a                ;print new line
 +
                call    printChar
 +
       
 +
                inc    byte[counter]          ;get next index value in array
 +
                loop    for                    ;keep on looping 16 times
 +
 
 +
;;;  exit()
 +
 
 +
                mov    eax,1
 +
                mov    ebx,0
 +
                int    0x80    ; final system call
 +
</source>
 +
<br />
 +
 
 +
==Helper Program 2==
 
<br />
 
<br />
 +
<source lang="asm">
 +
;;; ; hw4Prep2.asm
 +
;;; ; D. Thiebaut     
 +
;;; ;
 +
;;; ; Puts 0x89 in al, then prints '9' and '8' on the screen.
 +
;;; ; These happen to be the characters representing the hex
 +
;;; ; digits of the number.  Replace 0x89 but another 2-digit
 +
;;; ; hex value, and see the digits printed on the screen.
 +
;;; ;
 +
;;; ; to assemble and run:
 +
;;; ;
 +
;;; ;    nasm -f elf -F  stabs hw4Prep2.asm
 +
;;; ;    ld -melf_i386 -o hw4Prep2 hw4Prep2.o
 +
;;; ;    ./hw4Prep2
 +
;;; ; -------------------------------------------------------------------
 +
 +
extern          _printDec
 +
extern          _println
 +
       
 +
;;;  ------------------------------------------------------------
 +
;;;  code area
 +
;;;  ------------------------------------------------------------
 +
 +
                section .text
 +
                global  _start
 +
 +
_start:        mov    eax, 0  ;clear full register first
 +
                mov    al,0x89 ;set lower part to 0x89: 1000 1001
 +
                push    eax    ;save eax for later.
 +
 +
                and    eax,0x0F ;clear all bits except last 4
 +
                call    _printDec ;print digit (will print 9)
 +
 +
                pop    eax      ;get eax back
 +
 +
                shr    eax,4  ;shift eax right 4 bits
 +
                                ;now eax contains 8
 +
                call    _printDec ;print digit (will print 8)
 +
 +
                call    _println
 +
;;;  exit()
 +
 +
                mov    eax,1
 +
                mov    ebx,0
 +
                int    0x80    ; final system call
 +
 +
</source>
 
<br />
 
<br />
 +
 +
==Putting It All Together==
 +
<br />
 +
You will notice if you play with Helper Program 2 that it prints the hex digits of what you put in al correctly (in reverse order), except if the digits are letters.  0xAB, for example, is not printed as 'B' followed by 'A'.  Instead you will see 11, followed by 10.
 +
<br />
 +
But... if you combine Helper Program 1 with Helper Program 2, you should be able to.
 
<br />
 
<br />
 +
In a first step, combined both program so that 0xAB prints as 'B' followed by 'A'.
 
<br />
 
<br />
 +
When you are done, create a function that '''prints all 8 hexadecimal digits in eax, in the correct order'''.  Call your function '''_printHex''', and make it '''global''' (the same way that you make the '''_start''' label global):
 
<br />
 
<br />
 +
<source lang="asm">
 +
              global _start
 +
              global _printHex
 +
 +
</source>
 
<br />
 
<br />
 +
This way, I will be able to link your program with my test program, which will call your function and pass it different values in eax. 
 
<br />
 
<br />
 +
==Requirements==
 
<br />
 
<br />
 +
* Your program should be called Hw4_4.asm
 +
* It should contain at least 1 global function called _printHex
 +
* _printHex should print the 8 hex digits (even if they are 0s) corresponding to the 32-bit value in eax.
 +
* _printHex should NOT modify any of the other registers
 
<br />
 
<br />
 +
==Submission==
 
<br />
 
<br />
 +
* Submit '''Hw4_4.asm''' to the Moodle '''Homework 4 Program 4''' section.  Your function will be tested with 3 numbers:
 +
 +
00000000
 +
12345678
 +
ABCDEF00
 +
 
<br />
 
<br />
 +
<br /><br />
 +
<br /><br />
 +
<br /><br />
 +
<br /><br />
 +
<br /><br />
 +
 
[[Category:CSC231]][[Category:Homework]][[Category:Nasm]]
 
[[Category:CSC231]][[Category:Homework]][[Category:Nasm]]

Latest revision as of 12:42, 29 October 2014

--D. Thiebaut (talk) 07:11, 21 October 2014 (EDT)


The assignment is due on 10/28/10 at 11:55 p.m.





Problem #1: Addressing modes and one-dimensional arrays


Assume that your data section is initialized with the following variables:

      msg     db    3,"ALL",11,"PROGRAMMERS",3,"ARE",11,"PLAYWRIGHTS"
              db    3,"AND",3,"ALL",9,"COMPUTERS",3,"ARE",5,"LOUSY"
              db    6,"ACTORS"
      N       equ   10


Note that the msg contains byte numbers followed by words. The byte number preceeding a word corresponds to the number of letters in the word. So '3,"ALL"' for example means that the word that follows 3 is a 3-character word. '11,"PROGRAMMERS"' means that the string following the byte that contains 11 is an 11-character word.

N represents the total number of words in the string msg.

Your assignment is to write a program, called Hw4_1.asm, that uses one or several loops that go N times and that print all the words on separate lines, one after the other, such that each word is capitalized, i.e. its first letter is uppercase, and the others are lowercase.

If you observe the ASCII table, the difference between upper- and lower-case letters is always the same: 32. So, if you have an uppercase character in al and want to make it lowercase, you can do this:

          sub       al, 32


Better yet, you can write this instruction in a much more self-documenting fashion:

          sub       al, 'a'-'A'


In this case you ask nasm to figure out the difference between lower and uppercase letters, and subtract that difference from al. If al contained 'f', for example, then, after the sub instruction, it will contain 'F'.
Feel free to use the 231Lib.asm library for printing strings.

Submission


Submit your program in Moodle's Homework 4, Problem 1 section.




Problem #2: Documentation and Style


Take your solution program for Problem 1, above, and document it fully. Use past solution programs as examples. Your program should have:

  • A header, containing the name of the program (its file name), the name of the author, a description of what it does (and possible bugs you may know it to contain, and how one should assemble, link, and run it
  • Markers highlighting where the data section and code section are located
  • Comments throughout the code indicating what the various blocks of instructions do. Do not hesitate to add blank lines in your code to separate logical blocks. Make sure your comments help understand how the computation progresses, rather than what the instruction is doing.


For example, here is a bad way of documenting an instruction:


             inc        ebx              ; increment ebx


This is not very helpful because we are not learning anything more about what the code is doing. Instead, if eax is a pointer to a list of characters, a more useful comment would have been:


             inc        ebx              ; move ebx to the next character in string


  • You do not have to document each instruction. Only those that are important, or where having some additional details would help.
  • Make sure you use variables that have self-documenting names. x, a, for example, do not carry much information. But message, char, or index are much better.


Submission


You need to submit your fully documented program to a different section of Moodle. Your program will not be run or evaluated automatically. Instead I will download it from Moodle later, so that I can read it, annotate it, and comment on your programming style. You won't be able to run or evaluate this problem with Moodle.




Problem #3


Take your solution program (or my solution program) for Homework 3, Problem 5, and rewrite it (call it Hw4_3.asm), and this time make it use functions.
Your solution program should have several functions:

  • One function called printLn that prints a new-line character (0x0a). It will replace our _println function. Your function must use int 0x80 to print the 0x0a char. Your function should not call _println! printLn does not receive any parameter through registers, and must save all the registers it uses. In other words, when we return from printLn, all the registers will contain the same values they had before we called the function.
  • One function called printMsg that prints a string on the screen. printMsg will replace our _printString function. Your function must use int 0x80 to print the string. It will get the address of the string to print in ecx and the number of characters in the string in edx. This function should not call _printString. It must use the int 0x80 instruction.
  • One function called printFibMsg that gets a number in eax and prints the string Fibonacci(###) = where ### is the decimal value of the number in eax. You should call _printDec inside printFibMsg to print the number passed in eax.

Your printFibMsg function should save all the registers it modifies and should return them to their original values.

Restrictions


  • You can only use the _printDec library function in your program. No other function from the 231Lib.asm library should be used.


Submission


Submit your program to the Homework 4 Problem 3 section in Moodle.






Problem #4


Your assignment is to write a program in assembly that contains functions, one of which will display the contents of eax in hexadecimal. This function will be called repeatedly from a test program, and given dwords through eax. Your function will print the contents of eax in hexadecimal.

In order to get you started, you are given two helper programs. Program 1 shows you how to take a 4-bit value (i.e. a number between 0 and 15 decimal) and transform it into a character representing its hexadecimal equivalent. For example, 4 decimal, which is also 0x04, will get converted to the ASCII character '4'. 8, which is also 0x08, will be converted to '8', and 10, which is 0x0A, will be converted to the character 'A'.

Program 2 shows you how to shift the bits inside a register. We haven't covered shifts yet, but they are relatively easy to get. They are covered in Randy Hyde's e-text as well.


Helper Program 1


;;; ; hw4Prep.asm
;;; ; D. Thiebaut
;;; ;
;;; ; Takes a 4-bit value in al and find the ASCII char that represents
;;; ; the hex digit associated with this value.
;;; ;
;;; ; to assemble and run:
;;; ;
;;; ;     nasm -f elf -F  stabs hw4Prep.asm
;;; ;     ld -melf_i386 -o hw4Prep hw4Prep.o
;;; ;     ./hw4Prep
;;; ; -------------------------------------------------------------------
 


;;;  ------------------------------------------------------------
;;;  data areas
;;;  ------------------------------------------------------------

                section .data

bin2hex         db      "0123456789ABCDEF"
                                ;table of all the hex characters from 0 to F 

counter         db      0       ;counter incremented from 0 to 15

;;;  ------------------------------------------------------------
;;;  code area
;;;  ------------------------------------------------------------

                section .text
                global  _start

;;;  ------------------------------------------------------------
;;; printChar: prints the character in al.  Does not modify any
;;; of the registers.
;;;  ------------------------------------------------------------
printChar:      
                section .data
char            db      0          ;temporary string holding char to print
        
                section .text
                push    eax        ;save data regs
                push    ebx
                push    ecx
                push    edx

                mov     byte[char],al
                                   ;save char in string

                mov     ecx, char  ;print string using int 0x80
                mov     edx, 1
                mov     eax, 4
                mov     ebx, 1
                int     0x80

                pop     edx        ;restore data regs
                pop     ecx
                pop     ebx
                pop     eax
                ret

;;;  ------------------------------------------------------------
;;;  main program.
;;;  ------------------------------------------------------------        
_start:
                mov     ecx, 16

for:            mov     ebx, bin2hex            ;make ebx point to array of char
        
                mov     edx, 0                  ;put counter into edx
                mov     dl, byte[counter]

                mov     al, byte[ebx+edx]       ;get char at index edx from table
                call    printChar               ;print it
                mov     al, 0x0a                ;print new line
                call    printChar
        
                inc     byte[counter]           ;get next index value in array
                loop    for                     ;keep on looping 16 times

;;;  exit()

                mov     eax,1
                mov     ebx,0
                int     0x80    ; final system call


Helper Program 2


;;; ; hw4Prep2.asm
;;; ; D. Thiebaut       
;;; ;
;;; ; Puts 0x89 in al, then prints '9' and '8' on the screen.
;;; ; These happen to be the characters representing the hex
;;; ; digits of the number.  Replace 0x89 but another 2-digit
;;; ; hex value, and see the digits printed on the screen.
;;; ;
;;; ; to assemble and run:
;;; ;
;;; ;     nasm -f elf -F  stabs hw4Prep2.asm
;;; ;     ld -melf_i386 -o hw4Prep2 hw4Prep2.o
;;; ;     ./hw4Prep2
;;; ; -------------------------------------------------------------------

extern          _printDec
extern          _println
        
;;;  ------------------------------------------------------------
;;;  code area
;;;  ------------------------------------------------------------

                section .text
                global  _start

_start:         mov     eax, 0  ;clear full register first
                mov     al,0x89 ;set lower part to 0x89: 1000 1001
                push    eax     ;save eax for later.

                and     eax,0x0F ;clear all bits except last 4
                call    _printDec ;print digit (will print 9)

                pop     eax      ;get eax back

                shr     eax,4   ;shift eax right 4 bits
                                ;now eax contains 8
                call    _printDec ;print digit (will print 8)

                call    _println
;;;  exit()

                mov     eax,1
                mov     ebx,0
                int     0x80    ; final system call


Putting It All Together


You will notice if you play with Helper Program 2 that it prints the hex digits of what you put in al correctly (in reverse order), except if the digits are letters. 0xAB, for example, is not printed as 'B' followed by 'A'. Instead you will see 11, followed by 10.
But... if you combine Helper Program 1 with Helper Program 2, you should be able to.
In a first step, combined both program so that 0xAB prints as 'B' followed by 'A'.
When you are done, create a function that prints all 8 hexadecimal digits in eax, in the correct order. Call your function _printHex, and make it global (the same way that you make the _start label global):

               global _start
               global _printHex


This way, I will be able to link your program with my test program, which will call your function and pass it different values in eax.

Requirements


  • Your program should be called Hw4_4.asm
  • It should contain at least 1 global function called _printHex
  • _printHex should print the 8 hex digits (even if they are 0s) corresponding to the 32-bit value in eax.
  • _printHex should NOT modify any of the other registers


Submission


  • Submit Hw4_4.asm to the Moodle Homework 4 Program 4 section. Your function will be tested with 3 numbers:
00000000
12345678
ABCDEF00