与GCC 4.6.2的神秘堆栈问题

时间:2012-02-25 22:44:02

标签: gcc assembly stack osdev

我正在大学从事Pintos玩具操作系统,但使用GCC 4.6.2时有一个奇怪的错误。当我推动我的系统调用参数(在内联汇编中只有3个pushl-s)时,一些神秘的数据也出现在堆栈中,并且参数的顺序错误。设置-fno-omit-frame-pointer摆脱了奇怪的数据,但参数仍然是错误的顺序。 GCC 4.5工作正常。知道具体的选项可以解决这个问题吗?

注意:-O0仍会出现问题。

3 个答案:

答案 0 :(得分:1)

如果没有代码示例以及来自不同编辑的结果列表,则很难为您提供帮助。但是,这有三个可能的原因导致您的问题:

  1. 确保您了解如何将参数推送到堆栈。从后面推出争论。这使得printf(char *, ...)可以检查第一项以找出其中有多少项。如果您想调用函数int foo(int a, int b, int c),则需要按 c ,然后 b ,最后 a
  2. 堆栈上的奇怪数据可能是返回地址还是EFLAGS?我不知道Pintos以及如何进行系统调用,但请确保您了解CALL / RET和INT / IRET之间的区别。 INT将标志推入堆栈。
  3. 如果您的内联汇编有副作用,您可能需要在其前面写volatile / __volatile__。否则,GCC在优化时可以移动它。
  4. 我需要查看您的代码,以便更好地了解正在发生的事情。

答案 1 :(得分:0)

罪魁祸首是-fomit-frame-pointer,自4.6.2以来默认启用。 -fno-omit-frame-pointer解决了这个问题。

答案 2 :(得分:0)

你是否在系统调用后清理堆栈上的参数? gcc可能没有意识到你触摸堆栈并生成代码取决于它预期的堆栈指针。 -fno-omit-frame-pointer强制gcc使用e / rbp访问定位数据,但它只是隐藏了实际问题。