how to check a user input string if it is a empty string in mips - mips

I try to write a simple MIPS program that accepts user input which is a string, then checks if the user does not input anything to quit the program. I try to use beq to compare the user's input and an empty string, but I do not know how to assign an empty string to a register.
.data
userinput: .space 8
.txet
loop:
li $v0,8
la $a0,userinput
syscall
li $v0, 4
la $a1, // try to assgin an empty string to $a1
beq $a0,$a1, exit
j loop
exit: li $v0 10
syscall

Because strings are a variable length data structure, they go in memory — one character after another at successive (byte) memory locations, and usually as with C, NUL character terminated.  They are referenced by their starting address, aka the lowest address in the string, aka pointer to the first byte of the string.
If you compare strings by their reference address, you'll know whether two strings live at the same memory location and if they do they're equal (in that case, of course, the strings hold the same value), but if they are not at the same memory location, then you've learned nothing about whether the string data is the same or not.  To compare two strings, you need to compare their bytes in memory to see if they're the same.
You don't need a complete, general-purpose string compare to see if a string is empty.  Experiment with the string entered into memory by simply doing a return, and see what you get.  That's what to look for when you want to see if the string is empty.
I believe it will have a newline followed by a nul character.  I don't think any user input using syscall #8 could legitimately have any further character data after the newline, so I think for the empty input string test, it would be sufficient to look for the newline as the first character of the string.
beq/bne are useful — but as I said above you need to compare character data not reference addresses.  So, load the first byte of string from memory and compare it to the newline character constant value.
A truly empty string would start (and finish) with a single NUL terminating byte, and that's the character we would look for instead of looking for the newline character, but MARS syscall #8 appends the newline character (that the user types to complete the input) into the characters of input, so there's a difference then of looking for a truly empty string and looking for the minimal possible (empty) input from syscall #8.

Related

array address addition in MIPS and translating to C

