MIPS填充数据多个数组

时间:2016-06-01 14:47:22

标签: arrays assembly mips

我有一个来自uni的作业,我们必须创建一个执行以下功能的小程序:

1)创建一个新的个人资料(姓名,姓氏,兴趣,visibilityFlag ecc)

2)搜索个人资料(搜索个人资料的可见性必须为真)

3)删除自己的个人资料

4)显示所有5个配置文件(即使是那些具有虚假性的配置文件)

5)退出(刚完成程序)

所以我已经编写了一些代码,我为配置文件创建了5个数组,但是当我选择创建配置文件时,我开始从profile1创建它,之后prof命令将返回主菜单如果我想创建另一个配置文件只是做同样的,但我无法创建第二个配置文件,我只是一遍又一遍地覆盖第一个数据,我找不到传递给每个数组的方法,直到第五个阵列。

这是我的代码:

.data

## STRINGs MAIN MENU ##

welcome:        .asciiz "\n\n\n********* WELCOME ***********\n\n\n\n"
objective:          .asciiz "******************************************************\n\n the program task is to create max 5 profiles
and and being able to modify the data of your own 
profile,erase your profile ,search for visibiles profiles 
and output all the profiles even not visibles ones\n\n******************************************************"
choose:         .asciiz "\n\n- what you wanna do?\n"
options:        .asciiz "\n0)Create Profile\n1)Search Profile\n2)Erase Profilo\n3)Show all profiles\n4)Esci\n"
answer:         .asciiz "\n\nAnswer:"
exitMsg:        .asciiz  "\n\nBYE BYE\n"
msgError:       .asciiz "\n\n\nERROR, only numbers from 0-4n\n"

## STRING CREATE PROFILE##

Header:         .asciiz "\n** CREATE PROFILE ** \n"
name:           .asciiz "\n\n- Nome:"
surname:        .asciiz "\n- Cognome:"
interests:      .asciiz "\n\n- Interessi:\n"
userID:         .asciiz "\n- UserID:"
password:       .asciiz "\n- Password:"
email:          .asciiz "\n\n- Email:"
visibility:     .asciiz "\n- Visibilita:"
succes:         .asciiz "\n\n****** PROFILE CREATED ******\n\n"
optionsProfile: .asciiz "\n\n0)Modify Profile  1)Go back to main menu\n\n"

## STRINGS SEARCH ##

nameSearch : .space 256
surnameSearch : .space 256

## STRINGS SHOW PROFILES ##
userID_mp:         .asciiz "\nUserID:"
name_mp:           .asciiz "\nName:"
surname_mp:        .asciiz "\nSurname:"
interests_mp:      .asciiz "\nInterests:"
newLine:           .asciiz "\n"

profile1:   .asciiz "\n\n\n\n** Profilo 1\n"
profile2:   .asciiz "\n\n* Profilo 2\n"
profile3:   .asciiz "\n\n* Profilo 3\n"
profile4:   .asciiz "\n\n* Profilo 4\n"
profile5:   .asciiz "\n\n* Profilo 5\n"
profile6:   .asciiz "\n\n* Profilo 6\n"
profile7:   .asciiz "\n\n* Profilo 7\n"
profile8:   .asciiz "\n\n* Profilo 8\n"
profile9:   .asciiz "\n\n* Profilo 9\n"
profile10:  .asciiz "\n\n* Profilo 10\n"
newLine3:  .asciiz "\n\n\n"
backToMainMenu: .asciiz "\n\n\n0)Back to main menu\n"

## PROFILES ##

Profile1:   .word name1,surname1,interests1,userID1,visibility1,email1,password1
name1:       .space 256
surname1:    .space 256
interests1:  .space 256
userID1:     .space 256
visibility1: .space 256
email1:      .space 256
password1:   .space 256

Profile2:   .word name2,surname2,interests2,userID2,visibility2,email2,password2
name2:       .space 256
surname2:    .space 256
interests2:  .space 256
userID2:     .space 256
visibility2: .space 256
email2:      .space 256
password2:   .space 256

Profile3:   .word name3,surname3,interests3,userID3,visibility3,email3,password3
name3:       .space 256
surname3:    .space 256
interests3:  .space 256
userID3:     .space 256
visibility3: .space 256
email3:      .space 256
password3:   .space 256

Profile4:   .word name4,surname4,interests4,userID4,visibility4,email4,password4
name4:       .space 256
surname4:    .space 256
interests4:  .space 256
userID4:     .space 256
visibility4: .space 256
email4:      .space 256
password4:   .space 256

