################################################################################ ## ## LSU EE 4720 Fall 2007 Homework 1 ## ## ## Due Monday, 17 September 2007 .data name: .asciiz "dmk" # Put your name between the quotes. ## Instructions: # # (0) Read and follow account setup instructions at # http://www.ece.lsu.edu/ee4720/proc.html # # (1) Copy this assignment, local path name # /home/classes/ee4720/com/s/hw1.s, to a directory ~/hw in your # class account. (~ is your home directory.) Use this file for your # solution. The TA-bot will look first for a file named ~/hw/hw1.s. # If you have multiple versions make sure the one you want graded # is in ~/hw/hw1.s. # # (2) Find the problem in this file and solve it. # # A procedure shell has been provided for the problem. Place # your solution there. # # Assembler code following the problems runs your solutions. # That code can be modified. # # Please test your code with the demo routine. (Press f9.) # Make sure it works correctly. # # Your entire solution should be in this file. # # Do not rename the line labels in this file and be sure to use the # directory and filename given above. (Line labels may be added.) # # (3) Your solution will automatically be copied from your account by # the TA-bot. Late submissions can be E-mailed. # ## Additional Resources # # MIPS Architecture Manual Volume 2 (Contains a list of instructions.) # http://www.ece.lsu.edu/ee4720/mips32v2.pdf # Note: SPIM implements MIPS-I instructions. # # SPIM Documentation: # Appendix A of Patterson and Hennessey. # http://www.ece.lsu.edu/3755/spim.pdf # # Account Setup and Emacs (Text Editor) Instructions # http://www.ece.lsu.edu/ee4720/proc.html # To learn Emacs look for and follow instructions for the Emacs tutorial. # # Unix Help # http://www.ece.lsu.edu/v/4ltrwrd/ ## Note on SPIM # # Clicking the close button (usually the upper-right-hand button on # the window frame) of any window will immediately exit SPIM. # ## Troubleshooting # # Make sure that the "run" dialog box shows 0x0400000 for the starting # address. If not, __start was not properly defined, possibly due to # an error before __start. # # Check the messages (bottommost) pane for syntax and other errors. It # may be necessary to shorten other panes to make the messages pane visible. # Common syntax errors include using "addi" instead of "add", or vice versa. # Another common error is mistyping a label in a branch or jump target. # # Check the "Text Segments" pane to make sure all of your program is there. # If not, there may have been an error reading the program. # # If your program fails a test or otherwise does not produce the # expected output modify the test code so that the particular test it # fails comes first (if it's not already). Then, single-step the code # (using the "step") button until you find the problem. # # If you've hit a wall ask the instructor help. It's better to # err on the side of too many questions than too few. ################################################################################ ## Problem 0 # Do the setup described in the instructions above. # # Before making any changes to this file (other than comments) run # the assembler/simulator SPIM using the following steps: # # Load this file into an Emacs buffer using the class-account Emacs. # # If setup was done correctly comments should be red, "Problem 0" above # should be in a black, bold, sans-serif font and the assembler below # should look something like fruit salad, with pale blue mnemonics, # italicized pseudo instructions, purple assembler directives, green # line labels, etc. # # Start the SPIM assembler/simulator by pressing [F9]. # -> A window entitled "xspim" should pop up. The top pane should show # register values, the next pane should have buttons, the third # should show the program in binary and assembler forms, the fourth # pane shows the data area, and the bottom pane (which might extend # past the bottom of the screen) shows messages. # # Run the program by clicking the "run" button then clicking "ok" on the # dialog box that pops up. # -> A window entitled "SPIM Console" should pop up, the window # should be asking you to include your name in this file. After # a name is entered and Spim is re-run it should show four wrong # conversions (for Problem 1). For Problem 0 that's success!!! # # Put your name at the top of the file then run the code in this # file. # -> The output window of the simulator (which might be hidden # behind the main window) should show that the output of the unpack # routine is "Not yet implemented." and is not the correct output. ################################################################################ ## Problem 1 # The itox routine below is to convert an unsigned 32-bit integer into # an ASCII string of its radix-R representation, where R is any # positive power of 2. (For example, if R is 2 convert to binary, if R # 16 convert to hexadecimal.) But wait, itox is not just any # integer-to-string program. With itox the caller specifies the digit # set to use. For example, when converting 5 to binary one might # specify digit set "01" (resulting in the usual "101") or one might # choose digit set "ft" (resulting in "tft"). # The itox routine is called with three arguments, in $a0, $a1, and $a2. # Register $a0 holds the unsigned 32-bit integer to convert. # Register $a1 holds the address of the digit set, a null-terminated # string. The character at address $a1 is the digit for zero, the # character at address $a1 + 1 is the digit for one, and so on. # Register $a2 holds the address at which the converted string # is to be written. # If the number of digits in the digit set is not a power of 2 then # itox should write a 0 at $a2 (in effect returning a zero-length # string). Otherwise, it should write, starting at $a2, the radix-R # representation of $a0 using the digit set provided. # Complete the itox routine so that it behaves as described above. ################################################################################ ## itox -- Convert unsigned integer to custom ASCII string. ## Register Usage # # $a0: Procedure call argument. # Value to convert, an unsigned integer. # # $a1: Procedure call argument. # Address of digit string. # # $a2: Procedure call argument. # Place to put converted string. # # There is no return value, instead the string should be written # into the memory at $a2. # [ ] Do not modify registers s0-s7 # [ ] Can modify registers a0-a3, t0-t9. # [ ] Return a zero-length string if number of digits not a power of 2. # [ ] Make sure digits are in correct order. # [ ] DO NOT use division or modulo instructions, instead shift & mask. # [ ] The routine must be reasonably efficient. # [ ] Fill as many delay slots as possible. # [ ] Solutions with syntax errors will get low grades. .text itox: ## SOLUTION. addi $t7, $a2, 0 addi $t0, $a1, 0 # Count number of digits. # lenloop: lb $t1, 0($t0) bne $t1, $0, lenloop addi $t0, $t0, 1 sub $t1, $t0, $a1 addi $t1, $t1, -1 # $t1 holds number of digits. # Find log base 2 of the number of digits. # addi $t2, $0, 1 # Used as constant. addi $t3, $0, 0 # Log_2 of length. lgloop: sllv $t4, $t2, $t3 slt $t5, $t4, $t1 bne $t5, $0, lgloop add $t3, $t3, $t5 # If number of digits not a power of 2 return empty string. # beq $t4, $t1, ispot sb $0, 0($a2) jr $ra nop ispot: addi $t2, $t1, -1 # Mask for extracting low bits. # Convert number to ASCII string. String will be reversed. # loop: and $t6, $a0, $t2 # Mask off low bits. add $t6, $a1, $t6 # Compute address of digit character. lb $t6, 0($t6) # Load character... sb $t6, 0($a2) # ... and store it in result string. srlv $a0, $a0, $t3 bne $a0, $0 loop addi $a2, $a2, 1 sb $0, 0($a2) # Reverse the result string by swapping the first and last # character, the second and penultimate character, etc. # addi $a2, $a2, -1 rloop: lb $t0, 0($a2) lb $t1, 0($t7) sb $t1, 0($a2) sb $t0, 0($t7) addi $t7, $t7, 1 addi $a2, $a2, -1 slt $t2, $a2, $t7 beq $t2, $0 rloop nop jr $ra nop ################################################################################ ## Demonstration and Test Routine # This routine calls itox on sample numbers, and displays the original # and converted numbers. # It's okay to change the code below if that will help you debug your code, # but your code should work on the original test routine and for other # valid inputs. .data # Indicate to the assembler that the stuff below is data. # # Message displayed if student's name omitted. # who_are_you: .asciiz "Please put your name at the top of the file where indicated." # # Integer values to be converted. # values: # Assembler converts "values" to address of stuff below. .word 0x0 # Assembler places zero in memory after label "values". .word 0xe .word 0x1234abcd .word -1 # Mark end of list. # # Digit strings to be used when converting the numbers above. # digits: .asciiz "0123456789abcdef" # Ordinary hex digits. .asciiz "oltefsif%^@;()>+" # Use bizarre letters for hex. .asciiz "01" # Ordinary binary. .asciiz "FT" # False / True. .asciiz "nesw" # Base four (north, east, south, west) .asciiz "" # Mark end of list. # # Message used by demonstration routine. # msg: .asciiz "HEX VAL 0x%/s3/08x CUSTOM VAL %/s2/18s DIGIT SET %/s1/s\n" # # Memory space to be used for result string. # str: .space 256 # Tell assembler to reserve 256 characters of space. .text # Tell assembler to put stuff below in "text" (program) segment. .globl __start __start: la $s0, name lb $s0, ($s0) bne $s0, $0, DODEMO la $a0, who_are_you addi $v0, $0, 11 syscall addi $v0, $0, 10 syscall DODEMO: # Put constant (address of values a few lines above) in register # $s0 using pseudo instruction la. la $s0, values # s0: Address of next value to use. addi $s4, $0, -1 # s4: Value marking end of value list. # # Call itox for each pair of value/digit appearing above. # # Outer loop - iterate over digit sets. # DIGITLOOP: la $s1, digits # s1: Address of next digit set to use. # Inner loop - iterate over values. # VALLOOP: # Call itox # lw $a0, 0($s0) # For call to itox load first value ... la $a2, str # ... address of storage ... jal itox addi $a1, $s1, 0 # ... and address of digit set to "a" registers. # Show results of itox call. # lw $s3, 0($s0) # Re-load value (for display). la $s2, str # Load address of converted string (for display). la $a0, msg # Load message. addi $v0, $0, 11 # Load code for LSU xspim's printf syscall. syscall # Display results. MLEN: # Find next digit set. # lb $t0, 0($s1) bne $t0, $0, MLEN addi $s1, $s1, 1 lb $t0, 0($s1) bne $t0, $0 VALLOOP # If next digit set not empty, use it. lw $t0, 4($s0) # Load next value. bne $t0, $s4 DIGITLOOP # If next value not end of list, use it. addi $s0, $s0, 4 MEXIT: addi $v0, $0, 10 syscall nop