I just started learning MIPS and don't have much idea what's going on. The following problem asks to translate the last add instruction to C code :
.data
A: .word 0:16 # in C: int A[16];
.text
la $s6, A # in C: int* s6 = A;
li $t0, 3 # in C: int t0 = 3; // integer array index
sll $t0, $t0, 2 # (In MIPS: $t0 = $t0 << 2) ($t0*4 is the byte offset used in MIPS.)
add $s0, $s6, $t0 # <--- What is the equivalent C code
What I understood was this : the address of array A is stored in register $s6, then the constant 3 denoting an array index is stored in $t0, the sll instruction stores 3*2^2 = 12 into register $t0. Then, the add instruction adds the contents of $s6 and $t0 and stores the sum into $s0.
$s6 + $t0 = address of A + 12 ?? I am not able to make sense of this, please help me? Does it mean it adds 12 to the address of A and stores that into $s0?
In C, we do array indexing as follows:
a[i]
which by definition of the operators in C is equivalent to
*(a+i)
This construct represents pointer arithmetic (pointer addition, with binary + operator), followed by dereference (the unary * operator, applied after the addition).
What you're showing is just the pointer arithmetic without the dereference, so basically:
a+i
C knows which one is the pointer and which one is the index, so even i+a would be the same in C (we can also do *(i+a) and i[a] in C, believe it or not, and these are both equivalent to a[i] and *(a+i), indexing into the array to access an element.)
The fundamental difference here between C and assembly (beyond syntax) is that C knows the data type of the pointer, and so automatically scales the index by the element size and you never see that explicitly done in C — whereas in assembly it must be done explicitly, which is sll (shift of two) being used to multiply the index by 4.
So the addition of the array base pointer and index in C is more or less formally called pointer arithmetic and is equivalent to the shift and add in assembly.  Since C hides the scaling, though, there's no direct equivalent to just the add alone.
In C, pointer arithmetic also includes subtraction of pointer and index, with the same scaling automatically applied to the index.
In C, pointer arithmetic also include subtraction of two pointers, so a-b if they are both pointers to the same type and same array or memory block, will compute the index that represents the difference between two pointers.  In C, this is also inversely scaled to obtain a regular index.  In assembly we can do the same with subtraction followed by shifting in the opposite direction, namely right.
Of course there is no addition of pointer to pointer (it doesn't make sense).
Most hardware these days is byte addressable, so we need to use byte addressing both in C and in assembly.  (In languages like Java that don't have pointers we don't see the byte addressing that the language does for you, much like C hides index scaling.)
Any pointer is, in some sense, a pointer to a single byte.  Data items that occupy more than one byte are referred to by their first byte, and this includes arrays, structs, etc..
To do array indexing (into an integer array) we convert the index (0,1,2,3) into a byte offset (0,4,8,12) by scaling (multiplying the index by the pointer's element size).  Then add the byte address (base of the array) to that byte offset, yielding another byte address, but this one refers to the element at the index.

MIPS, How do I find the decimal value in the immediate field of instruction

I'm working with MIPS in Mars. If I'm given the address of an instruction, how do I find the decimal value in the immediate field for the instruction.
i.e. beq $t0, $t1, someLabel - at address (in decimal) 08
This form of branch addressing is called PC-relative addressing. Since all MIPS instructions are 4 bytes long, MIPS stretches the distance of the branch by having PC-relative addressing refer to the number of words to the next instruction instead of the number of bytes. Thus, the 16-bit field can branch four times as far by interpreting the field as a relative word address rather than as a relative byte address. Refer to pic attached. (cred:Computer Organisation and Design David & John)
As we can see the address is 80000 (in decimal). So, in PC relative we get the difference of target and next address /4.
For your question We use
Target (decimal) = (immediate*4)+next instruction (address in decimal)
And your answer is
(Target - next instruction)/4 (this is the third value (immediate field) in the beq statement)

MIPS “la” pseudo instruction

can someone explain to me why MARS translate the pseudo instruction into two instructions: lui & ori? Is there cases when the translation is to only one instruction?
This simple program
.data
msg: .asciiz "This is a string"
.text
la $a0, msg # pseudo-instruction to load the address of the label str
Translates to the instructions
Address Code Basic Source
0x00400000 0x3c011001 lui $1,0x00001001 4 la $a0, msg # pseudo-instruction to load the address of the label str
0x00400004 0x34240000 ori $4,$1,0x00000000
And its always these two instructions AFAIK.
The lui instruction makes the immediate value shifted left 16 bits and stored in the register. The lower 16 bits are zeroes.
This way, you can load 32 bit address (in mips32) with 32 bit instructions.
As you may know every type of command has a "Similar" structure command is structured like that:
The size that is being saved for the value is really the problem/reason that they splitted it to two different commands.
You can see in the figure that the largest type for value (I-Type, the lowest one) has only 26 bits. address has a 32 bit value as you know 32 bit value cant fit into a 26 bit command. And so they splitted it to two steps:
First step: you load the address to the upper 16 bit of the register using an r-type command (LUI) load upper immediate which is the second structure in the figure. It is simply copy the upper 16 bit to the upper 16 bit of the register.
Second step: Copy the lower 16 bits of the address using an or instruction. So it will just "copy" the lower part of the address to the lower part of the register.

mips accessing variable with procedures

I've just started to learn MIPS and I have a question about it.Here is my sample code :
.data
var2: .space 201
var1: .byte '.'
.text
main:
la $a0,var2
li $a1,201
li $v0,8
syscall
jal foo
# code is over.
li $v0,10
syscall
foo:
As you can see in the code, I did not assign any register to var1.Now can I use var1 in foo procedure ? Or to be able to use variables,defined in .data segment, outside of main procedure should I assign them to argument registers ? thanks in advance
EDIT
As you can see, I've created var2 to store somethings. First of all I read a stdin and store it say $t0 register. What I want to do is that I want to read char by char the stdin and compare it with some chars which are stored in var2,however at the first step of my comparision, var2 will be empty (or has garbage) and I want to know how could I solve my problem ?
When you say, "Now can I use var1 in foo procedure", it shows that you're still thinking like a high-level language programmer. That's not a bad thing, of course... it's just that assembly is a whole other ball game.
You don't really have "variables". You have memory, and everyone has access to it. var1 isn't a variable, it's just the address of a location in memory. You could store and load data from that memory address from anywhere in your assembly code.
Now, keeping that in mind, I don't think your "variable declarations" did what you expected them to. Here's what you did:
You allocated a block of 201 bytes. This area of memory has not been initialized, so its contents could be anything. The first byte in that block can be accessed (by anyone) by referencing label var1.
You allocated one more byte, and gave it the contents 0x2E (ASCII character '.').
You called the syscall that expects an ASCIIZ string of characters. But you didn't put a '\0' (0x00) terminator anywhere, so the syscall could in theory go on printing characters until the end of memory. (Chances are it didn't because the MARS emulator tends to set memory to 0x00.)
Your other question is, "should I assign them to argument registers". That's still HLL thinking, I think. If you want to use a value that is stored in memory, you load it into a register: lw $t0 var1 gets you the contents of the first word starting at address var1. If you want to put the value in the register, into the memory location starting at var1, you store it from a register: sw $t0 var1.
Does that help clarify things?

function codes for MIPS architecture

Im reviewing a problem where given a MIPS instruction, I have to write down the decimal value of the 4 fields corresponding to the opcode, rs, rt, and the function. I understand that the decimal value for rs and rt are just the decimal representations of the registers (i.e, $s0 is 16) but how could i figure out the 16 bit function code?
You can not determine that value.You need to be given that values.Each function code does different things,there are many instruction that has the same format.
Every instruction has its own opcode & function code. You can find the opcodes here, for example:
https://www.student.cs.uwaterloo.ca/~isg/res/mips/opcodes
For example, addi is 001000 in binary for the first 6 bytes (the opcode), followed by 2x5 bytes for the registers, followed by 16 bytes for the immediate value
add is 000000 (opcode), followed by 3x5 bytes for the registers, 00000 for shift amount (not used for this instruction), followed by 100000 for the function code.