Profile5:   .word name5,surname5,interests5,userID5,visibility5,email5,password5
name5:       .space 256
surname5:    .space 256
interests5:  .space 256
userID5:     .space 256
visibility5: .space 256
email5:      .space 256
password5:   .space 256



.text

main:

Main_Menu:

## the main menu functions ##


li $v0,4
la $a0,welcome
syscall

li $v0,4
la $a0,objective
syscall

li $v0,4
la $a0,choose
syscall

li $v0,4
la $a0,options
syscall

li $v0,4
la $a0,answer
syscall

## READ INPUT AND SAVES IN $t0 ##
li $v0,5  
syscall 
move $t0,$v0 # salva la scelta in t0


## CHOOSE ONE FUNCTION##

## counter?
li $s0,1

li $t1, 0
beq $t0, $t1, Create_Profile        # Create a Profile starting from 1 ending 5

li $t1, 1
beq $t0, $t1, Search_Profile        # Search a Public profile 

li $t1, 2
beq $t0, $t1, Erase_Profile         # Erase your profile

li $t1, 3
beq $t0, $t1, Show_Profiles         # Show all profiles

li $t1, 4
beq $t0, $t1, Exit                  # Just finish


la $a0, msgError                
li $v0,4
syscall
j Main_Menu



## FUNCTIONS ##

Create_Profile:

## start from 1 , come back to main_menu and create the second , come back again and the third...

li $s5,1

li $t0,1
beq $s5,$t1,createProfile1



li $t1,2
beq $s5,$t1,createProfile2


## and the rest

createProfile1:

li $t0,1

addi $s5, $s5, 4

li $v0,4
la $a0,name
syscall

la $a0, name1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,surname
syscall

la $a0, surname1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,interests
syscall

la $a0, interests1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,userID
syscall

la $a0, userID1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,password
syscall

la $a0, password1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,email
syscall

la $a0, email1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,visibility
syscall

la $a0, visibility1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0, succes
syscall


j options_Profile

createProfile2:

li $t0,2

li $v0,4
la $a0,nome
syscall

la $a0, nome2
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,cognome
syscall

la $a0, cognome2
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,interessi
syscall

la $a0, interessi2
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,userID
syscall

la $a0, userID2
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,password
syscall

la $a0, password2
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,email
syscall

la $a0, email2
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,visibilita
syscall

la $a0, visibilita2
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0, succes
syscall


j options_Profile


createProfile3:
createProfile4:
createProfile5:
createProfile6:
createProfile7:
createProfile8:
createProfile9:
createProfile10:


options_Profile:

## show some options

li $v0,4
la $a0, optionsProfile
syscall

li $v0,4
la $a0,answer
syscall

## read an Integer
li $v0,5
syscall 
move $t0,$v0

li $s1,1
beq $t0,$s1,Main_Menu

li $s1,0
beq $t0,$s1,Modify_Profile





Modify_Profile:

li $t1,1
beq $t0,$t1,Mod_Profile1


li $t1,2
beq $t0,$t1,Mod_Profile1



Mod_Profile1:

## Just do the same like when you create a profile

li $t0,1

addi $s5, $s5, 4

li $v0,4
la $a0,name
syscall

la $a0, name1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,surname
syscall

la $a0, surname1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,interests
syscall

la $a0, interests1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,userID
syscall

la $a0, userID1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,password
syscall

la $a0, password1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,email
syscall

la $a0, email1
li $a1, 256
li $v0, 8
syscall

li $v0,4
la $a0,visibility
syscall

la $a0, visibility1
li $a1, 256
li $v0, 8
syscall



la $a0, backToMainMenu  ## opzion torna al menu p...
li $s0,4
syscall

li $v0,5
syscall 
move $t0,$v0


li $s1,0
beq $t0,$s1,Main_Menu




Search_Profile:

la $a0, nome                
li $v0,4  
syscall

la $a0, nomeCerca
li $a1, 256
li $v0, 8
syscall

la $a0, cognome                
li $v0,4  
syscall

la $a0, cognomeCerca  
li $a1, 256
li $v0, 8
syscall


Erase_Profile:



Show_Profiles:

li $t0,1

beq $t0,1,Show_Profile1
addi $t0, $t0, 4

beq $t0,2,Show_Profile2
addi $t0, $t0, 4

beq $t0,3,Show_Profile3
addi $t0, $t0, 4

