Assembly 有没有办法通过在MIPS中自我修改来创建计数器?

Assembly 有没有办法通过在MIPS中自我修改来创建计数器?,assembly,mips,mips32,self-modifying,mips64,Assembly,Mips,Mips32,Self Modifying,Mips64,我想创建一个子例程,如下所示: 第一次呼叫:返回0 第二次呼叫:返回1 第三次呼叫:返回2 但是我们不应该使用寄存器和内存来保存当前的号码。我们必须通过改变代码(自我修改)来解决这个问题。 有什么办法吗?这就是我找到的解决方案: # subroutine nextInt: # return value is in $v0 add $v0,$zero,0 la $t0,nextInt # load subroutine

我想创建一个子例程,如下所示:

  • 第一次呼叫:返回0
  • 第二次呼叫:返回1
  • 第三次呼叫:返回2
但是我们不应该使用寄存器和内存来保存当前的号码。我们必须通过改变代码(自我修改)来解决这个问题。
有什么办法吗?

这就是我找到的解决方案:

# 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

当然,有一条指令,比如
ori$t0、$zero、0
。然后编写一些代码加载该指令,将立即数字段增加1,并将结果存储回内存。这假设您的函数驻留在RAM.IIRC中,如果希望保证下一次执行将获取修改后的指令,MIPS需要在存储后运行某种内存屏障或缓存失效指令。(没有这一点,I-cache与D-cache的一致性就无法得到保证。MARS可能不会模拟陈旧的缓存效果。)MARS将要求您选择“自修改代码”设置选项。否则,程序在从用户空间读取指令(更不用说写入指令)时会出错。使用寄存器或内存位置存储数字有什么错?@Alejandro:这样就不需要SMC,突破了看起来像是学习练习的要点。
next
nextInt
是不同的符号名称。这难道不是在自我调整吗?但无论如何,是的,立即数字段位于MIPS I-type指令的底部(最低有效位),因此将指令字增加1是可行的。IDK为什么在第一条指令(您将修改)中没有使用
addi
助记符,而在后一条指令中使用了助记符,因为它们都需要使用立即数。汇编程序将处理它,但对于要修改的指令来说,明确指令的形式/编码更为重要。