MIPS32 - Load a half-word using only load word and store word instructions - memory

For educational purposes, I need to figure out how to load a half-word from a memory address to a register using only the lw and sw instructions in MIPS.
I am aware you can use lh, sh, lb, and sb but I want to know how to do it with only lw and sw.
For example, load the two bytes "AB" into register $t0:
Mem: [ A ] [ B ] [ C ] [ D ]
100 200 300 400
$t0: [ 0 ] [ 0 ] [ A ] [ B ]
My solution so far:
lw $t0, 100($zero)
srl $t0, t0, 16
Is there a way to do the same operation using only sw and lw instructions and no other operations?

Related

Bad address in data/stack read in program - not sure what went wrong

I'm currently working on an assignment for class where we have to recursively find the sum of a linked list implemented in MIPS. I get the "bad address in data/stack read in program error at the lw $s0, 0($a0) line. I'm not sure what went wrong, so help would be really appreciated.
llsum:
la $t0, 4($a0)
beqz $t0, return # if next pointer is null, jump to return
jal recurse
# otherwise, iterate through linked list and repeat
recurse:
addi $sp, $sp, -12 # free space (12 bits) on stack
sw $ra, 0($sp) # add return address and s0 to the stack
sw $s0, 4($sp) # storage for current pointer
# sw $a0, 8($sp) # storage for next pointer
lw $s0, 0($a0) # put first four bytes of a0 into s0 (current)
#set a0 (the cell) equal to its next for the iteration
lw $a0, 4($a0)
jal llsum # "sum(n.next)"
sw $v0, 8($sp)
lw $t0, 4($sp)
add $v0, $v0, $t0 # add current to sum (in v0)
lw $ra, 0($sp) # load return address
addi $sp, $sp, 12 # restore stack
jr $ra # return to caller
return:
jr $ra # return to caller
Here's the implementation of the linked list:
.data
listA0: .word -267 listA1
listA1: .word 514 listA2
listA2: .word -927 0

opencv read() function is just working well from python idle shell. works bad from python ./image_handler.py

