## LSU EE
3755 --10/13 Fall 2004 -- Computer Organization
#
## MIPS� Notes 4 -- Load and Store Instructions
#
## Contents
#
# Load Byte (Unsigned)
# Store Byte
# Load Byte
# Load Word, Store Word
# Load and Store Half
# Array Access Examples
# Histogram Program
## References
#
# :PH:� Patterson & Hennessy, "Computer
Organization & Design"
# :Mv1: MIPS
Technologies, "MIPS32 Architecture for Programmers Vol I: Intro"
# :Mv2: MIPS
Technologies, "MIPS32 Architecture for Programmers Vol II: Instr"
################################################################################
## Load Byte (Unsigned)
# :Syntax: LBU rt,
offset(rs)����������������� # Load Byte
Unsigned
#��������� rt <- { 24'b0, Mem[ rs + offset ]
}
#��������� Note: rs and rt are registers.
#��������� Offset is a 16-bit immediate
#��������� sign extended.
# :Example:
#
# Simple uses of lbu.
������� # Initially: $a2 <-- 0x0000 1000
������� # At Mem[ 0x0000 1004 ] = 0x12
������� #
������� lbu $a0, 4($a2)
������� #
������� # Effective address is 4 + 0x0000 1000
= 0x0000 1004.
������� # $a0 loaded with 0x0000 0012.
������� addi $a2, $a2, 4�� # $a2 <- 0x0000 1004
������� lbu $a0, 0($a2)
������� #
������� # Effective address is 0 + 0x0000 1004
= 0x0000 1004 (same as above.)
������� # $a0 loaded with 0x0000 0012 (again)
####
# :Example:
#
# Procedure to
determine the length of a C-style string.�
Includes
# code to call the
procedure.
������� .data
str:
������� .asciiz "EE3755 is probably a
cool class ."
msg:
������� .asciiz "The length of string
\n�� \"%/a1/s\"\nis
%/v1/d.\n"
������� .text
������� .globl __start
__start:
������� la $a0, str������������ # Load address of string.
������� jal strlen������������� # Call strlen procedure.
������� nop
������� addi $a1, $a0, 0���� ���# Move address of string to $a1
������� addi $v1, $v0, 0������� # Move length of string to $v1
������� addi $v0, $0, 11������� # System call code for message.
������� la $a0, msg������������ # Address of message.
������� syscall
������� addi $v0, $0, 10������� # System call code for exit.
������� syscall
strlen:
������� ## Register Usage
������� #
������� # $a0: Address of first character of
string.
������� # $v0: Return value, the length of the
string, $v0 holds the length of the string.
������� #
������� # $t0: Character being examined.
������� # $t1: Address of current character
being examined.
������� #
������� addi $t1, $a0, 0
LOOP:
������� lbu $t0, 0($t1)
������� addi $t1, $t1, 1
������� bne $t0, $0, LOOP
������� nop
������� addi $t1, $t1, -1
������� jr $ra
������� sub $v0, $t1, $a0
####
# Why� addi $t1, $t1, -1 ?
# Look at a memory
location . we assume only "EE3755\0".
#������������������� Memory
#��� msg:��
#������������������ 0x1000����� E�����
#������������������ 0x0001����� E
#������������������ 0x0002����� 3
#������������������ 0x0003����� 7
#������������������ 0x0004����� 5
#������������������ 0x0005����� 5
#������������������ 0x0006����� \0
# program at strlen
procedure.
#� t1� =
1000,��� t0 = E
#� t1�
=1001���� t0� = E
#� ��.......(assume it repeats till it loads "5".
#� t1�
=1005�� t0 = 5��
#� t1 = 1006��
t0 = \0 (now load null).
#� t1 = 1007��
# addi $t1,$t1, 1 // increments address by one
#����������������������������������������������������
although the character is null
#�������������������� # so we have to decrement
by one
#� t1 = 1006.�
t1 - a0 = 6� ==> v0..
#� so�
$v0 holds the length of the string.
################################################################################
## Store Byte
# :Syntax: SB rt,
offset(rs)����������������� # Store Byte
#��������� Mem[ rs + offset ] = rt[7:0]
# :Example:
#
# Simple uses of sb.
������� # Initially: $a2 <- 0x0000 1004
������� # At Mem[ 0x0000 1004 ] = 0
������� #
������� addi $t0, $0, 0x14��� # t0 <- 0x0000 0014
������� sb $t0, 0($a2)
������� #
������� # Effective address is 0 + 0x0000 1004
= 0x0000 1004
������� # 0x14 written to Mem[ 0x0000 1004 ]
������� addi $t0, $0, 0x1234�� # t0 <- 0x0000 1234
������� sb $t0, 0($a2)
������� #
������� # Effective address is 0 + 0x0000 1004
= 0x0000 1004
������� # 0x34 written to Mem[ 0x0000 1004 ]
������� # Note that only bits 7:0 of $t0
written to memory.
####
# :Example:
#
# Program to convert a
C-style string to upper case.
������� .data
str:
������� .asciiz "Hello, world!"
before:
������� .asciiz "Before: %/s1/s\n"
after:
������� .asciiz "After:� %/s1/s\n"
���������������
������� .text
������� .globl __start
__start:
������� la $s1, str
������� la $a0, before
������� addi $v0, $0, 11
������� syscall
������� jal upper
������� add $a0, $s1, $0
������� la $a0, after
������� addi $v0, $0, 11
������� syscall
������� li $v0, 10
������� syscall
upper:
������� ## Register Usage
������� #
������� # $a0: Address of string to convert.
������� #
������� # $a0: Address of character being
examined.
������� # $t1: Character being examined.
������� # $t2: Comparison result.
������ #��������� Check whether the character is upper case or not.
LOOP:
������� lbu $t1, 0($a0)
������� addi $a0, $a0, 1
������� beq $t1, $0, DONE
������� slti $t2, $t1, 97 # < 'a'�� // not a lower case.
������� bne $t2, $0 LOOP
������� slti $t2, $t1, 123 # 'z' + 1 // 97-122
lower case.
������� beq $t2, $0, LOOP# $t2 =1 means ,
character is lower case.
������� addi $t1, $t1, -32�� # change to upper case.
������� j LOOP
������� sb $t1,-1($a0)� #because of addi $a0,$a0,1
DONE:
������� jr $ra
������� nop
####
##� put ASCII table here
##
################################################################################
## Load Byte
# :Syntax: LB rt,
offset(rs)����������������� # Load Byte
#��������� rt <- sign_extend( Mem[ rs +
offset ] );
#��������� Note: rs and rt are registers.
#������� ��Offset is a 16-bit immediate.
# :Example:
#
#
# Initially: $a2 <-
0x0000 1000
# At Mem[ 0x0000 1000 ]
= 0x12���� // 12 = 0001 0010
# At Mem[ 0x0000 1001 ]
= 0x7f���� //� 7f� = 0111 1111
# At Mem[ 0x0000 1002 ]
= 0x80��� // 80� = 1000 0000�
(negative #)
# At Mem[ 0x0000 1003 ]
= 0xff����� // ff��� = 1111 1111 (negative #)��
#
������� lb $t0, 0($a2)� # $t0 <- 0x0000 0012������� 18
������� lb $t1, 1($a2)� # $t1 <- 0x0000 007f������� 127
� ������lb $t2, 2($a2)� # $t2
<- 0xffff ff80� (-128)
������� lb $t3, 3($a2)� # $t3 <- 0xffff ffff� (-1)
####
�## Usage
#
# lbu:� Characters, unsigned integers.
# lb:�� Signed integers.
################################################################################
## Load Word, Store
Word
�## Note
#
# Each memory location
holds 8 bits.
# Register size: 32
bits.
#
# To load a register
use lw (load word).
# Loads for consecutive
bytes into a register.
# :Syntax: LW rt,
offset(rs)
#��������� rt <- { Mem[ rs + offset + 3 ],
Mem[ rs + offset + 2 ],
#����������������� Mem[ rs + offset + 1 ], Mem[
rs + offset + 0 ]� }
#����������������
#��������� Load register rt with four bytes of
memory starting at address
#��������� rs + offset.
#��������� Address rs + offset must be a
multiple of 4.
# :Example:
#
������� # Assume: $a2<- 0x0000 1004
������� # At Mem[ 0x0000 1004 ] = 0x00003755
������� # More precisely:� (Little�
Endian)� //$$
������� #��
Mem[ 0x0000 1007 ] = 0x00
������� #��
Mem[ 0x0000 1006 ] = 0x00
������� #��
Mem[ 0x0000 1005 ] = 0x37
������� #��
Mem[ 0x0000 1004 ] = 0x55
������� #
������� lw $a0, 0($a2)
������� # 0x0000 3755 loaded into $a0
������� lw $a0, 2($a2)� # Error
������� # Effective address = 0x0000 1006, not
a multiple of 4
������� addi $a2, $a2, -2
������� lw $a0, 2($a2)� # No problem
������� # Effective address = 0x0000 1004, is
a multiple of 4
# :Example:
#
������� .data
my_word:
������� .word 123
������� .word 456
������� .text
������� la $t0, my_word
������� lw $t1, 0($t0)��� # t1 <- 123
������� lw $t2, 4($t0)��� # t2 <- 456
������� addi $t0, $t0, 4
������� lw $t3, 0($t0)��� # t3 <- 456� (Another way to load 456)
������� addi $t0, $t0, 4
������� lw $t4, -4($t0)�� # t4 <- 456� (And another way to load 456)
# Error, instruction
will never finish because address not a multiple of 4.
������� lw $t9, 1($t0)
####
# :Syntax: SW rt,
offset(rs)
#��������� Mem[ rs + offset+� 3 ] = rt[31:24]
#��������� Mem[ rs + offset + 2 ] = rt[23:16]
#��������� Mem[ rs + offset + 1 ] = rt[15:8]
#��������� Mem[ rs + offset + 0 ] = rt[7:0]
#��������� Write memory starting at address
offset + rs with contents of rt.
#��������� Effective address, rs + offset, must
be a multiple of 4.
# :Example:
#
������� # Assume: $a2, <- 0x0000 1004
������� # At Mem[ 0x0000 1004 ] = 0x00003755
������� # More precisely:� (Little�
Endian)
������� #��
Mem[ 0x0000 1007 ] = 0x00
������� #��
Mem[ 0x0000 1006 ] = 0x00
������� #��
Mem[ 0x0000 1005 ] = 0x37
������� #��
Mem[ 0x0000 1004 ] = 0x55
������� #
������� lui $a0, 0x1234
������� ori $a0, $a0, 0x5678� # $a0 <- 0x12345678
������� sw $a0, 0($a2)
������� #��
Mem[ 0x0000 1007 ] = 0x12
������� #��
Mem[ 0x0000 1006 ] = 0x34
������� #��
Mem[ 0x0000 1005 ] = 0x56
������� #��
Mem[ 0x0000 1004 ] = 0x78
������� lbu $t0, 3($a2)� # $t0 <- 0x0000 0012
������� lbu $t1, 2($a2)� # $t1 <- 0x0000 0034
������� lbu $t2, 1($a2)� # $t2 <- 0x0000 0056
������� lbu $t3, 0($a2)� # $t3 <- 0x0000 0078
������� lw $a0, 2($a2)� # Error
������� # Effective address = 0x1006, not a
multiple of 4
������� addi $a2, $a2, -2
������� lw $a0, 2($a2)� # No problem
������� # Effective address = 0x1004, is a
multiple of 4
####
################################################################################
## Load and Store Half
# :Syntax: LH rt,
offset(rs)������������������� # Load
Half
#��������� rt <- sign_extend( { Mem[ rs +
offset + 1� ], Mem[ rs + offset] } )
#��������� Load register rt with two bytes of
memory starting at address
#������ ���rs + offset.
#��������� Address rs + offset must be a
multiple of 2.
#
# :Syntax: LHU rt,
offset(rs)������������������ # Load Half
Unsigned
#��������� rt <- { 16'b0, Mem[ rs + offset
+1], Mem[ rs + offset] }
#��������� Load register rt with two bytes of
memory starting at address
#��������� rs + offset.
#��������� Address rs + offset must be a
multiple of 2.
#
# :Syntax: SH rt,
offset(rs)������������������� # Store
Half
#��������� Mem[ rs + offset + 1 ] = rt[15:8]
#��������� Mem[ rs + offset + 0 ] = rt[7:0]
#��������� Effective address, rs + offset, must
be a multiple of 2.
################################################################################
## Array Access
Examples
# :Example:
#
# Array accesses.� In most examples i is the index (the number
of the
# element to
load).� Note that i must be multiplied
by the size of the
# element before adding
it on to the address of the first element.
#
# Registers:� a, s1;�
b, s5;� s, s2;� us, s3; �c, s4;� i, t0;� x, t1
������� # char *c; ...����� # $s4 = c;� $t0 = i
������� # x = c[i];
������� #
������� add $t5, $s4, $t0�� # $t5 <- &c[i]� (Address of c[i].)
������� lb $t1, 0($t5)����� # x = c[i];�� $t1 <- c[i]�
������� # char *c; ...����� # $s4 = c;� $t0 = i
������� # x = c[i+1] + c[i+2];
������� #
������� # beginner's� way to compile� above
code(not efficient).
������� # pay attention to the addressing
mode.
�
�� �addi $t2,$t0,1���������������������������� #i+1;
��������� add $t5, $s4, $t2����� ����������������# $t5 <- &c[i+1]� (Address of c[i+1].)
��������� lb $t6,0($t5)������������������������������ #�� t6<= c[i+1]
�������� addi $t3,$t0,2��������������������������� # i +2;
�������� add $t5,$s4,$t3������������������������ #$t5
<-&c[i+2]�
�������� lb $t7,0($t5)������������������������������� # t7 <=
c[i+2]�
�������� add $t1,$t6,$t7������������������������� # x = c[i+1]+c[i+2]
������
������� # so 7 lines of code. see below a
little bit better use of
������� # addressing mode(4 lines)
�� �����add $t5, $s4, $t0�� #
$t5 <- &c[i]� (Address of c[i].)
������� lb $t6, 1($t5)����� # $t6 <-� c[i+1]
������� lb $t7, 2($t5)����� # $t7 <- c[i+2]
������� add $t1, $t6, $t7�� # x = c[i+1] + c[i+2]
������� # int *a; ...������ # $s1 = a;� $t0 = i
������� # x = a[i];
������� sll $t5, $t0, 2���� # $t5 <- i * 4;� Each element is four characters.
������� add $t5, $s1, $t5�� # $t5 <- &a[i]� (Address of a[i].)
������� lw $t1, 0($t5)����� # x = a[i];�� $t1 <- a[i]
������� # int *a; ...������ # $s1 = a;� $t0 = i
������� # x = a[i+1] + a[i+2];
������� #
������� sll $t5, $t0, 2���� # $t5 <- i * 4;� Each element is four characters.
������� add $t5, $s1, $t5�� # $t5 < - &a[i]� (Address of a[i].)
������� lw $t6, 4($t5)����� # $t6 <- a[i+1]
������� lw $t7, 8($t5)����� # $t7 <- a[i+2]
������� add $t1, $t6, $t7�� # x = a[i+1] + a[i+2]
������� # int x, j, *a, *b; # $t1 = x;� $t2 = j;�
$s1 = a;� $s2 = b
������� # j = 3;
������� # b = a + j;��� //pay attention to this add operation
������� #������������������� // if a = 0x1000 and j = 3, then b= a+j�
������� #������������������ //�����
which will NOT be� 1003 =� 1000 + 3.
������� #������������������ // since a is pointer, we should add like this
following:
������� #���������������� ��//�� 1000( a) +�� 3(j) * size of varialbe.
������� #������������������ //� so
a+j = 1000 + 3 * 4;
������� #����������������� //�����
a+j = 100c.
��������
������� # x = *b;����� // x = a[3];
������� addi $t2, $0, 3���� # j = 3;
������� sll $t5, $t2, 2�� ��#
$t5 <- j * 4
������� add $s5, $s1, $t5�� # b = a + j;//address of a[3]
������� lw $t1, 0($s5)����� # x = *b = a[j]� = a[3]
������� # short *s; ...���� # $s2 = s;� $t0 = i� // short is
2bytes long.
������� # x = s[i];
������� #
������� sll $t5, $t0, 1 ����# $t5 <- i * 2;� Each element is two characters.
������� add $t5, $s2, $t5�� # $t5<-�
&s[i]� (Address of s[i].)
������� lh $t1, 0($t5)����� # x = s[i];�� $t1<- s[i]
������� #�������������������� $s3 = us;�
$t0 = i
������� # unsigned short *us;
������ �# x = us[i];
������� #
������� sll $t5, $t0, 1���� # $t5 <- i * 2;� Each element is two characters.
������� add $t5, $s3, $t5�� # $t5 <- &us[i]� (Address of us[i].)
������� lhu $t1, 0($t5)����� # x = us[i];�� $t1 <- us[i]�
�������������������������������������� # using
"lhu" instead of "lh"
####
################################################################################
## Histogram Program
�## Histogram Program.
#
# Computes how many
times each letter appears in a string.
#
# For example, for the
following string:
#
#� We hold these truths to be self-evident that
all men are created
#� equal, that they are endowed by their
Creator with certain unalienable
#� Rights, that among these are Life, Liberty,
and the pursuit of
#� Happiness. That to secure these rights,
Governments are instituted
#� among Men, deriving their just powers from
the consent of the
#� governed.�
That whenever any Form of Government becomes destructive of
#� these ends, it is the Right of the People to
alter or to abolish it,
#� and to institute new Government, laying its
foundation on such
#� principles and organizing its powers in such
form, as to them shall
#� seem most likely to effect their Safety and
Happiness
#
# The program would
generate the counts shown below:
#
#� Letter A�
count:� 33 (� 5.05) ****************
#� Letter B�
count:�� 6 (� 0.92) ***
#� Letter C�
count:� 11 (� 1.68) *****
#� Letter D�
count:� 15 (� 2.30) *******
#� Letter E�
count:� 77 ( 11.79)
**************************************
#� Letter F�
count:� 14 (� 2.14) *******
#� Letter G�
count:� 13 (� 1.99) ******
#� Letter H�
count:� 32 (� 4.90) ****************
#� Letter I�
count:� 36 (� 5.51) ******************
#� Letter J�
count:�� 1 (� 0.15)
#� Letter K�
count:�� 1 (� 0.15)
#� Letter L�
count:� 18 (� 2.76) *********
#� Letter M�
count:� 14 (� 2.14) *******
#� Letter N�
count:� 39 (� 5.97) *******************
#� Letter O�
count:� 36 (� 5.51) ******************
# �Letter P�
count:� 11 (� 1.68) *****
#� Letter Q�
count:�� 1 (� 0.15)
#� Letter R�
count:� 34 (� 5.21) *****************
#� Letter S�
count:� 36 (� 5.51) ******************
#� Letter T�
count:� 65 (� 9.95) ********************************
#� Letter U�
count:� 13 (� 1.99) ******
#� Letter V�
count:�� 8 (� 1.23) ****
#� Letter W�
count:�� 7 (� 1.07) ***
#� Letter Y�
count:�� 7 (� 1.07) ***
#� Letter Z�
count:�� 1 (� 0.15)
#
#� For Example:
# Memory :
# 0x1000� :�� W
# 0x1001� :�� e
# 0x1002� :
# 0x1003� :�� h
# 0x1004� :�� o
# 0x1005� :�� l
# 0x1006� :�� d
�� ....
�� ....
�
# str <=0x1000;
# Table :������������������ //we assume� 0x 7000;
# 0x 7000�
# 0x 7001
# 0x 7002
# 0x 7003������������������� //we save int:� the number�
of occurence of "A"��
# 0x 7004
# 0x 7005
# 0x 7006
# 0x 7007������������������ //��� the number of occurence of
"B"������
..
..���������������������������� .......
# 0x 7058������������������ //���� the number of occurence of "W"
#
#��� (c ="W") -'A'
#�������� 87 - 65
#��� index <= 22.����� 22 *� 4=� 88(decimal)
#������������������������������� 88 = 0x58
#��� table[index]++;�������� ..
# Here is such a
histogram procedure written in C:
#
#
# Unoptimized:
#
# void
# histo(char *str, int
*table)
# {
#�� upper(str);
#
#�� for(; *str; str++)
#���� {
#������ char c��� = *str;
#������ int index = c - 'A';
#
#������ if( index >= 0 && index
<= 25 )
#�������� table[ index ]++;
#���� }
# }
#
#
# Optimized:
#
# void
# histo2(unsigned char
*str, int *table)
# {
#�� upper(str);
#
#�� for(; *str; str++)
#���� {
#������ unsigned int index = *str - 'A';
#
#������ if( index < 26 )
#�������� table[ index ]++;
#
#���� }
# }
#
#
# The assembler version
of the procedure is to be called with register
# $a0 set to the address
of the first character of the string and $a1
# set to the address of
the first element of the histogram table.
#
# The code below is
just the histogram procedure.� The
program
# used to generate the
table above� is at the end of this
notes.
histo:
������� ## Register Usage
������� #
������� # Call: $a0� String to analyze.
������� #���������� $a1� Address of
table.� Each element is an integer.
������� addi $s0, $ra, 0��� # Make a copy of the return address.
������� jal upper���������� # Convert to upper case.
������� addi $t0, $a0, 0��� # Make a copy of string start address.
������� addi $ra, $s0, 0��� # Restore return address.
LOOP:
������� lbu $t1, 0($t0)���� # Load a character.
������� addi $t0, $t0, 1��� # Increment address.
������� beq $t1, $0, DONE�� # Check for null termination.
������� addi $t1, $t1, -65� # Set $t1 to table index. ( A->0,
B->1, etc.)
������� sltiu $t2, $t1, 26�� # If $t1 is >= 26 then it's not a
letter.
������� beq $t2, $0, LOOP�� # Note that comparison above is unsigned.
�� �����sll $t1, $t1, 2���� #
Scale index.
������� add $t3, $a1, $t1�� # Add index on to address of first element
������� lw $t4, 0($t3)����� # Load histogram entry.
������� addi $t4, $t4, 1
������� j LOOP
������� sw $t4, 0($t3)����� # Store the incremented value.
DONE:
������� jr $ra
������� nop
####
# Assembly language
generated by gcc for unoptimized version:
#
# Comment text in
square brackets describe activities not covered in 3755.
#
$Lscope0:
����������� .align� 2
����������� .globl� histo
����������� .text
$LM6:
# hist.c:11: {
����������� .ent���� histo
histo:
����������� .frame����������� $sp,32,$ra���������������� # vars= 0, regs= 3/0, args= 16,
extra= 0
����������� .mask 0x80030000,-8
����������� .fmask����������� 0x00000000,0
$LBB2:
����������� subu� $sp,$sp,32����� # [Increment stack pointer.]
����������� sw������ $s0,16($sp)���� # [Save register s0, restored before
return.]
����������� move� $s0,$a0
����������� sw������ $s1,20($sp)���� # [Save register s1, restored before
return.]
����������� sw������ $ra,24($sp)���� # [Save register ra, restored before
return.]
$LM7:
# hist.c:12:�� upper(str);
����������� .set���� noreorder
����������� .set���� nomacro
����������� jal������� upper
����������� move� $s1,$a1�������� # Make a copy of $a1.
����������� .set���� macro
����������� .set���� reorder
$LM8:
# hist.c:14:�� for(; *str; str++)
����������� lb�������� $v0,0($s0)����� # Load first character of string, sign
extended.
����������� lbu����� $a0,0($s0)����� # Load first character of string again.
����������� .set���� noreorder
����������� .set���� nomacro
����������� beq���� $v0,$zero,$L26
����������� sll������� $a3,$a0,24����� # First of two instructions to
sign-extend
����������� .set���� macro���������� # loaded character. (I don't know
why
����������� .set���� reorder�������� # compiler didn't just use $v0.)
$LBB3:
$LM9:
# hist.c:16:������ char c��� = *str;
$L27:
����������� sra����� $v1,$a3,24����� # Finish sign extension.
$LM10:
# hist.c:17:������ int index = c - 'A';
����������� addu� $a1,$v1,-65
����������� sll������� $a2,$a1,2
$LM11:
# hist.c:19:������ if( index >= 0 && index
<= 26 )
����������� sltu���� $a0,$a1,27����� # Note: unsigned comparison, so no need
������������������������������� # to check for
index >= 0.
$LM12:
# hist.c:16:������ char c��� = *str;
����������� addu� $s0,$s0,1������ # This is really : str++
$LM13:
# hist.c:19:������ if( index >= 0 && index
<= 26 )
����������� .set���� noreorder
����������� .set���� nomacro
����������� beq���� $a0,$zero,$L11
����������� addu� $v1,$a2,$s1���� # $v1 -> &table[ index ];
����������� .set���� macro
����������� .set���� reorder
$LM14:
# hist.c:20:�������� table[ index ]++;
����������� lw������� $t1,0($v1)
����������� #nop
����������� addu� $t0,$t1,1
����������� sw������ $t0,0($v1)
$LBE3:
$LM15:
# hist.c:14:�� for(; *str; str++)
$L11:
����������� lb�������� $t2,0($s0)����� # Load character of string, sign
extended.
����������� lbu����� $a0,0($s0)����� # Load character of string again.
����������� .set���� noreorder
����������� .set���� nomacro
����������� bne���� $t2,$zero,$L27
����������� sll������� $a3,$a0,24����� # First of two instructions to
sign-extend
����������� .set���� macro���������� # loaded character. (I don't know
why
����������� .set���� reorder�������� # compiler didn't just use $t2.)
$L26:
����������� lw������� $ra,24($sp)���� # [Restore saved $ra]
����������� lw������� $s1,20($sp)���� # [Restore saved $s1]
����������� lw������� $s0,16($sp)���� # [Restore saved $s0]
����������� #nop
����������� .set���� noreorder
����������� .set���� nomacro
����������� j���������� $ra
����������� addu� $sp,$sp,32����� # [Restore stack pointer.]
����������� .set���� macro
����������� .set���� reorder
$LBE2:
����������� .end��� histo
#############################################
##complete code for
histogram and generating table
������ .data
doi:
������� .ascii
"We hold these truths to be self-evident that all men "
������� .ascii
"are created equal, that they are endowed by their "
������� .ascii
"Creator with certain unalienable Rights, that among "
������� .ascii
"these are Life, Liberty, and the pursuit of "
������� .ascii
"Happiness. That to secure these rights, Governments "
������� .ascii
"are instituted among Men, deriving their just powers "
������� .ascii
"from the consent of the governed.�
That whenever any "
������� .ascii
"Form of Government becomes destructive of these ends, "
������� .ascii
"it is the Right of the People to alter or to abolish "
������� .ascii
"it, and to institute new Government, laying its "
������� .ascii
"foundation on such principles and organizing its "
������� .ascii
"powers in such form, as to them shall seem most likely "
������� .asciiz
"to effect their Safety and Happiness "
�
msg:
������� .asciiz
"Letter %/t3/c� count: %/t1/3d
(%/f4/6.2f%%) %/t5/s\n";
�
������� .align
4
histogram_data:
������� .space
104
stars:
���� ���.space 40
�
������� .text
������� .globl
__start
__start:
������� la
$a0, doi
������� la
$a1, histogram_data
������� addi $t1,
$a1, 0
������� addi $t2,
$t1, 100
L3:
������� sw $0, 0($t1)
������� bne $t1, $t2,
L3
������� addi $t1,
$t1, 4
�
������� la
$t1, stars
������� addi $t2,
$t1, 40
������� addi $t3, $0,
42� # '*'
L4:
������� sb $t3,
0($t1)
������� bne $t1, $t2,
L4
������� addi $t1,
$t1, 1
������� sb $0, 0($t1)
�
������� jal strlen
������� nop
������� mtc1 $v0, $f2
������� cvt.d.w $f2,
$f2
������ �addi $v0, $0, 100
������� mtc1 $v0, $f4
������� cvt.d.w $f4,
$f4
������� div.d $f2,
$f4, $f2
�
������� jal histo
������� nop
������� add $t0, $0,
$0
������� addi $t3, $0,
64
������� addi $t4,
$t3, 26
������� la
$s1, histogram_data
������� addi $v0, $0,
11
������� la
$s2, stars
������� addi $s2,
$s2, 41
L2:
������� lw $t1,
0($s1)
������� addi $s1,
$s1, 4
������� beq $t1, $0,
TEST
������� addi $t3,
$t3, 1
������� srl $t6, $t1,
1
������� sub $t5, $s2,
$t6
������� mtc1 $t1, $f0
������� cvt.d.w $f0,
$f0
������ �mul.d $f4, $f0, $f2
������� syscall
TEST:
������� bne $t3, $t4,
L2
������� nop
�
������� addi $v0, $0,
10
������� syscall
�
�
################################################################################
## histo: Compute Character Usage Histogram
�
histo:
������� ## Register
Usage
������� #
������� # Call:
$a0� String to analyze.
������� #������ $a1�
Address of table.� Each element
is an integer.
�
������� addi $s0,
$ra, 0��� # Make a copy of the return
address.
������� jal
upper���������� # Convert to upper case.
������� addi $t0,
$a0, 0��� # Make a copy of string start
address.
������� addi $ra,
$s0, 0��� # Restore return address.
�
LOOP:
������� lbu $t1,
0($t0)���� # Load a character.
������� addi $t0,
$t0, 1��� # Increment address.
������� beq $t1, $0,
DONE�� # Check for null termination.
������� addi $t1,
$t1, -65� # Set $t1 to table index. (
A->0, B->1, etc.)
������� sltiu $t2,
$t1, 26� # If $t1 is >= 26 then it's
not a letter.
������� beq $t2, $0,
LOOP�� # Note that comparison above is
unsigned.
������� sll $t1, $t1,
2���� # Scale index.
������� add $t3, $a1,
$t1�� # Add index on to address of first
element
������� lw $t4,
0($t3)����� # Load histogram entry.
������� addi $t4,
$t4, 1
������� j LOOP
������� sw $t4,
0($t3)����� # Store the incremented
value.
�
DONE:
������� jr $ra
������� nop
�
�
################################################################################
## upper: Convert to Upper Case
�
upper:
������� ## Register
Usage
������� #
������� # $a0: (Call)
Address of string to convert.
������� #
������� # $a0:
Address of character being examined.
������� # $t1:
Character being examined.
������� # $t2:
Comparison result.
ULOOP:
������� lbu $t1,
0($a0)
������� addi $a0,
$a0, 1
������� beq $t1, $0,
UDONE
������� slti $t2,
$t1, 97 # < 'a'
������� bne $t2, $0
ULOOP
������� slti $t2,
$t1, 123 # 'z' + 1
������� beq $t2, $0,
ULOOP
������� addi $t1,
$t1, -32
������� j ULOOP
������� sb
$t1,-1($a0)
�
UDONE:
������� jr $ra
������� nop
�
�
################################################################################
## strlen: String Length
�
strlen:
������� ## Register
Usage
������� #
������� # $a0:
Address of first character of string.
������� # $v0: Return
value, the length of the string.
������� #
������� # $t0:
Character being examined.
������� # $t1:
Address of current character being examined.
������� #
������� addi $t1,
$a0, 0
SLOOP:
������� lbu $t0,
0($t1)
������� bne $t0, $0,
SLOOP
������� addi $t1,
$t1, 1
�
������� addi $t1,
$t1, -1
������� jr $ra
������� sub $v0, $t1,
$a0