2015-05-14 143 views
0

我有下面的內嵌彙編代碼。我收到編譯錯誤「錯誤:無效'asm':操作數編號在%hi,%lo存在的每一行%字母后丟失。使用內聯彙編代碼編譯%hi()和%lo()的錯誤

void func() 
{ 

    __asm__ (
    "lis %%r4, %hi(%0);" 
    "ori %%r4,%%r4,%lo(%0);" 
    "stw r3, 0(%%r4);" 
    "lis %%r4, %hi(%0);" 
    "ori %%r4,%%r4,%lo(%0);" 
    "lis %%r3, %hi(%1);" 
    "ori %%r3,%%r3,%lo(%1);" 
    "stw %%r3, 0(%%r4);" 
    ::"r"(var1), "r"(var2)); 
} 

在進一步分析中,我發現內聯程序集會在找到%符號時期望一個數字(%0,%1 ...)。所以把所有%都改爲%%(它只是一個盲注),然後最終得到如下所示的很多。

{standard input}: Assembler messages: 
{standard input}:3394: Error: bad expression 
{standard input}:3394: Error: syntax error; found `h', expected `,' 
{standard input}:3394: Error: junk at end of line: `hi(%r9)' 
{standard input}:3394: Error: bad expression 
{standard input}:3394: Error: syntax error; found `l', expected `,' 
{standard input}:3394: Error: junk at end of line: `lo(%r9)' 
{standard input}:3394: Error: bad expression 

了很多努力後,我才知道,還有,如果我們使用%喜()或%LO內聯彙編代碼中的一些問題。如果我從我的代碼中刪除%hi和%lo,它就會被編譯。任何人都可以建議我如何在內聯彙編代碼中使用%hi()和%lo?

+0

糟糕,我看到你嘗試將%符號加倍。然後查看生成的asm代碼,使用'gcc -S'。 PS:你的代碼至少錯過了clobber列表。 – Jester

+0

@Jester它只是一個盲目的嘗試。我想要做的就是在我的彙編代碼中使用%hi()和%lo。我認爲clobber列表是可選參數,所以我沒有使用它。 –

+0

無論如何,你應該使用它。這是有很好的理由。考慮編譯器在優化時內聯的函數。 – Olaf

回答

0

GNU AS不支持%hi()%lo()。相反,它使用符號上的@h@l後綴來表示高和低部分。另請注意,您不能將其與寄存器操作數一起使用,並且您使用r約束。

+0

我已經嘗試過這個選項,並得到了錯誤{標準輸入}:彙編器消息: {標準輸入}:3394:錯誤:語法錯誤;發現'@',預計',' {標準輸入}:3394:錯誤:垃圾在行末:'@h'。你也可以詳細說明你在代碼中提到的寄存器操作數。 –

+0

您使用了'r'約束,因此編譯器會將您的輸入放入寄存器中,但不能在寄存器中使用'@ h/l',就像您無法使用'%hi/lo'一樣。如果你使用寄存器,編譯器已經加載完整的地址,所以你不需要自己亂用'lis/ori'。 – Jester

+0

那麼如何提供輸入? –