beq $t0,4,Show_Profile4
addi $t0, $t0, 4

beq $t0,5,Show_Profile5
addi $t0, $t0, 4

beq $t0,11,go_MainMenu





Show_Profile1:


la $a0, profile1   
li $v0,4  
syscall

la $s0, Profile1   

la $a0,userID_mp
li $v0,4
syscall

lw $t1,12($s0)
la $a0,0($t1)
li $v0,4
syscall

la $a0,name_mp     
li $v0,4
syscall

lw $t1,0($s0)       
la $a0,0($t1)      
li $v0,4
syscall


la $a0,surname_mp     
li $v0,4
syscall

lw $t1,4($s0)
la $a0,0($t1)
li $v0,4
syscall


la $a0,interests_mp   
li $v0,4
syscall

lw $t1,8($s0)
la $a0,0($t1)
li $v0,4
syscall

Show_Profile2:

la $a0, profile2   
li $v0,4  
syscall

la $s0, Profile2   

la $a0,userID_mp
li $v0,4
syscall

lw $t1,12($s0)
la $a0,0($t1)
li $v0,4
syscall

la $a0,name_mp    
li $v0,4
syscall

lw $t1,0($s0)      
la $a0,0($t1)     
li $v0,4
syscall


la $a0,surname_mp    
li $v0,4
syscall

lw $t1,4($s0)
la $a0,0($t1)
li $v0,4
syscall


la $a0,interests_mp 
li $v0,4
syscall

lw $t1,8($s0)
la $a0,0($t1)
li $v0,4
syscall

Show_Profile3:

la $a0, profile3  
li $v0,4  
syscall

la $s0, Profile3 

la $a0,userID_mp
li $v0,4
syscall

lw $t1,12($s0)
la $a0,0($t1)
li $v0,4
syscall

la $a0,name_mp      
li $v0,4
syscall

lw $t1,0($s0)      
la $a0,0($t1)      
li $v0,4
syscall


la $a0,surname_mp    
li $v0,4
syscall

lw $t1,4($s0)
la $a0,0($t1)
li $v0,4
syscall


la $a0,interests_mp   
li $v0,4
syscall

lw $t1,8($s0)
la $a0,0($t1)
li $v0,4
syscall


Show_Profile4:


la $a0, profile4   ## number
li $v0,4  
syscall

la $s0, Profile4   ## adress

la $a0,userID_mp
li $v0,4
syscall

lw $t1,12($s0)
la $a0,0($t1)
li $v0,4
syscall

la $a0,name_mp       ## name
li $v0,4
syscall

lw $t1,0($s0)      ## adress
la $a0,0($t1)     
li $v0,4
syscall


la $a0,surname_mp     ## surname
li $v0,4
syscall

lw $t1,4($s0)
la $a0,0($t1)
li $v0,4
syscall


la $a0,interests_mp   ## interests
li $v0,4
syscall

lw $t1,8($s0)
la $a0,0($t1)
li $v0,4
syscall


Show_Profile5:


la $a0, profile5    ## number profile
li $v0,4  
syscall

la $s0, Profile5   ## adress 

la $a0,userID_mp
li $v0,4
syscall

lw $t1,12($s0)
la $a0,0($t1)
li $v0,4
syscall

la $a0,name_mp       ## nome
li $v0,4
syscall

lw $t1,0($s0)      ## direccion de nome1 
la $a0,0($t1)      ## stampa nome1
li $v0,4
syscall


la $a0,surname_mp     ## cognome
li $v0,4
syscall

lw $t1,4($s0)
la $a0,0($t1)
li $v0,4
syscall


la $a0,interests_mp   ## interessi
li $v0,4
syscall

lw $t1,8($s0)
la $a0,0($t1)
li $v0,4
syscall




go_MainMenu:

la$a0,backToMainMenu
li $s0,4
syscall

li $v0,5  
syscall 
move $t0,$v0

li $s1,0
beq $t0,$s1,Main_Menu


Exit:

la $a0, exitMsg
li $v0, 4
syscall

li $v0,10 # exit
syscall

我在SPIM模拟器中运行我的程序。

抱歉我的英文不好

1 个答案:

答案 0 :(得分:1)

您正在为每个配置文件创建单独的功能。但是,假设您必须拥有10,000个单独的配置文件而不仅仅是5个?

使用等效的C结构数组会更容易。在asm,a" struct"被表征为来自基地址的偏移/长度。这是一个重要的概念,因为它使您的程序更多更简单

