0

我使用来自这个站点的 MMIX:http: //mmix.cs.hm.edu/ 我使用这段代码让控制台打印“Hello World”“times”次:

times IS 3

msg BYTE "Hello World",#A,0
Main GETA $255,msg
    SET $91,times
    MUL $91,$91,2
    SUB $91,$91,1 
    TRAP 0,Fputs,StdOut
    BP $91,@-8
    TRAP 0,Halt,0

我想知道为什么这只产生 3 个。查看代码,因为我乘以 3,它应该打印 Hello World 3 次。然而,经过仔细检查,我注意到“00000701 (TRAP) $255 = Fputs(StdOut,#c) = 0”和“00000701 (TRAP) $255 = Fputs(StdOut,#0) = 12”会交替出现。我以为这是原因。但是为什么会这样呢?

我对用这种语言编码非常陌生,所以请在术语上放轻松。

4

1 回答 1

1

这是一个有趣的错误。实际上输出是:

Hello World
Hello World
Hello World

为什么这样做是这个玩具程序的组装方式和输出在 MMIX 中的工作方式的结果

当程序在内存中组装时,它从地址 0x0 处的字符串开始 - 字节是:

0  1  2  3  4  5  6  7  8  9  10  11  12  ...
H  e  l  l  o  _  W  o  r  l   d  \n  \0  ...

输出指令为

    TRAP 0,Fputs,StdOut

该指令打印地址在寄存器 $255 中的字符串,并将返回值放入 $255 中。返回值是成功时写入的字节数,错误时为-1

循环确实按预期运行了 6 次,但发生的情况是:

循环以 $255 开始,设置为 0,这是字符串的地址

第一次迭代打印“Hello World\n”并将 $255 设置为 12,这是字符串的长度

第二次 $255 的值为 12 - 这用作要打印的字符串的地址。您可以在上面的内存布局中看到,地址 12 有一个 NUL 字符。这使得 TRAP 不会成功打印任何内容,并且 $255 设置为 0 以表示写入的字节数。

第三次 $255 的值为 0,这是字符串的有效地址,因此它被打印出来,并且 $255 被设置为 12 以表示写入的字符串的长度。

你明白了。

因此字符串每隔一次打印一次,总共打印 3 次,共 6 次

解决方法是将 $255 设置为循环内字符串的地址。完整的程序是:

times IS 3

msg   BYTE "Hello World",#A,0
Main  SET $91,times
      MUL $91,$91,2
      SUB $91,$91,1 
      GETA $255,msg
      TRAP 0,Fputs,StdOut
      BP $91,@-12
      TRAP 0,Halt,0
于 2020-09-23T13:17:43.233 回答