mips assembly undefined and weird symbols - undefined

I have a simple project to do and I think it's working fine, but I have these problems:
Even though I have declare this:
.data
.msg:.asciiz "Give a number: " <-
.text2:.asciiz "x==-5"
.text1:.asciiz "Array is full"
I get a message saying: The following symbols are undefined: msg
And in the others messages text2 and text1 when they executed I'm getting weird symbols back.
Why?
This is my code:
.data
.msg:.asciiz "Give a number: " #messages <-UNDEFINED MESSAGE
.text2:.asciiz "You typed -5"
.text1:.asciiz "Array is full"
.align 2
a:.space 20 #array for 5 integers
.text
.globl main
.globl loop
.globl loop2
.globl end1
.globl end2
main:
addi $14,$0,5 #t=5
addi $15,$0,-5 #f=-5
addi $16,$0,0 #i=0
addi $17,$0,0 #x=0
la $18,a
addi $2,$0,4 #Give a number:
la $4,msg
syscall
loop: #for
beq $16,$14,end1 #if i==5, end
addi $2,$0,5 #take number from console
syscall
add $17,$2,$0 #add it to array
sw $17, 0($18)
addi $18,$18,4 #change array
beq $17,$15,end2 #if x==-5, end
bne $16,$14,loop2 #if i!=5, go to loop2
loop2:
addi $16,$16,1 #i++
addi $2,$0,4 #Give a number:
la $4,msg
syscall
j loop #jumb to first loop
end1: #if i==5
addi $2,$0,4 #"Array is full"
la $4,text1
syscall
end2: #if x==-5
addi $2,$0,4 #"You typed -5"
la $4,text2
syscall

.msg is a different label from msg. You define .msg with .msg: on an early line, but then reference msg with a la $4,msg. Those are two different symbols, so the assembler complains that msg was never defined.
The leading . is special in .globl; it's not a label at all but rather a directive to make another symbol global. See https://sourceware.org/binutils/docs/as/Global.html
Similarly, .data doesn't declare a label called data, it's a shortcut for .section .data. And yes, the section name really does have a . in it.
You can define "local" label names that won't show up in the object file by using label names like .Lmsg. https://sourceware.org/binutils/docs/as/Symbol-Names.html#index-local-symbol-names
C compiler output typically uses this, you'll find a lot of .L1:, .L2: and .LC0 type of labels in gcc -S output. (How to remove "noise" from GCC/clang assembly output?)

Related

how can I write a MIPS assembly code to write a function

Hi I've just started learning MIPS codeing and I'm really stuck on this, I want to write a function called isCapital, that tests whether a character ch is capitalcase or not?
Please help, Thank you.
.data
lowerCaseChar: .asciiz "Lower case character"
upperCaseChar: .asciiz "Upper case character"
notAlphabeticChar: .asciiz "Not alphabetic character "
char : .byte 'b' # type a character what you want
.text
.globl main
main:
jal isCapital
exit:
li $v0, 10
syscall
isCapital:
addi $sp,$sp,-4
sw $ra,0($sp)
lbu $s0,char
sge $t1,$s0,65
sle $t2,$s0,90
and $t3,$t1,$t2
beq $t3,1,upperCase
sge $t1,$s0,97
sle $t2,$s0,122
and $t3,$t1,$t2
beq $t3,1,lowerCase
j notAlphabetic
end:
li $v0,4
syscall
lw $ra,0($sp)
addi $sp,$sp,4
jr $ra
lowerCase:
la $a0,lowerCaseChar # system call 4 for print lower case
j end
upperCase:
la $a0,upperCaseChar # system call 4 for print upper case
j end
notAlphabetic:
la $a0,notAlphabeticChar
j end

Can anyone tell what mistake i'm doing in this MIPS code?

