Beruflich Dokumente
Kultur Dokumente
N. B. Dodge 9/15
Programming Problem
Our joint program will take keyboard input for a decimal
number up to eight digits (99,999,999) and convert the
decimal number to hexadecimal.
It will then print out the hex result on the SPIM simulated
console.
The program will run continually and convert multiple
numbers, if desired.
We will construct this program together, so that you can get
some more practice in live coding.
The program should be completed off-line if you do not
finish by the end of class (and also to make an addition to
the program discussed at the end of class).
2
N. B. Dodge 9/15
Convert each hex digit to ASCII, and print out using syscall 11.
Convert all the digits, store in a string, and output using syscall 4.
Lecture #16: SPIM Programming Example
N. B. Dodge 9/15
Thoughts (2)
Some good news:
All numbers in the computer are binary.
Furthermore, these binary numbers are immediately partitionable
into hex (as in the SPIM simulated console display).
Then any number input into the MIPS computer can be easily
separated into 4-bit nibbles, that represent hexadecimal digits.
N. B. Dodge 9/15
Thoughts (3)
Other considerations:
For simplicity, we will only use fixed-point, integral numbers,
(we have not covered floating-point programming).
Remember: System call 5 will take any number of digits in an
input. However, it truncates after the decimal number input
reaches the size of a 32-bit fixed-point representation (that is
0x ffff ffff, or about 2,150,000,000).
Worse yet, it truncates the most significant bits.
In order to forestall this problem we will limit inputs to eight
(8) decimal digits. The biggest 8-digit decimal number is
99,999,999 = 0x05f5e0ff, so we will always be able to represent
the decimal number properly in the conversion.
5
N. B. Dodge 9/15
Thoughts (4)
N. B. Dodge 9/15
Thoughts (5)
Since we want to output the converted hex number correctly, that
means that we must print out the most significant digit first,
proceeding to less significant digits in descending order (we read
numbers left-to-right starting with the most significant digit).
This suggests that we analyze the hex number starting with the
most significant digit, then the next-most-significant, and so on, so
that the printing order will be correct.
Due to the restriction of 8 decimal digits (99,999,999 max. size), the
left-most digit will always be 0. If the input number is much
smaller, more digits of the result will be 0.
Leading 0s can easily be discarded by a preliminary testing loop.
Note that after a non-zero number is encountered, we will want to
keep 0s interior to the number.
7
N. B. Dodge 9/15
Thoughts (6)
How can we analyze the eight-digit hex number
one digit at a time?
Use logical AND instruction to mask off or isolate
each 4-bit hex number.
The masked result will be a 32-bit number with
all 0s except where the 4-bit mask preserved 4 bits.
To simplify the loop, the mask should always be in
the same place.
We can use a shift or rotate instruction to get each
succeeding 4-bit nibble positioned under our mask.
8
N. B. Dodge 9/15
Thoughts (7)
Doing a rol 4 then an andi using a 0x 0000 000f mask will
result in a hex number (nibble) in the four LSB positions, and
also allows analysis of the most-significant hex digit first.
We put the number being analyzed in the four least significant
bit locations. Then the four bits can be analyzed as the single
hex digit that they represent (the other 28 bit positions = 0).
0x 0000 d000
This is d thousand, NOT hex d.
0x 0000 000d
This number is a hex d.
After converting the digit to the equivalent ASCII character,
we can either output using syscall 11 or store the character for
later output using syscall 4. By analyzing the most-significantdigit first, our print routine will print out digits in the correct
numeric order.
9
N. B. Dodge 9/15
Program Sequence
Now we can write down a the basic task sequence:
Loop sequence:
Rotate 4 most significant (leftmost) bits to right-most 4 bit
position.
Mask off those 4 bits and store in another register.
(Result is one hex digit [4-bits] in right 4 bit positions.)
Test to see if nibble = 0. Discard 0s until non-0 character found.
Convert binary nibbles to equivalent hex ASCII character.
Output using syscall 11 or store characters for later print-out.
Repeat for each 4-bit number until remaining digits are converted.
Print out digits (if not printed on the fly).
10
N. B. Dodge 9/15
Leading 0?
No
Yes
Decrement
counter ($tz)
No
Count = 0?
11
Yes
Number conversion
is complete.
Loop Mechanics
With the basic program flow laid out, the hex digit
analysis loop must be designed.
Since each 32-bit binary MIPS number is equivalently 8 hex
digits, we must go through the loop 8 times (remembering that
at least the first digit will always be a leading zero).
This means that we require a counter. This can be a register
that we initially set to 0.
Each time we traverse the loop and analyze one ASCII
character, we will add one to the register.
When the number in the register = 8, we will have gone
through the loop 8 times, and the analysis will be complete.
12
N. B. Dodge 9/15
N. B. Dodge 9/15
Data declarations:
prompt: .asciiz Enter decimal number (8 digits, maximum):
answer: .asciiz Hexadecimal number is: 0x
comp:
.asciiz Input another number (y/n)?
14
N. B. Dodge 9/15
Register Assignments
To keep it simple, lets assign registers now, so we will
be programming using a common set of designations.
We can use mainly the t-registers with one exception.
My suggestion:
Counter Use $t0 This will keep track of times through the
loop.
Register to hold hex digit (nibble) being analyzed Use $a0
(Why use this register?)
Register to hold original number input (transfer from $v0)
Use $t1
N. B. Dodge 9/15
Leading 0?
No
Yes
Convert 4-bit # in
$a0 to ASCII and
print.
$t0 $t0+1
No
Loop
count = 8?
16
Yes
Output is complete.
Output CR/LF so
that program is ready
for next conversion.
N. B. Dodge 9/15
N. B. Dodge 9/15
Program Prolog
# Lecture 16 Demo Program 1, Hex Number Conversion
#
#
#
#
#
#
18
N. B. Dodge 9/15
Data Declarations
Initial prompt to user
Data directive
.data
prompt: .asciiz Enter decimal number (8 digits, maximum): "
answer: .asciiz "Hexadecimal number is 0x" Answer leader
Program will do
comp: .asciiz "Input another number(y/n)?"
multiple conversions
19
N. B. Dodge 9/15
N. B. Dodge 9/15
Pre-Loop Software
main:
21
.text
la $a0,prompt
li $v0,4
syscall
li $v0,5
syscall
move $t1,$v0
la $a0,answer
li $v0,4
syscall
move $t0,$0
# Text declaration
# Load print out of prompt sequence
# Output prompt to enter decimal number
# Read integer to convert to hex
# Get number out of $v0
# Output answer header
N. B. Dodge 9/15
N. B. Dodge 9/15
23
N. B. Dodge 9/15
elim:
24
li $v0,11
rol $t1,$t1,4
N. B. Dodge 9/15
Converting to Hex
The big question: How to convert a hex digit to the
ASCII code for the character representing that digit?
Consider hexadecimal numbers 0-9 (0000-1001):
N. B. Dodge 9/15
N. B. Dodge 9/15
N. B. Dodge 9/15
Yes
Leading 0?
Yes
Eighth 0?
No
No
Yes
Rol 4 $t1,
AND with 0xf,
store in $a0
# = 0-9?
No
Add 7 to #
Add 48
to #
Print out a
0 as the
$t0 $t0+1,
final answer
No
Loop
count = 8?
Yes
Do
Another
#?
Yes
No
28
Halt
N. B. Dodge 9/15
N. B. Dodge 9/15
rol $t1,$t1,4
# Left rotate left digit to right-most position
and $a0,$t1,0xf # "Mask off" left-most digit
num: ble $a0,9,conv # Go to conv routine directly if hex # 0-9
add $a0,$a0,7 # Add 7 because hex number is a-f
conv: add $a0,$a0,48 # Convert number to ASCII
syscall
# Output ASCII representation of hex number
addi $t0,$t0,1 # Increment counter
blt $t0,8,loop # If analysis not complete, do loop again
j next
# Analysis complete; go to end routine
30
N. B. Dodge 9/15
N. B. Dodge 9/15
32
li $a0,0x0a
# Print out carriage return for neatness
syscall
la $a0,comp
# Convert another number to hex?
li $v0,4
syscall
li $v0,11
#
li $a0,0x0a
# Output CR/LF
syscall
#
li $v0,12
# Input answer (y = "Yes")
syscall
beq $v0,0x79,main # If yes, go back to start of program
li $v0,10
# End program
syscall
Lecture #16: SPIM Programming Example
N. B. Dodge 9/15
#
#
#
#
#
#
#
.text
main: la $a0,prompt # Load print out of prompt sequence
li $v0,4
# Output prompt to enter decimal number
syscall
li $v0,5
# Read integer to convert to hex
syscall
move $t1,$v0
la $a0,answer
# Output answer header
li $v0,4
syscall
move $t0,$0
# Clear counter
elim:
loop:
num:
33
li $v0,11
rol $t1,$t1,4
and $a0,$t1,0xf
bgtz $a0,num
addi $t0,$t0,1
beq $t0,8,zero
j elim
rol $t1,$t1,4
and $a0,$t1,0xf
ble $a0,9,conv
add $a0,$a0,7
conv:
add $a0,$a0,48
syscall
addi $t0,$t0,1
blt $t0,8,loop
j next
zero:
li $a0,0x30
syscall
next:
li $a0,0x0a
syscall
la $a0,comp
li $v0,4
syscall
li $v0,11
li $a0,0x0a
syscall
li $v0,12
syscall
beq $v0,0x79,main
li $v0,10
syscall
prompt:
answer:
comp:
#
34
.data
.asciiz Enter decimal number (8 digits, maximum): "
.asciiz "Hexadecimal number is 0x"
.asciiz "Input another number(y/n)?"
Summary
We have now defined, flow-charted, coded, and
checked out another program together.
In order to properly learn SPIM, you MUST do this
process a number of times.
As I am sure you have learned by now, the only way to
improve your programming skill is to do more
programming.
My experience: Unless you design 10-15 programs, as
you are required to do in your homework and labs and
class exercises, you reduce your chances of passing EE
2310. And that means on your own.
35
N. B. Dodge 9/15
Program 2
.text
main:
data1:
.data
.space 1
N. B. Dodge 9/15
Practice Assignment
Do the following: Add lines of code to the class
programming exercise program to (1) eliminate
negative numbers, and (2) eliminate all positive
numbers greater than 99,999,999.
38
N. B. Dodge 9/15