2012-02-25 62 views
0

我正在研究大学的Pintos玩具操作系统,但使用GCC 4.6.2时出现了一个奇怪的错误。当我推入我的系统调用参数(在内联程序集中只有3个pushl-s)时,一些神秘的数据也出现在堆栈上,并且参数的顺序错误。设置-fno-omit-frame-pointer可以消除奇怪的数据,但参数仍然是错误的顺序。 GCC 4.5正常工作。任何想法什么具体选项可以解决这个问题GCC的神秘堆栈问题4.6.2

注意:问题仍然发生在-O0。

+3

最小的示例代码? – 2012-02-25 22:47:49

回答

0

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

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移动它。

我需要查看您的代码才能更好地了解发生了什么。

+0

使用三个pushl-s传递参数,然后按下系统呼叫号码(在asm volatile中)。但是,当内核段看到内存的参数是3 1 2顺序(甚至垃圾,取决于选项)。使用GCC 4.5,他们处于正确的位置,而且顺序正确。 – 2012-02-26 13:32:23

+0

@vahokif你能展示一个代码示例吗?我不知道我能否解决这个问题,但即使看代码也几乎是不可能的。当然,编译器中有时会出现错误。在这种情况下,您可能需要提交错误报告。 – 2012-02-26 13:59:09

0

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