2012-02-25 66 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來訪問定位數據,但它只是隱藏實際問題。