4

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

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

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

4

1 回答 1

0

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

但是,如果您真的很喜欢它,您可以开发这样的工具。

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

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

在某些情况下,很难弄清楚开始和结束,或者寄存器是否真正被丢弃或保存。其中一些可以通过额外的启发式方法来解决。其余的默认情况下会导致警告。最好有误报、误报,然后反过来。如果代码很小,那么判断警告是否有意义应该很容易。

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

于 2012-10-02T01:09:06.837 回答