-1

I want to create a subroutine like this:

  • first time call: return 0
  • second time call: return 1
  • third time call: return 2
  • ...

but we should not use register and memory to save the current number. we have to solve this by changing the code (self-modifying). Is there any way?

  • 2
    Sure, have an instruction like `ori $t0,$zero,0`. Then write some code that loads that instruction, increments the immediate field by 1, and stores the result back to memory. This assumes that your function resides in RAM. – Michael Dec 10 '20 at 09:56
  • 1
    IIRC, MIPS needs to run some kind of memory barrier or cache invalidate instruction after a store, if you want to be guaranteed that the next execution will fetch the modified instruction. (I-cache coherency with D-cache isn't guaranteed without that. MARS might not simulate stale cache effects.) – Peter Cordes Dec 10 '20 at 13:50
  • 2
    MARS will require you to select the "Self-modifying code" Settings option. Without that, program will fault on reading an instruction from user space (not to mention writing it). – Erik Eidt Dec 10 '20 at 15:19
  • 1
    What's wrong with using a register or memory location to store the number? – Alejandro Dec 10 '20 at 15:52
  • @Alejandro: That would avoid the need for SMC, defeating the point of what looks like a learning exercise. – Peter Cordes Dec 10 '20 at 20:32
  • @Michael thank you. but I need a instruction to load a encoded number to memory for execution – mh hssoleyman Dec 12 '20 at 10:52
  • What is an _"encoded number"_? In any case, what I proposed does exactly what you asked for in your question. – Michael Dec 12 '20 at 11:04

1 Answers1

0

This is the solution which I found:

# subroutine
nextInt:                    # return value is in $v0
add     $v0,$zero,0
la      $t0,nextInt         # load subroutine address
lw      $t1,0($t0)          # load content of address
addi    $t1,$t1,1           # change content (increment)
sw      $t1,0($t0)          # save
jr      $ra
  • `next` and `nextInt` are different symbol names. Isn't this supposed to be modifying itself? But anyway yes, the immediate field is at the bottom (least-significant) bits in MIPS I-type instructions, so incrementing the instruction word by 1 works. IDK why you didn't use the `addi` mnemonic for the first instruction (which you'll modify), but did for the later one, when they both need to use an immediate. The assembler will handle it, but being explicit about the form / encoding of the instruction is *more* important for the instruction you want to modify. – Peter Cordes Dec 20 '20 at 19:46