I wanna use opencv to grab frame from a webcamera as a common use function API.
The code as following only works well from python idle invoking (frame is not empty, data is good with image get from webcamera, cap.imshow function display normal video/picture from camera). but not work well when not invoking from python idle (frame data is almost empty, and cap.imshow function display almost black screen video/picture from camera).
I do not know why it does not work from python module invoke from interpreter out of idle?
And how to fix this issue? thanks if anyone can give me any suggestion or guides!!!
References:
CODE:
import cv2
def get_images_via_opencv():
cap = cv2.VideoCapture(1, cv2.CAP_DSHOW)
ret, frame = cap.read()
print(cap.isOpened())
print(ret)
print(frame)
# print(decode_fourcc(cap.get(6)))
cv2.imshow('frame', frame)
cv2.imwrite('capture.jpg', frame)
cap.release()
cv2.destroyAllWindows()
get_images_via_opencv()
Result from python IDLE execution - normal video/image:
True
True
[[[ 5 4 8]
[ 5 4 8]
[ 5 3 9]
...
[ 85 99 137]
[ 83 98 134]
[ 80 95 131]]
...
Result from other ways - with black screen video/image:
True
True
[[[ 80 1 210]
[187 118 2]
[ 0 0 144]
...
[ 0 0 0]
[ 0 0 0]
[ 0 0 0]]
...

code is not reprinting board after initial print.. 2x2 Dots and Boxes game

The below code is a one player 2x2 Dots and Boxes Game. It prints the board at first and waits for the user input. After that, it simply does not print the board but successfully asks the question. Any insight?
.data
board: .ascii "\n\n . . . . 0 . 1 ."
.ascii "\n 2 3 4"
.ascii "\n . . . . 5 . 6 ."
.ascii "\n 7 8 9"
.asciiz "\n . . . . a . b .\n"
intro: .asciiz "\n One-Player 2x2 Dots-and-Boxes Game.\n"
prompt: .asciiz "\n Please Enter Next Move. (0..b): "
contPrompt: .asciiz "\n Would you like to Continue? (y/n): "
newGame: .asciiz "\n New Game? (y/n): "
wrongMove: .asciiz "\n---------Wrong Move-----------\n"
duplMove: .asciiz "\n--------Duplicate Move--------\n"
accept: .asciiz "y"
end: .asciiz "b"
buffer: .space 2
addr: .byte 6, 8, 33, 35, 37, 62, 64, 89, 91, 93, 118, 120
mark: .byte '-', '-', '|', '|', '|', '-', '-', '|', '|', '|', '-', '-'
.text
main:
la $a0, intro
li $v0, 4
syscall
j game
game:
# Printing the Board
la $a0, board
li $v0, 4
syscall
# Printing Prompt for Value
la $a0, prompt
li $v0, 4
syscall
# Reading Input Values
li $v0, 8
la $a0, buffer
li $a1, 2
syscall
# Checking for Validity
lb $t0, end
lb $t1, buffer
bgt $t1, $t0, error
lb $t0, buffer
j placePiece
placePiece:
# Placing Values
lb $t1, addr($t0)
lb $t2, mark($t0)
sb $t2, board($t1)
j printBoard
printBoard:
la $a0, board
li $v0, 4
syscall
j con
con:
la $a0, contPrompt
li $v0, 4
syscall
li $v0, 8
la $a0, buffer
li $a1, 2
syscall
lb $t0, accept
lb $t1, buffer
beq $t0, $t1, game
j exit
error:
la $a0, wrongMove
li $v0, 4
syscall
j game
exit:
la $a0, newGame
li $v0, 4
syscall
la $a0, buffer
li $a1, 2
li $v0, 8
syscall
lb $t0, accept
lb $t1, buffer
beq $t0, $t1, main
li $v0, 10
syscall
I think your problem is that you are writing '\0' at the beginning of board.
It seems that you read an ASCII code and then read a look up table using that ASCII code as the index. You should subtract the ASCII code '0' for the digits and subtract ('a'-10) for the letters 'a' and 'b'. Note there is a gap between ASCII code '9' and ASCII code 'a'.
You may as well change the last two board moves to ':' and ';' as they are next to '9' in the ASCII table.
So, assuming you change 'a' with ':' and 'b' with ';' you would need to subtract '0' before jumping to placePiece, e.g.:
lb $t0, buffer
subiu $t0, $t0, '0' # convert to array index
j placePiece

I need to get my number to print out in binary for mips. This number is a sum that was calculated. My code isn't working

.data
prompt:.asciiz "\nEnter an integer: "
add: .asciiz "\n The sum in decimal is: "
bin: .asciiz "\n The sum in binary is: "
sgt: .asciiz "\n The second integer is greater than the first. "
fgt: .asciiz "\n The first integer is greater than the second."
equal: .asciiz "\n The two entered values are equal: "
.text
main:
li $v0, 4 #print string code
la $a0, prompt #argument
syscall #execute, service print stri
li $v0, 5 # read integer
syscall #v0 gets the returned value
move $s0, $v0 #set v0 -> s0
li $v0, 4
la $a0, prompt
syscall
li $v0, 5
syscall
move $s1, $v0 #set v0 -> s1
add $s2, $s1, $s0 #s2 -> s0 + s1
li $v0, 4 #print string
la $a0, add #argument
syscall
move $a0, $s2
li $v0, 1 #print int
syscall
# Output "sum in binary is:".
la $a0, bin
li $v0, 4
syscall
# Output the binary number. (This is done by isolating one bit
# at a time, adding it to the ASCII code for '0', and outputting
# the character. It is important that the bits are output in
# most-to-least significant bit order.
move $t2, $a0
li $s1, 32 # Set up a loop counter
Loop:
rol $t2, $t2, 1 # Roll the bits left by one bit - wraps highest bit to lowest bit.
and $t0, $t2, 1 # Mask off low bit (logical AND with 000...0001)
add $t0, $t0, 48 # Combine it with ASCII code for '0', becomes 0 or 1
move $a0, $t0 # Output the ASCII character
li $v0, 11
syscall
subi $s1, $s1, 1 # Decrement loop counter
bne $s1, $zero, Loop # Keep looping if loop counter is not zero
slt $t0, $s0, $s1
beq $t0, $0, else
li $v0, 4
la $a0, sgt
syscall
j jump
else:
li $v0, 4
la $a0, fgt
syscall
jump:
li $v0, 10 #system call for exit
syscall
I'm also having quite a bit of trouble getting "the two inputed digits are equal to work. I tried using the three case scenarios and having three separate labels: to send my code to. But it didn't work. I don't know whats going on.
Pretty trivial mistake here.
Look at the line before the loop:
move $t2, $a0
You are clearly attempting to move the sum into $t2 but $a0 contains the address of bin.
Changed this line to:
move $t2, $s2
And everything functions correctly.

How Can I Store a String in MIPS using Dynamic Memory?

Okay guys, basically the problem I'm having is this.
I've been assigned to write a MIPS program that stores a struct dynamically.
Basically, it stores an ID, a Year, a Title, and a Description
It's to be stored using a binary search tree.
If you've ever coded a stack in C++ you know what I'm talking about.
I've successfully stored the ID and Titles in memory dynamically,
but I'm having trouble storing the user-entered strings.
This is a complex question and there's not a lot of info that I've
been able to find online so props if you can help me out with this :)
Here is my memory setup:
$s5 - Stores Root Node
$s7 - Stores Size of Tree (Not Necessary)
Each New Item Contains a chunk of 344 bytes
The bytes are setup as such:
8 Bytes - [ID]
8 Bytes - [Year]
64 Bytes - [Title]
256 Bytes - [Description]
8 Bytes - [LastNodeAddress]
8 Bytes - [NextNodeAddress]
Here's the code and you may see the issue:
li $v0, 9 #allocate memory for new record
li $a0, 344 #enough memory for 2 addresses and all the data
syscall
move $s0, $v0 #hang onto the initial address of all our info
li $v0, 4 #prompt for ID
la $a0, addid
syscall
li $v0, 5 #enter integer
syscall
sw $v0, 0($s0) #store our ID into memory Offset: 0
li $v0, 4 #prompt for add year
la $a0, addyear
syscall
li $v0, 5 #enter integer
syscall
sw $v0, 4($s0) #store year into our memory Offset: 4
li $v0, 4 #prompt for add title
la $a0, addtitle
syscall
li $v0, 8 #read title into titlebuffer
la $a0, titlebuffer
li $a1, 64
syscall
sw $a0, 8($s0) #store title into our memory Offset: 8
li $v0, 4 #prompt for add description
la $a0, adddescription
syscall
li $v0, 8 #read from input into descriptionbuffer
la $a0, descriptionbuffer
li $a1, 256
syscall
sw $a0, 72($s0) #store description into our memory Offset: 72
bne $s7, 0, setlocations #if this isn't root node let's set the locations
add $s7, $s7, 1 #add 1 to the size of the records
move $s5, $s0 #store this address as root node for now
The problem is that all that's being stored is the address of the buffers.
The buffers are defined in my data section like this:
.data
titlebuffer: .space 64
descriptionbuffer: .space 256
What I end up with is just the addresses stored in the memory I allocated,
and I have no idea how to store strings into allocated memory.
Any help would be greatly appreciated! :)
Don't bother defining your memory at the start of your program like I showed in the original question.
Instead, allocate it and read the values into the correct offsets of your dynamic memory.
Instead of la $a0, descriptionbuffer
Instead of la $a0, titlebuffer
Use:
la $a0, 8($s0)
la $a0, 72($s0)
Here I move the memory address into $s0 using move $s0, $v0 and read the values into the correct offsets.
to print you do the same thing!
Here is the working code:
li $v0, 9 #allocate memory for new record
li $a0, 344 #enough memory for 2 addresses and all the data
syscall
move $s0, $v0 #hang onto the initial address of all our info
li $v0, 8 #read our title into the allocated space
la $a0, 8($s0) #Offset: 8
li $a1, 64
syscall
li $v0, 8 #read our description into the allocated space
la $a0, 72($s0) #Offset: 72
li $a1, 256
syscall
In addition, you can find the final solution here: https://stackoverflow.com/a/9953839/1274820
Edit: Well, after 10k views, I decided to add more info here so you don't have to search through later code 😉
Here's the full code to store 4 different pieces of data in memory:
li $v0, 9 #allocate memory for new record
li $a0, 344 #[334 = how much memory - in bytes]
syscall
move $s0, $v0 #store the address of our allocated memory in $s0
li $v0, 5 #enter integer
syscall
sw $v0, 0($s0) #store our ID into memory Offset: 0
li $v0, 5 #enter integer
syscall
sw $v0, 4($s0) #store year into our memory Offset: 4
li $v0, 8 #read our title into the allocated space
la $a0, 8($s0) #Offset: 8
li $a1, 64
syscall
li $v0, 8 #read our description into the allocated space
la $a0, 72($s0) #Offset: 72
li $a1, 256
syscall
That will store ID, Year, Title, and Description - the offset is where we place the data in the dynamic memory.
Imagine that I have a block of 334 bytes (like above):
[ 334 ]
We store the ID an integer (4 bytes of data) at offset 0 like this:
[(ID) 330 ]
Then, we store the year next to it (at offset 4).
[(ID)(YR) 326 ]
And so on ...
To print it, do it like this:
li $v0, 1 #Print the ID stored at $s0 [Offset: 0]
lw $a0, 0($s0)
syscall
li $v0, 1 #Print the Year stored at $s0 [Offset: 4]
lw $a0, 4($s0)
syscall
li $v0, 4 #Print the Title stored at $s0 [Offset: 8]
la $a0, 8($s0)
syscall
li $v0, 4 #Print descript stored at $s0 [Offset: 72]
la $a0, 72($s0)
syscall

Resources