C函数可以运行尽可能多的寄存器

时间:2014-05-16 14:25:49

标签: c++ c assembly

我正在为多个CPU架构上的汇编程序存根编写测试套件。存根旨在将参数传递给C回调。

我已经编写了测试来覆盖多个场景(例如,通过值传递struct,混合不同原生大小的参数,将float args与int混合等)我现在想要测试回调来执行某些事情这将耗尽大量的寄存器/堆栈插槽等。

我的想法是尝试清除仅由fluke工作的实现(例如,值没有正确地放在堆栈上,但它恰好仍然存在于某个寄存器中,因此您可以使用它等等)。

任何人都可以推荐一款可以用作测试的好C / C ++吗?我意识到寄存器的使用在架构之间变化很大,并且根本无法保证它会得到完全的覆盖,但是有一些能够给出合理的信心的东西会很好。感谢

1 个答案:

答案 0 :(得分:2)

C / C ++标准中没有任何内容可以帮助您。最终唯一可靠的方法就是编译器编写者的方式。他们研究编译器生成的代码,并想出打破它的方法。

话虽如此,我可以想到一些可能会消除一些常见问题的策略。

  1. 使用许多不同的参数类型和数字组合进行调用。例如,具有单个参数或返回值的函数(char / short / int / long / float / double / pointer等)将执行一定范围的编译器代码生成(如果可能,可能会在寄存器中传递)。具有大量参数的相同函数将使用不同的策略,并且(在大多数情况下)没有足够的寄存器。
  2. 将前导码插入到被调用函数中,这样传入的参数不会立即使用,但寄存器会被其他值填充。
  3. 使用可变参数。可变参数的调用约定(特别是使用单独的编译和链接)实际上保证了堆栈上的参数,而不是寄存器中的参数。
  4. 练习许多不同的调用类型:不只是简单的标量,而是按值的结构,指向函数的指针,指向成员的指针等。
  5. 作弊。使用一个原型调用但是转换函数指针,以便被调用者具有不同的原型。例如,在堆栈上调用double,但callee函数有两个long。需要一些编译器工作的内部知识。
  6. 您将找到的唯一预编写的代码是您所选编译器的编译器合规性套件。

    打破编译器很有趣。希望这里的东西可以帮助你做到这一点。