2011-12-20 2 views
0

Я учусь GCC расширенные опции ASMневозможно ограничение на ассемблере - неспецифическое НКУ сообщение

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-гну (32 бита), ядро ​​3.0.0-14-родовой

ответ

3

Ваше утверждение является частичным и не хватает определений переменных, используемых для заполнения входных ограничений вашей инструкции по сборке.

Наиболее вероятным кандидатом является выражением [wc] "I" (wc * sizeof(uInt)) если wc что-нибудь еще, но время компиляции константа - "I" ограничения должны быть evaluatable к непосредственным. Также может быть [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) предполагая th является uInt*). Аналогично, с инструкциями по сборке у вас нет, нет явной необходимости использовать "a", "b", "c" или "d", поэтому вы искусственно ограничиваете, какие регистры могут выбрать компилятор. Если это то, что вы хотите, возможно, полностью написать функцию в сборке лучше/проще, чем пытаться принудить компилятор.

+1

+1 Для твердых догадок, основанных на неопределенном и неясном вопросе – hirschhornsalz

+0

Благодарим за полезные советы. 'wc' является« длинным »членом произвольного арифметического класса точности, вызывающим нестатический характер. Но на самом деле я решил изменить подход, это текущий (рабочий вариант :): – leventov

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 
    ); 
Смежные вопросы