我重新设计了你的程序,使用一个结构和一个使用sbrk系统调用动态分配的数组。

我用于偏移定义的语法是spim理解的语法。如果您使用mars作为模拟器,我可以重新生成并重新下载我的代码。

我创建了所有五个基本操作。我没有处理可见性,因为我不明白它的含义[确切]和字段值是什么(例如可见 - >" true"或" 1"?等。)

我尽可能地保持对你的代码的忠诚,但我不得不改变很多。

另外,在我看到你的另一个问题之前,搜索标准对我来说并不是很清楚。搜索会提示输入要匹配的字符串。然后它尝试匹配配置文件中的所有字段[vs.提示输入给定的字段名称]。这可能不是您想要/需要的,但它实现起来更简单,并且通常是某些系统运行的方式。

无论如何,这里的代码[请原谅无偿的风格清理]:

# global registers:
#   s0 -- main menu selection
#   s1 -- profile number (1-n)
#   s2 -- pointer to profile
#   s3 -- pointer to profile field
#   s4 -- pointer to field processing function

    .data

sdata:
#@+
# NOTE: this is what a C struct for a profile would look like
#   struct profile {
#       char prof_name[256];
#       char prof_surname[256];
#       char prof_interests[256];
#       char prof_userID[256];
#       char prof_visibility[256];
#       char prof_email[256];
#       char prof_password[256];
#   };
#@-

    # this is how we define it for mips -- as offsets from a base register

    prof_name = 0
    prof_name_sizeof = 256

    prof_surname = prof_name + prof_name_sizeof
    prof_surname_sizeof = 256

    prof_interests = prof_surname + prof_surname_sizeof
    prof_interests_sizeof = 256

    prof_userID = prof_interests + prof_interests_sizeof
    prof_userID_sizeof = 256

    prof_visibility = prof_userID + prof_userID_sizeof
    prof_visibility_sizeof = 256

    prof_email = prof_visibility + prof_visibility_sizeof
    prof_email_sizeof = 256

    prof_password = prof_email + prof_email_sizeof
    prof_password_sizeof = 256

    profile_sizeof = prof_password + prof_password_sizeof

    ###.eqv PROFMAX         5

profiles:   .word       0               # pointer to profile array

    # # STRINGs MAIN MENU ##

welcome:    .asciiz     "\n\n********* WELCOME ***********\n\n"
objective:  .ascii      "******************************************************\n"
    .ascii  "the program task is to create max 5 profiles\n"
    .ascii  "and being able to modify the data of your own profile\n"
    .ascii  "erase your profile\n"
    .ascii  "search for visibile profiles\n"
    .ascii  "and output all the profiles even not visibles ones\n\n"
    .asciiz "******************************************************\n"

choose:     .asciiz     "\n\n- what you wanna do?\n"
options:    .ascii      "0) Create Profile\n"
    .ascii  "1) Search Profile\n"
    .ascii  "2) Erase Profile\n"
    .ascii  "3) Show all profiles\n"
    .asciiz "4) Esci\n"
answer:     .asciiz     "\n\nAnswer: "

exitMsg:    .asciiz     "\n\nBYE BYE\n"
msgError:   .asciiz     "\n\n\nERROR, only numbers from 0-4n\n"

name:       .asciiz     "Nome"
surname:    .asciiz     "Cognome"
interests:  .asciiz     "Interessi"
userID:     .asciiz     "UserID"
password:   .asciiz     "Password"
email:      .asciiz     "Email"
visibility: .asciiz     "Visibilita"
    # field name strings

succes:     .asciiz     "\n\n****** PROFILE CREATED ******\n\n"

colon:      .asciiz     ": "
newLine:    .asciiz     "\n"
newLine3:   .asciiz     "\n\n\n"

profno_msg: .asciiz     "Enter Profile Number: "
profmsg:    .asciiz     "\n* Profilo "
showprof_msg:   .asciiz "Profiles are:\n"

search_msg: .asciiz     "Enter field data to search for: "
search_string:  .space  40              # string to match on

    .text
    .globl  main

main:
    li      $a0,5                   # number of profiles
    li      $t0,profile_sizeof      # sizeof a single profile
    mul     $a0,$a0,$t0             # total space needed

    # allocate the space we need and save a pointer to it
    li      $v0,9                   # sbrk
    syscall
    sw      $v0,profiles            # pointer to profiles