.data
array: .space 10
prompt: .asciiz "Enter an integer (0 to quit) :"
text: .asciiz "After sorting, the list of integers is:"
.text
.globl main
main:
la $a1, array
read_numbers:
# Rest of code omitted for brevity...
beqz $v0, sort
j read_numbers
sort:
la $a1, $array
li $v0, 4
la $a0, text
syscall
loop:
lw $t0, 0($a1)
addiu $a1, $a1, 4
beqz $t0, done
li $v0, 1
move $a0, $t0
syscall
j loop
Assuming that the code above is formatted correctly in the file rather than all on one line, and ignoring that you are missing code at
# Rest of code omitted for brevity
And ignoring that you haven't said what it is supposed to do, or what it does do ….
The first thing I see if that you are branching in main:
read_numbers: # Rest of code omitted for brevity...
beqz $v0, sort
j read_numbers
But since you didn't set v0 to anything, it is set to whatever value it was set to before your code (and when I go to run it, non zero)
So, it never branched to the sort routine, and jumps to read_numbers and does an endless loop.
If it was in the 'sort', it will grab the first number from array, which is 0 (unless you had populated the array somehow), see that it was 0 and attempt to branch to 'done' which also isn't in your code.

Self-Modifying MIPS Code

I'm trying to write a program in MIPS that continuously prompts for two integers and prints the sum until the sum is 0. The trick is that if the sum is 13, I need to call a method to change the assembled MIPS code so that
add $t2, $t0, $t1
becomes
and $t2, $t0, $t1
and all subsequent runs of the loop use the and instruction.
I have the summation loop working so that when 13 is the sum the method instMod is called which I want to modify the instruction. Unfortunately, I have no idea where to start and can't find any examples of this online. I assume I need to somehow get the hex code of the add out of the assembled code and replace it with the hex code for the and but I do not know how to do that or if that is the right course of action to take.
# Nick Gilbert
# MIPS Program to demonstrate self-modifying code
.data
num1Prompt: .asciiz "Enter num1: "
num2Prompt: .asciiz "Enter num2: "
num1: .word 0
num2: .word 0
addOut: .asciiz "ADD: "
andOut: .asciiz "AND: "
.text
main:
sumLoop:
la $a0, num1Prompt #Asking user for num1
li $v0, 4 #Call code to print string
syscall
li $v0, 5 #Call code to read an int
syscall
move $t0, $v0 #Moving read int to $t1
la $a0, num2Prompt #Asking user for num2
li $v0, 4 #Call code to print string
syscall
li $v0, 5 #Call code to read an int
syscall
move $t1, $v0 #Moving read int to $t2
add $t2, $t0, $t1 #Adding num1 and num2 together
la $a0, addOut
li $v0, 4
syscall
move $a0, $t2
li $v0, 1
syscall
beq $t2, 13, instMod #Calling method to modify add instruction if sum = 13
bne $t2, 0, sumLoop #If result is not yet 0, ask for new sum
endSumLoop:
li $v0, 10
syscall
instMod: #Method to change add instruction to an and instruction
Add a label at the instruction you want to replace, e.g:
instruction_to_be_replaced:
add $t2, $t0, $t1 #Adding num1 and num2 together
then in your routine instMod
instMod: #Method to change add instruction to an and instruction
lw $t1, instruction_to_replace
sw $t1, instruction_to_be_replaced
j sumLoop # go back to your sumLooop
instruction_to_replace:
and $t2, $t0, $t1
The code loads in temporary register $t1 the contents of the instruction you want to replace, and then stores it in the location labelled instruction_to_be_replaced.
The "source" of the instruction goes labelled in instruction_to_replace.
To do this, you need to be able to write on the code section which I assume you have otherwise you would not be asking this question.
Try this:
Assemble the instruction that you need to an object file
Extract the hexadecimal of the equivalent machine code
Place a label in front of the code you need to change
mov the hexidecimal from step 2 into the location from step 3 in your instMod section
For this to function the two instructions with operands must be of identical length. If they are not, pad the original or the replacement with nop as appropriate.

What is a function/How to distinguish a function in MIPS?

