Вот код, который я считаю, будет работать:
# codgen -- generate code or random number
#
#@+
# FUNCTION codgen(): UNSIGNED INTEGER;
# LOCAL SIGNED INTEGER n;
# LOCAL UNSIGNED INTEGER x,y;
# BEGIN
# n := [right-justify the five bits "seed"<24:20>, and zero-extend];
# WHILE (n >= 0) LOOP
# x := [shift "seed" left-logical by 3 bits];
# y := [divide "seed" (unsigned) by the constant 16];
# seed := x-y; [ignore overflow condition]
# n := n-1;
# ENDLOOP
# RETURN (seed XOR 0x0176f7df);
# END;
#@-
#
# arguments:
# s0 -- seed
#
# NOTE:
# under mips, the phrase "seed is a global variable" allows it to be in a
# register. if it had to be a global "in memory" (e.g.):
# seed: .word 0
# just add (at start):
# lw $s0,seed
# and (at end):
# sw $s0,seed
#
# registers:
# t0 -- n
# t1 -- x
# t2 -- y
codgen:
srl $t0,$s0,20 # get seed bits 24-20 to lower 5 bits
andi $t0,$t0,0x1F # isolate them
j codgen_start # start loop
codgen_loop:
sll $t1,$s0,3 # x = seed << 3
srl $t2,$s0,4 # y = (unsigned) seed/16 (aka seed >> 4)
subu $s0,$t1,$t2 # seed = x - y
subi $t0,$t0,1 # n -= 1
codgen_start:
bgez $t0,codgen_loop # n >= 0? if yes, loop
xori $v0,$s0,0x0176F7DF # ret = seed^0x0176F7DF
jr $ra # return
Выше просто стол проверил. Я сделал фактически не запустить его, и я сделал не написать версию C первых, чтобы обеспечить диагностическую/эталонную реализацию, потому что ...
Не обижайтесь, но, в псевдокоде будучи некоторых [ «древний» :-)] языкового происхождения, такого как Algol, Pascal, Ada, VHDL (?) или [modern] Fortran, мне было трудно найти алгоритм/намерение.
Перевод на C был бы такой же ошибкой, как и прямой перевод в asm.