2011-12-20 84 views
0

我學習GCC擴展ASM選項不可能約束 - 非特異性GCC消息

asm goto (
    "clc\n" 
    "lo:\t" 
    "lods\t%[ax]\n\t" 
    "lea\t%[wc](%[base], %[off], %[k]), %[la]" 
    "adc\t%[ax], (%[la])\n\t" 
    "inc\t%[off]\n\t" 
    "jnz\tlo\n\t" 
    "jnc\t%l[nocarry]\n" 
    : 
    : [base] "d" (th), [oz] "S" (oz), [wc] "I" (wc*sizeof(uInt)), 
     [k] "N" (sizeof(uInt)), [la] "b" (0), [ax] "a" (0), [off] "c" (-wc) 
    : 
    : nocarry 
); 

而且具有編譯:

> impossible constraint in 'asm' 

試過一個接一個發表意見的所有限制,相同的結果。 請幫忙!

gcc版本4.6.1(Ubuntu的/ Linaro的4.6.1-9ubuntu3),i686的Linux的GNU的(32位), 內核3.0.0-14泛型

回答

3

你的說法是片面和缺乏定義用於填充彙編指令輸入約束的變量。

如果wc只是編譯時常量 - "I"約束必須可評估爲立即數,那麼最有可能的候選是[wc] "I" (wc * sizeof(uInt))表達式。也可能是[k] "N" (sizeof(uInt)),因爲這不符合lea

我建議改變聲明:

asm (
    "lea (%[base], %[off], %[k]), %[base]\n\t" 
    "neg %[off]\n\t" 
    "clc\n\t" 
    "lo: " 
    "lods %[ax]\n\t" 
    "lea (%[base], %[off], %[k]), %[la]\n\t" 
    "adc %[ax], (%[la])\n\t" 
    "inc %[off]\n\t" 
    "jnz lo\n\t" 
    "jnc %l[nocarry]\n" 
: 
: [k] "I"(sizeof(uInt)), [base] "d" (th), [oz] "S" (oz), 
    [la] "b" (0), [ax] "a" (0), [off] "c" (wc) 
: 
: nocarry 
); 

,但你可能要評估讓編譯器更自由地選擇(比如,說[base] "r" (th + wc)假設thuInt*)。同樣,根據您的彙編指令,沒有明確的需要使用"a","b","c""d",因此您可以人爲地限制編譯器可以選擇哪些寄存器。如果這就是你想要的,也許在試圖強制編譯器時更好/更容易地在彙編中編寫函數。

+1

+1對於基於模糊和不明確問題的可靠猜測 – hirschhornsalz 2011-12-20 12:18:44

+0

感謝您提供有用的建議。 'wc'是任意精密ariphmetic類的「長度」成員,其原因是非靜態的。 但實際上我決定改變方法,這是當前(工作:)變體: – leventov 2011-12-20 19:04:07

0
BigInt & BigInt::operator+=(const BigInt &rhs) 
{ 
    this->grow(rhs.wc); 
    uInt *th = (uInt*)words, *oz = (uInt*)rhs.words; 
    asm goto (
     "clc\n" 
     "l1:\t" 
     "mov\t(%[oz]), %[ax]\n\t" 
     "adc\t%[ax], (%[th])\n\t" 
     "lahf\n\t" 
     "add\t%[ws], %[th]\n\t" 
     "add\t%[ws], %[oz]\n\t" 
     "sahf\n\t" 
     "loop\tl1\n\t" 
     "jnc\t%l[nocarry]\n" 
     : 
     : [th] "r" (th), [oz] "r" (oz), 
      [ws] "I" (sizeof(uInt)), [ax] "a" ((uInt)0), "c" (wc) 
     : 
     : nocarry 
    );