https://courses.missouristate.edu/KenVollmar/MARS/Help/SyscallHelp.html показывает, что MARS имеет некоторые системные вызовы RNG. Используйте это, чтобы проиндексировать ваш массив. Использование генератора случайных чисел в MIPS?
Вам даже не нужно отображать случайное 32-разрядное целое число в вашем диапазоне; MARS сделает это за вас, если вы используете syscall 42 вместо 41. Syscall принимает ID # ГСЧ в качестве входа, но, похоже, вам не нужно его инициализировать, просто используйте 0
.data
dragon: .asciiz "Dragon\n"
orc: .asciiz "Orc\n"
sword: .asciiz "Sword\n"
# this can't be line-wrapped, unless you use another .word directive
dice: .word dragon, dragon, dragon, dragon, dragon, orc, orc, orc, sword, sword, sword, sword
#.equ die_size, (. - dice)/4
#die_size = (. - dice)/4
.eqv die_size, 12 # 11 + 1
# MARS built-in assembler is crap and can't calculate the size for us at assemble time.
.text
main:
li $v0, 42 # Service 42, random int range
li $a0, 0 # Select random generator 0
li $a1, die_size # upper bound of range (non-inclusive)
syscall # invoke the system call, returns in $a0
# $a0 is in the range [0..12), i.e. 0..11
sll $a0, $a0, 2 # scale by size of word, $a0 is a byte index into pointer array
lw $a0, dice($a0)
li $v0, 4 # print string
syscall
li $v0, 17
li $a0, 0
syscall # exit(0) because MARS doesn't support returning from main!?!
# jr $ra
У меня настроен MARS для размещения раздела данных в 16 килобайтах адресного пространства, чтобы я мог использовать dice($reg)
для индексации массива. Если вы этого не сделаете, вы можете использовать addu
для вычисления адреса.
Встроенный ассемблер MARS действительно отстой, и, кажется, вынуждает вас жестко кодировать размер массива как литерал число. В реальном ассемблере, таком как GAS, вы будете использовать .equ die_size, (. - dice)/4 + 1
для вычисления во время сборки из числа элементов в массиве указателей.