Before even mentioning code, you need to clarify whether the struct you want to create will be static data (data segment), local data (stack), or dynamically allocated data (heap). There are different ways to allocate each.
But before discussing that, the very first thing you need to do is determine the layout of the struct instance. At the very least it could be:
------------------
| data - 32-bits |
------------------
| next - 32-bits |
------------------
To create an instance statically, it's simply:
.data
.align 2
anInstance: .word 0,0
And on the heap:
.text
Allocator.newNode:
li $a0, 8 #allocate 8 bytes
li $v0, 9
syscall #returns word-aligned ptr
jr $ra
If placing on the stack, simply allocate 8 bytes for it.
A cleaner way is to use a prototype-based method.
Your object layout becomes:
------------------
| size - 32-bits |
------------------
| atr 1 - 32-bits|
------------------
| atr 2 - 32-bits|
------------------
.
.
.
------------------
| atr n - 32-bits|
------------------
For each struct, you create a prototype which the allocation routine will use to create the instance.
.data
ListProto: .word 8,0 #size, head ptr
NodeProto: .word 12,0,0 #size, data, next ptr
.text
main:
la $a0, ListProto
jal Allocator.newObject #create new list instance
la $a0, NodeProto
jal Allocator.newObject #create new node instance
Allocator.newObject:
lw $a0, 0($a0) #a0 = object size
li $v0, 9
syscall
jr $ra
Whether you want the instance to actually keep a size field is up to you. With that approach you can simply add prototypes and that's it.