我有一个应用程序的汇编指令列表,我想知道哪些寄存器可以免费使用,以及在列表的任何索引处使用了哪些寄存器。
如何知道何时使用寄存器以及何时将其释放(可以再次使用)?我的目标是到达真正免费的寄存器。
这是我解决问题的假设,因为我对装配知识如此有限,所以听起来可能很愚蠢。
术语:读取(源),写入(目标)
它能解决问题还是有意义?我也对其他解决方案持开放态度。
评论后更新:
我看到JMPS /调用/条件移动搞砸了所有这些。为了保证安全(安全=免费寄存器真的免费),做这样的事情怎么样:当我看到每个跳/呼/有条件移动到外面时,我将所有寄存器标记为"正在阅读&#34 ;哈罗德描述的最极端悲观假设。我相信在这种情况下我会得到更安全的结果,即使它不会很好,因为寄存器大部分时间都处于繁忙状态。您是否同意我的结果会以这种方式安全?
说明:
结果:
更新2
我会将应用程序拆分为基本块,其中每个块代表跳转(也是条件),调用和返回之间的一大块代码。跳转语句将是块的结尾。然后,假设所有寄存器在开始时都在使用,我将分析每个块。我可能会错过很多免费注册,但当我得到一个,我知道那个是真的免费注册=)
更新3
我仍在尝试根据反馈改进解决方案(感谢哈罗德)。
我已经阅读了活体分析,据我所知,建议从应用程序结束到开始进行分析。但我不知道在编译程序集中应用程序的结束,如下面的评论中提到的停止问题,所以我将对未来的分支做另外的处理。
may_continue_with
容器,该容器包含指向它可能继续的分支的指针。答案 0 :(得分:5)
第1步很简单,只需要很多实际工作(需要解析x86机器代码),有些库可能对此有所帮助。
由于控制流程,步骤2并不像听起来那么容易。在控制流程简单的假设下,活跃度分析是众所周知的问题。在这种情况下还有一些额外的问题。
switch
被编译到跳转表时。实际上,并不能保证变量跳跃首先是过程间的,你可能大部分都认为......我真的不知道该怎么办。然后我将分析每个块,假设所有寄存器在开始时都在使用。
这是一个巨大的浪费,通过适当的liveness analysis可以轻松避免。