Встроенная сборка GCC: ограничения

Мне трудно понять роль ограничений во встроенной сборке GCC (x86). Я читал инструкцию , который точно объясняет, что делает каждое ограничение. Проблема в том, что, хотя я понимаю, что делает каждое ограничение, у меня очень мало понимания того, почему вы можете использовать одно ограничение вместо другого, или каковы могут быть последствия.

Я понимаю, что это очень широкая тема, поэтому небольшой пример должен помочь сузить фокус. Ниже приводится простая процедура asm, которая просто складывает два числа. Если происходит целочисленное переполнение, оно записывает значение 1 в выходную переменную C.

 int32_t a = 10, b = 5;
 int32_t c = 0; // overflow flag

 __asm__
 (
  "addl %2,%3;"        // Do a + b (the result goes into b)
  "jno 0f;"            // Jump ahead if an overflow occurred
  "movl $1, %1;"       // Copy 1 into c
  "0:"                 // We're done.

  :"=r"(b), "=m"(c)    // Output list
  :"r"(a), "0"(b)     // Input list
 );

Теперь это работает нормально, за исключением того, что мне пришлось произвольно возиться с ограничениями, пока я не добился правильной работы. Первоначально я использовал следующие ограничения:

  :"=r"(b), "=m"(c)    // Output list
  :"r"(a), "m"(b)     // Input list

Обратите внимание, что вместо «0» я использую ограничение «m» для b . Это имело странный побочный эффект: если я скомпилировал с флагами оптимизации и дважды вызвал функцию, по какой-то причине результат операции сложения также сохранится в c . В конце концов я прочитал об « ограничениях сопоставления », которые позволяют указать, что переменная должна использоваться как входной и выходной операнд. Когда я изменил «m» (b) на «0» (b) , это сработало.

Но я действительно не понимаю, почему вы использовали одно ограничение вместо другого. Я имею в виду, что да, я понимаю, что «r» означает, что переменная должна быть в регистре, а «m» означает, что она должна быть в памяти - но я на самом деле не понимаю, каковы последствия выбора одной переменной над другой. есть, или почему операция сложения не t работает правильно, если я выберу определенную комбинацию ограничений.

Вопросы: 1) В приведенном выше примере кода, почему ограничение «m» на b привело к получению c написано? 2) Есть ли какой-нибудь учебник или онлайн-ресурс, в котором более подробно рассказывается об ограничениях?

17
задан Channel72 10 October 2010 в 02:40
поделиться