首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >顺时针旋转,右转和三次疯狂操作抛出分割错误

顺时针旋转,右转和三次疯狂操作抛出分割错误
EN

Stack Overflow用户
提问于 2019-08-13 19:30:31
回答 1查看 227关注 0票数 3

在Malbolge编译器/解释器中,三次操作、右转操作和疯狂操作都不能正常工作,并造成分段错误。

在看到关于编码挑战和Code的惊人答案之后,我决定开始用Malbolge编程,并学习用一种硬编程语言编程。

当我试图输出一个固定的字符时,我注意到*p (在规范化的Malbolge中)在我尝试使用它们的大部分时间里都会抛出分段错误。

我试图使用互联网,并查找字符串(在谷歌上) "'Malbolge‘疯狂的操作’分段故障‘和’‘Malbolge’旋转右‘分段故障’“。我还尝试在不同的上下文中使用这些命令,发现如果没有输入(这不是我想要的),它就能工作。

我正在使用由在线翻译托管的tio.run,或者在网上试用它。

我尝试使用的代码:

归一化Malbolge:/*<

马尔博格:u&a

在网上试试!

归一化Malbolge:/p*<v

马尔博格:u=%`M

在网上试试!

归一化Malbolge:/pp<v

马尔博格:u=<`M

在网上试试!

我预计u&au=%`Mu=<`M的输出不会引发任何错误,但实际输出是分段错误。

准确的错误:/srv/wrappers/malbolge: line 3: 21992 Segmentation fault (core dumped) /opt/malbolge/malbolge .code.tio < .input.tio,其中21992可以是任意数字(最有可能是几千到万)

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-08-14 02:54:41

为了诊断这里发生了什么,我一直在通过调试器中的Malbolge解释器。我想说的是“恭喜,您在Malbolge解释器中发现了一个bug”,但考虑到规范和解释器在其他方面不匹配(通常将权威版本视为解释器),而且这就是Malbolge,因为我知道这是有意的行为。(好吧,它可能并不是真正想要的行为,但也没有将许多其他特性作为重要的编程技术来处理。)

Malbolge将所有内容存储在一个大数组中,包括代码和数据。命令的目的是在运行后修改( Malbolge术语中的“encrypt”)本身,但是解释器最终没有完全正确地实现它:它实际上所做的是运行一个命令,然后查看代码指针指向的地址并对其进行加密。这就是为什么跳跃会在跳转目标之前加密指令,而不是跳转指令本身。

如果运行的命令超出了33到126的范围,那么命令就不会运行(实际上,在我所拥有的Malbolge解释器版本中,代码和数据指针也没有增加,这似乎不可避免地会导致无限循环;也许还有其他版本可以解决这个问题)。这是一个重要的检查,因为加密例程只是通过索引到查找表来工作;33到126范围之外的值最终将读取数组之前或之后的一些任意字节的内存。

不幸的是,由于代码和数据存储在一个大数组中,一个命令在运行时可能会修改自己:在运行之前它可能在33到126之间(从而导致安全检查成功),但是在运行之后,它超出了范围,然后加密将完成查找表的超出范围的索引。Malbolge解释器是用C编写的,它具有未定义的超出范围的读取行为,但是对于超出范围的很长一段时间的读取,分段错误很可能(但不是保证)行为。

让我们看看代码u&a发生了什么

代码语言:javascript
运行
复制
Command   A     C     D   memory
  start   0     0     0   117,    38, 97, 29432, 98, 29431, 98, 29432, 97, ...
      / input   0     0   117,    38, 97, 29432, 98, 29431, 98, 29432, 97, ...
encrypt input   1     1   111,    38, 97, 29432, 98, 29431, 98, 29432, 97, ...
      * 39378   1     1   111, 39378, 97, 29432, 98, 29431, 98, 29432, 97, ...
encrypt 39378   2     2   111,   ???, 97, 29432, 98, 29431, 98, 29432, 97, ...

如您所见,您实际上并不是在旋转加载到A中的输入;旋转操作从D (而不是从A)指向的地址读取,因此您正在旋转38 (内存位置1中的*命令的内存中表示形式)以生成39378。该值被存储到A和内存位置1中。不幸的是,内存位置1是当前正在执行的命令,因此当需要对其进行加密时,解释器会对查找表执行超出界限的读取(试图在一个表中查找对应于39378的位置,该位置仅涵盖33到126之间的范围),如果幸运的话,这将产生一个分段错误。

这种行为在“简单”Malbolge程序中很可能发生,因为C和D从相同的值开始,并且以相同的速度增长。如果希望旋转指令影响当前运行的命令以外的其他内容,则必须以某种方式对它们进行反同步。最简单的方法通常是使用j命令(注意:使用结果数据指针可能不是特别容易,但至少它可能在代码指针之外的其他地方)。

顺便说一句,实际上旋转用户输入比在你给出的示例程序中花费更多的精力。您必须首先将其存储到内存中,唯一能够根据A值编写内存的操作是p,它要求所讨论的单元格已经有一个适当的值(为了避免丢失信息,这需要通过Malbolge的算术生成的值为29524,因为它不能作为原始程序的一部分输入,即使这样,您也会以输入值中的1 trits替换0 trits )。然后,您必须将数据指针发送回写入输入的单元格,这样您就可以在它上运行*来旋转它。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57484219

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档