如果手工编写的汇编代码违反了平台的汇编调用约定,是否有办法让汇编器(或静态分析器)发出警告?
我使用的平台是带有GNU GAS汇编程序的ARMv7A。这个问题的原因是我写的一个bug,我的函数没有推入/弹出所需的寄存器(ARM上的R4-R11) upun进入/退出。寄存器被丢弃,导致调用者崩溃(谢天谢地,自动化测试检测到了这个bug)。简化的程序:
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 r0ARM调用约定:http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf
发布于 2012-10-02 09:09:07
我不认为有这样的工具。汇编语言程序员应该非常清楚他们在做什么。
然而,如果你真的想要它,你可以开发这样一个工具。
在它中,您需要解析汇编源代码,并识别修改寄存器的指令,这些指令必须由子例程保留。保存/恢复这些寄存器的指令同上。
您还需要弄清楚子例程的开始和结束位置。可以通过注意指定进入该子例程的入口点的标签被定义为public/global/基本上由链接器从外部可见的标签来识别开头。另一种可能的启发式方法是看到标签在call指令中使用,或者任何与其等效的东西。同样,您可以通过记录执行返回的指令或指令序列来确定子例程的结束。
可能在某些情况下,很难弄清楚开头和结尾,或者寄存器是否真的被丢弃或保存。其中一些问题可以用额外的启发式方法解决。其余的在默认情况下可能会导致警告。假阴性、假警报可能更好,反之亦然。如果代码很小,那么确定警告是否有意义应该很容易。
对于这个任务,你应该考虑一些脚本或脚本语言,它们可以很好地处理字符串,支持正则表达式,并支持使用它们的“标准”容器和算法(搜索/排序等)。Perl和Python可以很好地完成这项工作。我不建议用C或C++来做这件事,因为在开发过程中你需要重写和丢弃大量的小块代码。编译是一个额外的障碍,无论它有多小。调试低级代码或模板并不有趣。
https://stackoverflow.com/questions/12677553
复制相似问题