簡體   English   中英

如何告訴 gcc 不對齊堆棧上的 function 參數?

[英]How to tell gcc to not align function parameters on the stack?

我正在嘗試將 68000 處理器的可執行文件反編譯為 C 代碼,將原始子程序一一替換為 C 函數。

我面臨的問題是我不知道如何讓 gcc 使用與原始程序中使用的調用約定相匹配的調用約定。 我需要將堆棧上的參數打包,而不是對齊。

假設我們有以下 function

int fun(char arg1, short arg2, int arg3) {
    return arg1 + arg2 + arg3;
}

如果我們編譯它

gcc -m68000 -Os -fomit-frame-pointer -S source.c

我們得到以下 output

fun:
    move.b 7(%sp),%d0
    ext.w %d0
    move.w 10(%sp),%a0
    lea (%a0,%d0.w),%a0
    move.l %a0,%d0
    add.l 12(%sp),%d0
    rts

如我們所見,編譯器假定參數的地址為7(%sp)10(%sp)12(%sp)

堆棧上不需要的參數定位的圖示

但要使用原始程序,他們需要有地址4(%sp)5(%sp)7(%sp)

所需參數位置的圖示

一種可能的解決方案是按以下方式編寫 function(處理器為大端序):

int fun(int bytes4to7, int bytes8to11) {
    char arg1 = bytes4to7>>24;
    short arg2 = (bytes4to7>>8)&0xffff;
    int arg3 = ((bytes4to7&0xff)<<24) | (bytes8to11>>8);
    return arg1 + arg2 + arg3;
}

但是,代碼看起來很亂,我想知道:有沒有辦法既保持代碼干凈又達到預期的結果?


UPD:我犯了一個錯誤。 我正在尋找的偏移量實際上是5(%sp)6(%sp)8(%sp) (char-s 應該與 short-s 對齊,但 short-s 和 int-s仍然包裝):

更新后所需參數位置的圖示

希望這不會改變問題的本質。


UPD 2:事實證明,Sierra Systems 的 68000 C 編譯器給出了所描述的偏移量(如在 UPD 中,具有 2 字節對齊)。

但是,問題是關於調整 gcc(或者可能是另一個現代編譯器)中的調用約定。

這是一種打包結構的方法。 我在帶有-m32的 x86 上編譯它並在反匯編中獲得了所需的偏移量,所以我認為它仍然適用於 mc68000:

typedef struct {
    char arg1;
    short arg2;
    int arg3;
} __attribute__((__packed__)) fun_t;

int
fun(fun_t fun)
{

    return fun.arg1 + fun.arg2 + fun.arg3;
}

但是,我認為可能還有更清潔的方法。 這將需要更多地了解生成此類調用序列的其他代碼。 你有它的源代碼嗎?

其他代碼是否必須保留在 asm 中? 使用源代碼,您可以調整 asm 代碼中的偏移量以與現代 C ABI 調用約定兼容。

自 1981 年以來,我一直在 C 中編程,並花了數年時間做 mc68000 C 和匯編代碼(對於應用程序,Z50484C19F1AFDAF3841A0D821ED393D2 有點熟悉問題空間設備驅動程序)。

這不是 gcc 的“故障”,它是 68k 架構,要求堆棧始終在 2 個字節上對齊。 所以根本沒有辦法打破硬件堆棧上的 2 字節 alignment。

但要使用原始程序,他們需要有地址 4(%sp)、5(%sp) 和 7(%sp):

從 ODD memory 地址訪問 word 或 long 值將立即觸發 68000 上的 alignment 異常。

要獲取使用 2 字節 alignment 而不是 4 字節 alignment 傳遞的整數參數,您可以通過-mshort將默認int大小更改為 16 位。 您需要將代碼中的所有int替換為long (如果您希望它們為 32 位寬)。 執行此操作的粗略方法是將-Dint=long也傳遞給您的編譯器。 顯然,您將破壞 ABI 對使用-mno-short編譯的 object 文件的兼容性(這似乎是 gcc 的默認設置)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM