簡體   English   中英

如何在內聯匯編中使用可變偏移量?

[英]How to use a variable offset in inline assembly?

我試圖解決的總體問題是調用printf,同時從原始緩沖區中獲取其格式字符串和參數。 到目前為止,似乎效果最好的解決方案是通過使用內聯匯編作為將混合類型可變參數傳遞給函數的一種方式。

當前,字符和整數都可以正常工作,並且浮點數/雙精度數一直起作用,直到需要將它們傳遞到堆棧中為止。 (通過xmm0-xmm7可以完美地為我們工作)。 目的是一旦使用完xmm0-xmm7,就將這些浮點值壓入堆棧。 這些值將在隨后的printf調用中使用。 我們處理char和int的方法是僅通過使用push指令就可以將它們壓入堆棧,對printf的調用可以很好地使用它,但是由於該指令不適用於浮點值,因此我們必須使用以下方法手動將其“推入”堆棧。 我意識到這很可能是處理此問題的錯誤方法,但是我們還沒有辦法解決這種問題。

當前,我們要在堆棧上傳遞八個以上浮點值的解決方案要求我們知道傳遞給printf調用的參數的偏移量。 在這種情況下,偏移量對應於8個字節的增量。 第9個參數將加載到(%rsp) ,第10個參數將加載到0x8(%rsp) ,第11個參數將加載到0x10(%rsp) ,第12個參數將加載到0x18(%rsp) ,其余參數將繼續這種趨勢。

我的“可變偏移量”目標是減少處理遞增偏移量的重復代碼量。 當前,它僅檢查正在處理的參數,並跳轉到硬編碼的常量偏移量。 但這導致了很多重復的代碼,我希望將它們清理掉。

以下是我們目前正在做的一小段操作,即將參數之一移至其適當位置,以便調用printf來訪問參數。

double myDouble = 1.23;
asm volatile (
  "movsd %0, 0x8(%%rsp)" #The 0x8 is the offset we are hoping to pass in
:: "m" (myDouble)
);

我正在尋找一種方法來將該偏移量(0x8、0x10、0x18 ...)存儲在一個變量中,該變量在處理參數時可以增加8,盡管現在我擔心一旦我們開始混入更多變量,該偏移量就會破壞混合類型值被壓入堆棧。

任何指導將不勝感激!

使用具有恆定偏移量的指令是不可能的。 為了生成代碼,需要在編譯時知道偏移量,並且該偏移量不是可變的。 您必須使用另一條指令,使用基址寄存器和偏移量進行間接加載:

int foo(int64_t offset, double value)
{
    asm volatile (
        "movsd %0, (%%rsp,%1)" :: "x" (value), "r" (offset)
        : "memory"
    );
}

您還可以通過使用比例偏移量尋址模式讓CPU乘以8:

int foo(int64_t offset, double value)
{
    asm volatile (
        "movsd %0, (%%rsp,%1,8)" :: "x" (value), "r" (offset)
        : "memory"
    );
}

或者,如果您要模擬push ,則sub $8, %%rsp movsd %0, (%%rsp) / movsd %0, (%%rsp) ,但是您不能在不中斷編譯器生成的代碼的情況下弄亂內聯asm的堆棧指針。

暫無
暫無

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

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