首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >自动检测程序集调用约定的冲突

自动检测程序集调用约定的冲突
EN

Stack Overflow用户
提问于 2012-10-02 00:48:38
回答 1查看 194关注 0票数 4

如果手工编写的汇编代码违反了平台的汇编调用约定,是否有办法让汇编器(或静态分析器)发出警告?

我使用的平台是带有GNU GAS汇编程序的ARMv7A。这个问题的原因是我写的一个bug,我的函数没有推入/弹出所需的寄存器(ARM上的R4-R11) upun进入/退出。寄存器被丢弃,导致调用者崩溃(谢天谢地,自动化测试检测到了这个bug)。简化的程序:

代码语言:javascript
复制
my_function:
    mov     r4, #42  @Trash register r4 in violation of calling convention
    bx      lr       @Return from function

caller:
    ...
    mov r4, #4        @Initialise register r4, to be used later
    bl my_function    @Call my_function with no arguments
    mov r0, r4        @Set argument r0 as r4 (== 42, but should be 4)
    bl other_function @Call other_function with (the now trashed) argument r0

ARM调用约定:http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf

EN

回答 1

Stack Overflow用户

发布于 2012-10-02 09:09:07

我不认为有这样的工具。汇编语言程序员应该非常清楚他们在做什么。

然而,如果你真的想要它,你可以开发这样一个工具。

在它中,您需要解析汇编源代码,并识别修改寄存器的指令,这些指令必须由子例程保留。保存/恢复这些寄存器的指令同上。

您还需要弄清楚子例程的开始和结束位置。可以通过注意指定进入该子例程的入口点的标签被定义为public/global/基本上由链接器从外部可见的标签来识别开头。另一种可能的启发式方法是看到标签在call指令中使用,或者任何与其等效的东西。同样,您可以通过记录执行返回的指令或指令序列来确定子例程的结束。

可能在某些情况下,很难弄清楚开头和结尾,或者寄存器是否真的被丢弃或保存。其中一些问题可以用额外的启发式方法解决。其余的在默认情况下可能会导致警告。假阴性、假警报可能更好,反之亦然。如果代码很小,那么确定警告是否有意义应该很容易。

对于这个任务,你应该考虑一些脚本或脚本语言,它们可以很好地处理字符串,支持正则表达式,并支持使用它们的“标准”容器和算法(搜索/排序等)。Perl和Python可以很好地完成这项工作。我不建议用C或C++来做这件事,因为在开发过程中你需要重写和丢弃大量的小块代码。编译是一个额外的障碍,无论它有多小。调试低级代码或模板并不有趣。

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

https://stackoverflow.com/questions/12677553

复制
相关文章

相似问题

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