本文介绍了有可能使汇编语言程序永远自我编写吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
基本上,您可以让汇编代码在最后一行结束后不断地编写新代码,以便它可以永远保持直线运行,尽管开始的代码量是有限的吗?不允许循环。推荐答案
它必须是为某种带有无限磁带的机器(如图灵机)组装的,否则最终会到达地址空间的末尾。
除非您对指令指针具有定义明确的无错误回绕语义。您将需要一台在其可用地址空间中没有任何间隙的计算机(因此不是x86-64),而是具有PC相对寻址(因此不是i386)。
可能是RISC,其指令宽度与寄存器相同,如ARM。您需要从几条指令开始,将PC相关存储的编码放到一个寄存器中,然后运行它。除了ARM没有一致的I-缓存外,大多数RISC也没有。也许一个简单的ARM,但实际的Cortex-M0不能支持4G的RAM。或禁用L1i/d缓存的完整内核。
或者重复模式可以是8字节、stp
(存储对)/内存屏障。或者甚至stm
(存储多个),以允许使用单个指令存储多个字,从而为模式包括多个冲洗/屏障指令腾出空间。在重复模式和禁用中断之前,需要多少安装指令都无关紧要。在第一次回绕之后,这些指令字节将被覆盖。
您需要禁用中断,因为您将覆盖内存的每个字节,包括中断向量表。除非您在具有虚拟内存的用户空间进程中执行此操作,例如64位内核下的32位进程,特别修改为不保留任何用户空间页面。然而,在大多数ISA上,诸如中断表之类的内核/系统内容需要在当前地址空间中,因此这可能不可行。页表使用物理地址,因此不必是当前虚拟地址空间的一部分。
虚拟内存将允许您将多个虚拟页面映射到同一物理页面(因此,您实际上可以绕过相同的4k页面),因此,如果32位计算机具有MMU,您可以使用比32位计算机上的4G物理RAM少得多的物理RAM来实现这一点。(但如我所说,您可能仍需要禁用中断。)当然,您可以想象一个简单的玩具ISA,它不需要为任何东西预留任何地址空间。
内存分段确实使这一点变得更容易:您可以在一个段内获得回绕,例如,对于16位x86,64kiB。但是,如果没有与PC相关的存储,您就不能轻松地创建一个实际存储在执行位置前面的1指令模式。有趣的事实:8086没有指令长度限制,实际上可以在没有操作码的情况下对充满前缀的64k代码段进行无休止的循环。(https://retrocomputing.stackexchange.com/questions/15050/what-s-the-last-x86-cpu-that-didn-t-place-a-limit-on-the-size-of-a-single-instru)
我不知道具有分段和PC相关存储的计算机的特定示例。
这篇关于有可能使汇编语言程序永远自我编写吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!