Main_Menu:

    # # the main menu functions ##

    li      $v0,4
    la      $a0,welcome
    syscall

    li      $v0,4
    la      $a0,objective
    syscall

    li      $v0,4
    la      $a0,choose
    syscall

    li      $v0,4
    la      $a0,options
    syscall

    li      $v0,4
    la      $a0,answer
    syscall

    li      $v0,5
    syscall
    move    $s0,$v0                 # save the menu choice

    la      $ra,Main_Menu           # set return address

    # # CHOOSE ONE FUNCTION##
    beq     $s0,0,Create_Profile    # Create a Profile starting from 1 ending 5
    beq     $s0,1,Search_Profiles   # Search a Public profile
    beq     $s0,2,Erase_Profile     # Erase your profile
    beq     $s0,3,Show_Profiles     # Show all profiles
    beq     $s0,4,Exit              # Just finish

    la      $a0,msgError
    li      $v0,4
    syscall
    j       Main_Menu

# Create_Profile -- create a profile
Create_Profile:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)

    jal     profno_query            # get profile number to create/modify

    # # start from 1 , come back to main_menu and create the second ,
    # come back again and the third...
    la      $s4,fieldget            # get address of field function
    jal     profile_operation

    li      $v0,4
    la      $a0,succes
    syscall

    ###jal      Modify_Profile

    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra

# Search_Profiles -- search all profiles for match
Search_Profiles:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)

    # prompt user for field to search on
    la      $a0,search_msg
    li      $v0,4                   # puts
    syscall

    # get field data to search for
    la      $a0,search_string
    li      $a1,40
    jal     rdline

    li      $s1,1

Search_Profiles_loop:
    # probe for match
    la      $s4,fieldsearch         # get address of field function
    jal     profile_operation
    beqz    $t9,Search_Profiles_nomatch

    # show this matching profile
    jal     profile_header
    la      $s4,fieldshow           # get address of field function
    jal     profile_operation

Search_Profiles_nomatch:
    addi    $s1,$s1,1
    li      $t0,5
    ble     $s1,$t0,Search_Profiles_loop

    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra

# Erase_Profile -- erase profile based on profile number
Erase_Profile:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)
    jal     profno_query            # get profile number
    la      $s4,fielderase          # get address of field function
    jal     profile_operation       # perform the field erase on all fields
    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra

# Show_Profiles -- show all profiles
Show_Profiles:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)

    la      $a0,showprof_msg
    li      $v0,4                   # puts
    syscall

    li      $s1,1

Show_Profiles_loop:
    jal     profile_header          # output the profile header
    la      $s4,fieldshow           # get address of field function
    jal     profile_operation

    addi    $s1,$s1,1
    li      $t0,5
    ble     $s1,$t0,Show_Profiles_loop

    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra

# Exit -- exit program
Exit:
    la      $a0,exitMsg
    li      $v0,4
    syscall

    li      $v0,10                  # exit
    syscall

# profno_query -- prompt user for profile number
profno_query:
    # prompt user for profile number
    la      $a0,profno_msg
    li      $v0,4                   # puts
    syscall

    # get profile number
    li      $v0,5                   # rdint
    syscall
    move    $s1,$v0

    jr      $ra

# profile_operation -- perform operation on profile
#
# arguments:
#   s0 -- main menu selection
#   s1 -- profile number (1-n)
#
# registers:
#   s2 -- pointer to profile
profile_operation:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)
    jal     findprof
    jal     field_operations
    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra

# field_operations -- perform operation on all fields
field_operations:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)

    li      $t9,0                   # continue through all

    la      $a0,name                # prompt string
    li      $a2,prof_name_sizeof    # field size
    li      $a3,prof_name           # field offset
    jal     field_operation
    bnez    $t9,fields_done         # stop if requested

    la      $a0,surname             # prompt string
    li      $a2,prof_surname_sizeof # field size
    li      $a3,prof_surname        # field offset
    jal     field_operation
    bnez    $t9,fields_done         # stop if requested

    la      $a0,interests           # prompt string
    li      $a2,prof_interests_sizeof   # field size
    li      $a3,prof_interests      # field offset
    jal     field_operation
    bnez    $t9,fields_done         # stop if requested

    la      $a0,userID              # prompt string
    li      $a2,prof_userID_sizeof  # field size
    li      $a3,prof_userID         # field offset
    jal     field_operation
    bnez    $t9,fields_done         # stop if requested

    la      $a0,password            # prompt string
    li      $a2,prof_password_sizeof    # field size
    li      $a3,prof_password       # field offset
    jal     field_operation
    bnez    $t9,fields_done         # stop if requested

    la      $a0,email               # prompt string
    li      $a2,prof_email_sizeof   # field size
    li      $a3,prof_email          # field offset
    jal     field_operation
    bnez    $t9,fields_done         # stop if requested

    la      $a0,visibility          # prompt string
    li      $a2,prof_visibility_sizeof  # field size
    li      $a3,prof_visibility     # field offset
    jal     field_operation
    bnez    $t9,fields_done         # stop if requested