Extremely new to MIPs assembly language -- I haven't been able to find a link that specifically tells you what a function is distinguished as in MIPS, examples of how we use jal, jr, etc..
It's very difficult to find out how these actions work -- My text book for this section of the course is very broad and assumes I already know the language and just outlines a code (under the assumption that I know exactly what the code means)
Hence, the book isn't helping me so I'm trying to practice on my own..
Anywho, in my class we wrote a simple array code which supposedly has a "function" in it.
My question is -- how do I know what is the "function"
Below is a code we did in class -- it's supposed to output an array from 1 to 10.. I understand where it increments and such (addi) and why it's a 1 and 4 but I don't understand
what $ra, jal , jr mean... but I'm assuming that these have something to do with what a "function" is
#Load an array and display
.data
.align 2
a1: .space 40
.text
.globl main
main:
la $s0, a1
jal loadArray
la $s0, a1# <- return here after function return
jal displayArray
# <- return here after 2nd function
exit:
li $v0, 10
syscall
displayArray:
#$ra = the address of line 14
li $t0, 1 #int i = 0
displayLoop: blt $t0, 11, display
#else
jr $ra
display:
lw $t0, ($s0) # a1[i] = i;
li $v0, 1
move $a0, $t0
syscall
#incremment i and array pointer
addi $t0, $t0, 1
addi $s0, $s0, 4
j displayLoop
loadArray:
#$ra = the address of line 14
li $t0, 1 #int i = 0
loadLoop: blt $t0, 11, load
#else
jr $ra
load:
sw $t0, ($s0) # a1[i] = i;
#incremment i and array pointer
addi $t0, $t0, 1
addi $s0, $s0, 4
j loadLoop
So this is the sample code but the only difference between this code and a usual code with just labels is the jump register and jump and link...
Does that distinguish what is a function???
Sorry for the long wall of text -- TL;DR In MIPS, how do you know what is a "function" I know what a label is (obv.) but not a function...
This isn't as straight forward to me as it is in cpp or java lol.
A function (or subroutine) is really just any piece of code that you can call (with jal) and expect to return to you (with jr $ra). It is also generally expected to keep your stack and registers intact across the call.
The term function is used more often by high-level languages like C, whereas subroutine is more common at the assembly-language level.
jal means "Jump And Link" - I would expect this to be covered in your textbook. This instruction 1) stores the return address (the address of the instruction after the jal) in $ra, the link register (or return address register) and then 2) jumps to the target address. This is how you call a function.
When the function is finished, it returns to the caller by jumping to the address in the return address register, with the jr $ra instruction (Jump to Register $ra).
Your comments imply that you already understand this:
jal loadArray
la $s0, a1# <- return here after function return
jal displayArray
# <- return here after 2nd function
So loadArray can be considered a function, as can displayArray.
Read more:
Subroutines/Functions in MIPS
MIPS Quick Tutorial
MIPS Instruction Reference
MIPS Assembly/Control Flow Instructions
jal and jr

MIPS syscall on MARS: "address out of range"

I'm a newbie with MIPS & MARS. As a part of my program, I want to read a string from the user.
I have a simple code as follows
.globl test
.data 0x10010000
foo: .asciiz "Input a string"
.data 0x10020000
in: .asciiz "xyz"
.text 0x00400000
test:
li $v0, 54
add $a0, $zero, 0x1001
add $a1, $zero, 0x1002
add $a2, $zero, 3
syscall
The idea is to read a string of say length at most 3 into memory at 0x1002. Running the code gives me "Runtime exception at 0x00400010: address out of range 0x00001001".
Why does this happen? How do I fix it? I suspect I'm doing something very silly, but cannot figure it out.
I think you're mixed up with addressing. You've defined your buffer space at 0x10020000 but you're using an address of 0x1002 for the syscall. Same thing with the dialog string.
Your $a0 should be the address of the string that gets shown in the dialog; I suspect this should be foo:
la $a0, foo
And your buffer should be in:
la $a1, in
Edit: these are replacements for the adds, so in the end it should look like:
test:
li $v0, 54
la $a0, foo
la $a1, in
li $a2, 3
syscall
I've also replaced the $a2 line with something simpler. Try to see how they're equivalent.