Difference between revisions of "CSC231 Homework 5 Fall 2017"

From dftwiki3
Jump to: navigation, search
(Your Assignment, Part 1)
 
(5 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
<br />
 
<br />
 
<bluebox>
 
<bluebox>
This assignment is due Monday 11/6/2017 at 11:55 p.m.
+
This assignment is due Monday 11/6/2017 at 11:55 p.m.   <br />
 +
Note: you will not be given the ability to evaluate your program on Moodle, and see its final grade.  For this reason, make sure you thoroughly test your programs before submitting them!
 
</bluebox>
 
</bluebox>
 
<br />
 
<br />
Line 216: Line 217:
 
=Problem 4=
 
=Problem 4=
 
<br />
 
<br />
Create a new program in your account, called '''hw5dprep.asm''', and store the code below in it.
+
* Write a program called '''hw4d.asm''' that prompts the user for a string, and displays the ''checksum'' of this string, in decimal. 
 +
<br />
 +
* The checksum of a string is the ''exclusive or'' of all the bytes in a string.  This is an operation used mostly in communication, when bytes of data are sent over a network.  In general, when a packet of bytes is sent, the exclusive or of all the bytes is computed, and sent at the end, as an extra byte.  The receiving device, upon receiving the data, will compute the exclusive or of all the data bytes, and compare the checksum it computed to the checksum that was sent.  If the two checksums are different, very likely a transmission error occurred and the receiving device will ask for the packet to be transmitted again.
 +
<br />
 +
* Here is how you would compute the checksum of a string of 5 bytes: 0x41, 0x42, 0x43, 0x44, 0x45.  I will use binary, as it is simpler:
 +
 +
  checksum <-- 0x41  = 0100 0001
 +
  checksum <-- checksum xor 0x42    = 0100 0001 xor 0100 0010 = 0000 0011
 +
  checksum <-- checksum xor 0x43    = 0000 0011 xor 0100 0011 = 0100 0000
 +
  checksum <-- checksum xor 0x44    = 0100 0000 xor 0100 0100 = 0000 0100
 +
  checksum <-- checksum xor 0x45    = 0000 0100 xor 0100 0101 = 0100 0001
 +
 +
:The checksum of the 5 bytes is 0100 0001, or 0x41, or 65.  The program will print 65 as the checksum for the string ABCDE.
 +
 
 +
* Examples
 +
 
 +
cs231a@aurora ~ $ ./hw5d
 +
> hello there
 +
44
 +
 
 +
cs231a@aurora ~ $ ./hw5d
 +
> ABCDE
 +
65
 +
 
 +
cs231a@aurora ~ $ ./hw5d
 +
> AA
 +
0
 +
 
 +
cs231a@aurora ~ $ ./hw5d
 +
> Hello!
 +
99
 +
 
 +
cs231a@aurora ~ $ ./hw5d
 +
> I like milk chocolate better than dark chocolate.
 +
80
 +
 
 +
<br />
 +
==Submission==
 +
<br />
 +
Submit your program on Moodle, in the Homework 5, Problem 4 section.
 +
<br />
 +
<br />
 +
<showafterdate after="20171107 00:00" before="20171231">
 +
=Solutions=
 +
<br />
 +
==Problem 1==
 
<br />
 
<br />
 
::<source lang="asm">
 
::<source lang="asm">
;;; ; hw5d_prep.asm
+
;;; ; hw5a.asm
 
;;; ; D. Thiebaut
 
;;; ; D. Thiebaut
 
;;; ;
 
;;; ;
;;; ;     nasm -f elf -F  stabs hw5d_prep.asm
+
;;; ;  
;;; ;    ld -melf_i386 -o hw5d_prep 231Lib.o hw5d_prep.o
 
;;; ;    ./hw5d_prep
 
 
;;; ; -------------------------------------------------------------------
 
;;; ; -------------------------------------------------------------------
  
Line 232: Line 276:
  
 
        section .data
 
        section .data
fileName db "dummy.txt", 0
+
prompt db "> "
buffer db "                                                          "
+
bufferAddr dd 0
db      "                                                          "
+
noChars dd 0
db      "                                                          "
+
saveEcx dd 0
db      "                                                          "
+
db      "                                                          "
+
;;;  ------------------------------------------------------------
db      "                                                          "
+
;;;  code area
db      "                                                          "
+
;;;  ------------------------------------------------------------
db      "                                                          "
 
  
noCharsRead dd 0
+
        section .text
 +
        global  _start
 +
extern _getString
 +
extern _printString
 +
extern _println
 +
 +
_start:
 +
mov ecx, prompt
 +
mov edx, 2
 +
call _printString
 +
 
 +
call _getString
 +
mov dword[noChars], edx
 +
mov dword[bufferAddr], ecx
 +
 
 +
;;; print string in a loop that goes the same # of times
 +
;;; as the number of chars in the string.
 +
 
 +
mov ecx, dword[noChars]
 +
for: mov dword[saveEcx], ecx
 +
 
 +
mov ecx, dword[bufferAddr]
 +
mov edx, dword[noChars]
 +
call _printString
 +
call _println
 +
 
 +
mov ecx, dword[saveEcx]
 +
loop for
 +
 
 +
;;;  exit()
 +
 
 +
        mov    eax,1
 +
        mov    ebx,0
 +
        int    0x80 ; final system call
 +
 
 +
</source>
 +
<br />
 +
==Problem 2==
 +
<br />
 +
::<source lang="asm">
 +
 
 +
;;; ; hw5b.asm
 +
;;; ; D. Thiebaut
 +
;;; ;
 +
;;;  ------------------------------------------------------------
 +
;;;  data areas
 +
;;;  ------------------------------------------------------------
 +
 
 +
        section .data
 +
prompt db "> "
 +
bufferAddr dd 0
 +
noChars dd 0
 +
saveEcx dd 0
 
 
 
;;;  ------------------------------------------------------------
 
;;;  ------------------------------------------------------------
Line 250: Line 345:
 
        section .text
 
        section .text
 
        global  _start
 
        global  _start
 +
extern _getString
 +
extern _printString
 +
extern _println
 +
 +
_start:
 +
mov ecx, prompt
 +
mov edx, 2
 +
call _printString
 +
 +
call _getString
 +
mov dword[noChars], edx
 +
mov dword[bufferAddr], ecx
 +
 +
;;; print string in a loop that goes the same # of times
 +
;;; as the number of chars in the string.
 +
 +
mov ecx, dword[noChars]
 +
 +
for: mov edx, ecx
 +
mov dword[saveEcx], ecx
 +
 +
mov ecx, dword[bufferAddr]
 +
call _printString
 +
call _println
 +
 +
mov ecx, dword[saveEcx]
 +
loop for
 +
 +
;;;  exit()
 +
 +
        mov    eax,1
 +
        mov    ebx,0
 +
        int    0x80 ; final system call
 
 
extern _printString
+
extern _readFile
+
</source>
extern _println
+
<br />
 +
==Problem 3==
 +
<br />
 +
::<source lang="asm">
 +
;;; ; hw5c.asm
 +
;;; ; D. Thiebaut
 +
;;; ;
 +
;;; ; -------------------------------------------------------------------
 +
 
 +
;;;  ------------------------------------------------------------
 +
;;;  data areas
 +
;;;  ------------------------------------------------------------
 +
 
 +
        section .data
 +
prompt db "> "
 +
bufferAddr dd 0
 +
noChars dd 0
 +
saveEcx dd 0
 +
 +
;;;  ------------------------------------------------------------
 +
;;;  code area
 +
;;;  ------------------------------------------------------------
 +
 
 +
        section .text
 +
        global  _start
 +
extern _getString
 +
extern _printString
 +
extern _println
 
 
 
_start:
 
_start:
mov eax, fileName ; pass address of file-name in eax
+
mov ecx, prompt
mov ebx, buffer ; pass buffer address in ebx
+
mov edx, 2
mov ecx, noCharsRead ; pass address of var that will contain
+
call _printString
; number of chars read in ecx
+
 
 +
call _getString
 +
mov dword[noChars], edx
 +
mov dword[bufferAddr], ecx
 +
 
 +
;;; print string in a loop that goes the same # of times
 +
;;; as the number of chars in the string.
 +
 
 +
mov ecx, dword[noChars]
 
 
call _readFile ; read the file whose name was passed in
+
for: mov edx, ecx
; eax.  _readFile will read the file and
+
neg edx
; put all the bytes read into the buffer
+
add edx, dword[noChars]
; it will also put the number of bytes read
+
inc edx
; into the variable noCharsRead.
+
 +
mov dword[saveEcx], ecx
  
;; print the contents of the buffer
+
mov ecx, dword[bufferAddr]
mov ecx, buffer
 
mov edx, dword[noCharsRead]
 
 
call _printString
 
call _printString
 
call _println
 
call _println
 +
 +
mov ecx, dword[saveEcx]
 +
loop for
 +
 +
;;;  exit()
 +
 +
        mov    eax,1
 +
        mov    ebx,0
 +
        int    0x80 ; final system call
 +
 +
</source>
 +
<br />
 +
==Problem 4==
 +
<br />
 +
::<source lang="asm">
 +
;;; ; hw5d.asm
 +
;;; ; D. Thiebaut
 +
;;; ;
 +
;;; ; -------------------------------------------------------------------
 +
 +
;;;  ------------------------------------------------------------
 +
;;;  data areas
 +
;;;  ------------------------------------------------------------
 +
 +
        section .data
 +
prompt db "> "
 +
bufferAddr dd 0
 +
noChars dd 0
 +
checksum db 0
 +
 +
;;;  ------------------------------------------------------------
 +
;;;  code area
 +
;;;  ------------------------------------------------------------
 +
 +
        section .text
 +
        global  _start
 +
extern _getString
 +
extern  _printInt
 +
extern _println
 +
extern _printString
 
 
 +
_start:
 +
mov ecx, prompt
 +
mov edx, 2
 +
call _printString
 +
 +
call _getString
 +
mov dword[noChars], edx
 +
mov dword[bufferAddr], ecx
 +
 +
 +
;;; Get ready to scan the string and xor each char with al,
 +
;;; which we use as a checksum
 +
 +
mov ecx, dword[noChars]
 +
mov edx, dword[bufferAddr]
 +
mov eax, 0
 +
 +
;;; loop through the string
 +
for: xor al, byte[edx]
 +
inc edx
 +
loop for
 +
 +
;;; display the checksum in decimal
 +
call _printInt
 +
call _println
 
;;;  exit()
 
;;;  exit()
  
Line 278: Line 505:
 
        mov    ebx,0
 
        mov    ebx,0
 
        int    0x80 ; final system call
 
        int    0x80 ; final system call
 +
 
</source>
 
</source>
 
<br />
 
<br />
* Read the code of your program ''carefully.''  Notice that it uses a new function, called '''_readFile'''.  This function ''needs'' to be given 3 things in order to do its work.  It needs to have a string containing the name of a file.  This is given to the function in eax (and always eax).  It also needs the address of a buffer were we want to receive the contents of the text file.  The address of the buffer is given in ebx.  Finally, the function needs to know the address of the variable declared in our program that will contain the number of bytes put in the buffer.  The address of this variable is passed in edx.
+
</showafterdate>
* To test your program you need to first create a text file called '''dummy.txt''' with emacs, and enter two or three lines of text in it.  Maybe the first three lines of your favorite poem.
 
* Assemble and link the '''hw5dprep.asm''' with the 231Lib library (make sure you '''getcopy''' the new version of the 231Lib.asm library, and that you assemble the new library again).
 
* Run the '''hw5dprep''' executable, and verify that it prints the contents of the ''dummy.txt'' file.
 
 
<br />
 
<br />
==Your Assignment, Part 1==
 
 
<br />
 
<br />
* Copy hw5dprep.asm to '''hw5d.asm'''.  This will be the program you submit to Moodle.
 
* Modify hw5d.asm so that it prompts the user for the name of the file,  gets the name of the file with _getString, and stores the string in the '''fileName''' variable.  You may want to make the fileName array of bytes large enough to work for very long file paths.  (100 characters should be sufficient).
 
* Make the program put a byte containing 0x00 at the end of the file name.  This is a requirement for strings used by Linux.  Linux is written in '''C''', and in C all strings end with a byte containing 0x00, or 0, or '\0'.  So, if we want to give the name of our file for Linux to open, we need to put a byte containing 0 as then end of the file name. 
 
* Verify that your modified program works fine with different short text files that contain different text.
 
 
<br />
 
<br />
==Your Assignment, Part 2==
 
 
<br />
 
<br />
* Assume that the files we'll be processing with your program will always contain DNA strings, containing only 'A', 'C', 'G', 'T', and 'N', always in uppercase.  Modify your program so that it converts the DNA string to lowercase before printing it.
 
* Submit your solution to Moodle.
 
 
<br />
 
<br />
==Examples==
 
 
<br />
 
<br />
* I have three text files containing 3 different DNA strings
 
 
=Problem 5=
 
 
<br />
 
<br />
Stay tuned!
 
 
<br />
 
<br />
 +
[[Category:CSC231]][[Category:Homework]]

Latest revision as of 08:38, 7 November 2017

--D. Thiebaut (talk) 09:27, 30 October 2017 (EDT)



This assignment is due Monday 11/6/2017 at 11:55 p.m.
Note: you will not be given the ability to evaluate your program on Moodle, and see its final grade. For this reason, make sure you thoroughly test your programs before submitting them!



Preparation


For this assignment you will need to downloaded an updated version of 231Lib.asm, which has been augmented with a new function for reading strings.

getcopy 231Lib.asm

An example program using the new function, _getString(), is shown below:

;;; ; hw5Prep.asm
;;; ; D. Thiebaut
;;; ;
;;; ; Gets a string from the user and prints it back
;;; ;
;;; ; to assemble and run:
;;; ;
;;; ;     nasm -f elf  hw5Prep.asm
;;; ;     nasm -f elf  231Lib.asm
;;; ;     ld -melf_i386 -o hw5Prep hw5Prep.o 231Lib.o
;;; ;     ./hw5Prep
;;; ; -------------------------------------------------------------------

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

	        section .data
prompt		db	"> "

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

	        section .text
	        global  _start
		extern	_getString
		extern	_printString
		extern	_println
	
_start:
                ;; prompt the user 
		mov	ecx, prompt
		mov	edx, 2
		call	_printString

                ;; get a string from the user
                ;; _getString returns the address of the string read in ecx,
                ;; and the number of chars read in edx
		call	_getString

                ;; since ecx and edx already contain the address and number
                ;; of chars, we can directly call _printString, which needs
                ;; the string and number of chars in the same registers
		call	_printString

                ;; print a line-feed char.
		call	_println


;;;  exit()

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


Create a version of this program in your account, and play with it. Verify that it gets a string from you and prints it back.

Notes


  1. _getString saves the string in an array declared inside 231Lib.asm. This array contains at most 1000 bytes.
  2. when _getString returns to your main program, it will set ecx to the address of the array containing the string, and it will set edx to contain the number of characters the user typed at the keyboard.
  3. the user indicates the end of the string by pressing the ENTER key. The string does not contain the ENTER character (line-feed).
  4. although I didn't do that here because the program is so simple and short, it is a good idea, just after returning from a call to _getString, to save ecx and edx into two different variables in memory that will hold the address of the string and the number of chars entered at the keyboard.


Problem 1


Write a program called hw5a.asm that prompts the user for a string, and prints it back several times. The number of times the string is printed is the same as the number of characters in the string.

Examples
cs231a@aurora ~ $ ./hw5a
> B
B
cs231a@aurora ~ $ ./hw5a
> a
a
cs231a@aurora ~ $ ./hw5a
> hello
hello
hello
hello
hello
hello
cs231a@aurora  $ ./hw5a
> chocolate
chocolate
chocolate
chocolate
chocolate
chocolate
chocolate
chocolate
chocolate
chocolate
cs231a@aurora  $ ./hw5a
> Hall o ween
Hall o ween
Hall o ween
Hall o ween
Hall o ween
Hall o ween
Hall o ween
Hall o ween
Hall o ween
Hall o ween
Hall o ween
Hall o ween
 


Note


  • Your program does not have to handle 0-length strings. In other words, your program will not be tested with empty strings.


Submission


  • Submit your program in the Homework 5, Problem 1 section on Moodle.


Problem 2


Modify your solution program for Problem 1 so that it removes the last character of the previous printed string as it goes through the loop:

Examples
cs231a@aurora  $ ./hw5b
> Hall-o-ween
Hall-o-ween
Hall-o-wee
Hall-o-we
Hall-o-w
Hall-o-
Hall-o
Hall-
Hall
Hal
Ha
H
cs231a@aurora  $ ./hw5b
> a
a
cs231a@aurora ~/HWs/HW5/PB2 $ ./hw5b
> 123456789
123456789
12345678
1234567
123456
12345
1234
123
12
1


Submission


  • Submit your program in the Homework 5, Problem 2 section on Moodle.


Problem 3


Same as with Problem 2, but this time the triangle is reversed:

Example
cs231a@aurora  $ ./hw5c
> Hal-lo-we-en
H
Ha
Hal
Hal-
Hal-l
Hal-lo
Hal-lo-
Hal-lo-w
Hal-lo-we
Hal-lo-we-
Hal-lo-we-e
Hal-lo-we-en


Submission


  • Submit your program to the Homework 5, Problem 3 section on Moodle.


Problem 4


  • Write a program called hw4d.asm that prompts the user for a string, and displays the checksum of this string, in decimal.


  • The checksum of a string is the exclusive or of all the bytes in a string. This is an operation used mostly in communication, when bytes of data are sent over a network. In general, when a packet of bytes is sent, the exclusive or of all the bytes is computed, and sent at the end, as an extra byte. The receiving device, upon receiving the data, will compute the exclusive or of all the data bytes, and compare the checksum it computed to the checksum that was sent. If the two checksums are different, very likely a transmission error occurred and the receiving device will ask for the packet to be transmitted again.


  • Here is how you would compute the checksum of a string of 5 bytes: 0x41, 0x42, 0x43, 0x44, 0x45. I will use binary, as it is simpler:
 checksum <-- 0x41  = 0100 0001 
 checksum <-- checksum xor 0x42    = 0100 0001 xor 0100 0010 = 0000 0011
 checksum <-- checksum xor 0x43    = 0000 0011 xor 0100 0011 = 0100 0000
 checksum <-- checksum xor 0x44    = 0100 0000 xor 0100 0100 = 0000 0100
 checksum <-- checksum xor 0x45    = 0000 0100 xor 0100 0101 = 0100 0001

The checksum of the 5 bytes is 0100 0001, or 0x41, or 65. The program will print 65 as the checksum for the string ABCDE.
  • Examples
cs231a@aurora ~ $ ./hw5d 
> hello there
44
cs231a@aurora ~ $ ./hw5d 
> ABCDE
65
cs231a@aurora ~ $ ./hw5d 
> AA
0
cs231a@aurora ~ $ ./hw5d 
> Hello!
99
cs231a@aurora ~ $ ./hw5d 
> I like milk chocolate better than dark chocolate.
80


Submission


Submit your program on Moodle, in the Homework 5, Problem 4 section.

<showafterdate after="20171107 00:00" before="20171231">

Solutions


Problem 1


;;; ; hw5a.asm
;;; ; D. Thiebaut
;;; ;
;;; ; 
;;; ; -------------------------------------------------------------------

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

	        section .data
prompt		db	"> "
bufferAddr	dd	0
noChars		dd	0	
saveEcx		dd	0
	
;;;  ------------------------------------------------------------
;;;  code area
;;;  ------------------------------------------------------------

	        section .text
	        global  _start
		extern	_getString
		extern	_printString
		extern	_println
	
_start:
		mov	ecx, prompt
		mov	edx, 2
		call	_printString

		call	_getString
		mov	dword[noChars], edx
		mov	dword[bufferAddr], ecx

;;; print string in a loop that goes the same # of times
;;; as the number of chars in the string.

		mov	ecx, dword[noChars]
for:		mov	dword[saveEcx], ecx

		mov	ecx, dword[bufferAddr]
		mov	edx, dword[noChars]
		call	_printString
		call	_println

		mov	ecx, dword[saveEcx]
		loop	for

;;;  exit()

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


Problem 2


;;; ; hw5b.asm
;;; ; D. Thiebaut
;;; ;
;;;  ------------------------------------------------------------
;;;  data areas
;;;  ------------------------------------------------------------

	        section .data
prompt		db	"> "
bufferAddr	dd	0
noChars		dd	0	
saveEcx		dd	0
	
;;;  ------------------------------------------------------------
;;;  code area
;;;  ------------------------------------------------------------

	        section .text
	        global  _start
		extern	_getString
		extern	_printString
		extern	_println
	
_start:
		mov	ecx, prompt
		mov	edx, 2
		call	_printString

		call	_getString
		mov	dword[noChars], edx
		mov	dword[bufferAddr], ecx

;;; print string in a loop that goes the same # of times
;;; as the number of chars in the string.

		mov	ecx, dword[noChars]
	
for:		mov	edx, ecx
		mov	dword[saveEcx], ecx

		mov	ecx, dword[bufferAddr]
		call	_printString
		call	_println

		mov	ecx, dword[saveEcx]
		loop	for

;;;  exit()

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


Problem 3


;;; ; hw5c.asm
;;; ; D. Thiebaut
;;; ;
;;; ; -------------------------------------------------------------------

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

	        section .data
prompt		db	"> "
bufferAddr	dd	0
noChars		dd	0	
saveEcx		dd	0
	
;;;  ------------------------------------------------------------
;;;  code area
;;;  ------------------------------------------------------------

	        section .text
	        global  _start
		extern	_getString
		extern	_printString
		extern	_println
	
_start:
		mov	ecx, prompt
		mov	edx, 2
		call	_printString

		call	_getString
		mov	dword[noChars], edx
		mov	dword[bufferAddr], ecx

;;; print string in a loop that goes the same # of times
;;; as the number of chars in the string.

		mov	ecx, dword[noChars]
	
for:		mov	edx, ecx
		neg	edx
		add	edx, dword[noChars]
		inc	edx
	
		mov	dword[saveEcx], ecx

		mov	ecx, dword[bufferAddr]
		call	_printString
		call	_println

		mov	ecx, dword[saveEcx]
		loop	for

;;;  exit()

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


Problem 4


;;; ; hw5d.asm
;;; ; D. Thiebaut
;;; ;
;;; ; -------------------------------------------------------------------

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

	        section .data
prompt		db	"> "
bufferAddr	dd	0
noChars		dd	0	
checksum	db	0
	
;;;  ------------------------------------------------------------
;;;  code area
;;;  ------------------------------------------------------------

	        section .text
	        global  _start
		extern	_getString
		extern  _printInt
		extern	_println
		extern	_printString
	
_start:
		mov	ecx, prompt
		mov	edx, 2
		call	_printString

		call	_getString
		mov	dword[noChars], edx
		mov	dword[bufferAddr], ecx


;;; Get ready to scan the string and xor each char with al,
;;; which we use as a checksum

		mov	ecx, dword[noChars]
		mov	edx, dword[bufferAddr]
		mov	eax, 0

;;; loop through the string
for:		xor	al, byte[edx]
		inc	edx
		loop	for

;;; display the checksum in decimal
		call	_printInt
		call	_println
;;;  exit()

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


</showafterdate>