我从这个网站使用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 (陷阱) $255 =Fput(StdOut,#c) = 0“和"00000701 (陷阱) $255 =Fput(StdOut,#0) = 12”会交替出现。我假设这就是原因。但是为什么会发生这种情况呢?
我对用这种语言编码是非常陌生的,所以请不要使用术语。
发布于 2020-09-23 21:17:43
这是一个有趣的bug。实际上,输出是:
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字符。这将使陷阱成功打印任何内容,并将写入字节数的$255设置为0。
第三次$255的值为0,这是字符串的有效地址,因此它被打印出来,$255被设置为12,表示写入的字符串的长度。
你明白了吧。
因此,字符串每隔一次打印一次,总共打印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,0https://stackoverflow.com/questions/49087580
复制相似问题