fields_done:
    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra

# field_operation -- perform operation on single field
#
# arguments:
#   s0 -- operation to perform
#   s1 -- profile number (1-n)
#   s2 -- pointer to profile
#
#   a0 -- pointer to prompt string
#   a2 -- field size
#   a3 -- field offset with struct
#
# registers:
#   s3 -- pointer to profile field
field_operation:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)

    addu    $s3,$s2,$a3             # point to field
    jalr    $s4                     # call field function

    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra

# fieldget -- prompt user for field value
#
# arguments:
#   a0 -- pointer to prompt string
#   a1 -- pointer to field
#   a2 -- field size
#   a3 -- field offset with struct
fieldget:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)

    # output prompt string
    li      $v0,4                   # puts
    syscall

    la      $a0,colon
    li      $v0,4                   # puts
    syscall

    # read in field
    move    $a0,$s3
    move    $a1,$a2
    jal     rdline

    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra

# fieldshow -- show field value
#
# arguments:
#   a0 -- pointer to prompt string
#   a2 -- field size
#   a3 -- field offset with struct
fieldshow:
    li      $v0,4
    syscall

    la      $a0,colon
    li      $v0,4                   # puts
    syscall

    move    $a0,$s3
    li      $v0,4
    syscall

    la      $a0,newLine
    li      $v0,4
    syscall

    jr      $ra

# fielderase -- erase field
#
# arguments:
#   a2 -- field size
#   a3 -- field offset with struct
fielderase:
    move    $a0,$s3

fielderase_loop:
    sb      $zero,0($a0)
    addi    $a0,$a0,1               # increment field pointer
    addi    $a2,$a2,-1              # decrement field size -- done?
    bnez    $a2,fielderase_loop     # no, loop

    jr      $ra

# fieldsearch -- search field for match
#
# arguments:
#   a2 -- field size
#   a3 -- field offset with struct
fieldsearch:
    addiu   $sp,$sp,-4
    sw      $ra,0($sp)
    move    $t0,$s3                 # get address of field data
    la      $t1,search_string       # string to match on

fieldsearch_loop:
    lb      $t2,0($t0)              # get field character
    addiu   $t0,$t0,1

    lb      $t3,0($t1)              # get string character
    addiu   $t1,$t1,1

    bne     $t2,$t3,fieldsearch_done    # mismatch? if yes, done -- no match

    bnez    $t2,fieldsearch_loop    # EOS? if no, loop
    li      $t9,1                   # say field matched

fieldsearch_done:
    lw      $ra,0($sp)
    addiu   $sp,$sp,4
    jr      $ra

# findprof -- find profile
#
# RETURNS:
#   s2 -- pointer to profile
#
# arguments:
#   s1 -- profile number
findprof:
    addi    $t0,$s1,-1              # get index
    li      $t1,profile_sizeof      # size of profile
    mul     $t0,$t0,$t1             # get offset into profile list
    lw      $s2,profiles            # base pointer to profiles
    addu    $s2,$s2,$t0             # get pointer to profile
    jr      $ra

# profile_header -- output profile header message
profile_header:
    la      $a0,newLine
    li      $v0,4                   # puts
    syscall

    la      $a0,profmsg
    li      $v0,4                   # puts
    syscall

    # output the profile number
    move    $a0,$s1
    li      $v0,1                   # prtint
    syscall

    la      $a0,newLine
    li      $v0,4                   # puts
    syscall

    jr      $ra

# rdline -- read user response
#
# arguments:
#   a0 -- pointer to string buffer
#   a1 -- length of string buffer
rdline:
    li      $v0,8                   # gets
    syscall

    move    $t1,$a0
    lb      $t2,newLine

# strip newline
rdline_loop:
    lb      $t0,0($t1)              # get char -- is it newline?
    addiu   $t1,$t1,1               # increment pointer
    bne     $t0,$t2,rdline_loop     # no, loop
    sb      $zero,-1($t1)           # strip the newline

    jr      $ra
    .data

edata: