Встроенный sdcc asm() не работает

Я использую GCC (исправление) SDCC с Eclipse IDE для компиляции кода C для встроенной цели архитектуры 8051. Мне нужно вставить несколько NOP для синхронизации, и я не могу заставить компилятор принимать встроенный код сборки.

С __asm__ ("; This is a comment\nlabel:\n\tnop"); (как предложено ниже) или варианты я получаю предупреждение 112: неявное объявление функции '__asm__' и затем ошибка 101: слишком много параметров, как будто я пытаюсь вызвать необъявленную функцию. Я пробовал все другие опции в разделе 3.14 руководства SDCC. __asm ... __endasm дает синтаксическую ошибку на __asmТо же самое с одним подчеркиванием, и комбинации пробелов, переносов или той же строки не помогают.

Если я правильно соединяю командную строку из Makefile (без пути #include), CFLAGS в командной строке SDCC:

-Wp,-MD,$(@:%.rel=%.d),-MT,$@,-MP --disable-warning 110 -Wa,-p --model-medium

2 ответа

Решение

Перемещено из комментария

В источниках лексера SDCC 3.1.0 я вижу, что оба _asm/_endasm а также __asm/__endasm поддерживаются. Я еще не заметил поддержку __asm("string") в парсере пока нет.

Также в коде лексера тип лексинга встроенного токена "blob" токена изменяется на CPP_ASM только если свойство называется preproc_asm установлен в 0как видно из sdcc/support/cpp/libcpp/lex.c:1900,

      result->type = CPP_NAME;
      {
        struct normalize_state nst = INITIAL_NORMALIZE_STATE;
        result->val.node.node = lex_identifier (pfile, buffer->cur - 1, false,
                                                &nst);
        warn_about_normalization (pfile, result, &nst);
      }

      /* SDCC _asm specific */
      /* handle _asm ... _endasm ;  */
      if (result->val.node.node == pfile->spec_nodes.n__asm || result->val.node.node == pfile->spec_nodes.n__asm1)
        {
          if (CPP_OPTION (pfile, preproc_asm) == 0)
            {
              comment_start = buffer->cur;
              result->type = CPP_ASM;
              _sdcpp_skip_asm_block (pfile);
              /* Save the _asm block as a token in its own right.  */
              _sdcpp_save_asm (pfile, result, comment_start, result->val.node.node == pfile->spec_nodes.n__asm);
            }
          result->flags |= ENTER_ASM;
        }
      else if (result->val.node.node == pfile->spec_nodes.n__endasm || result->val.node.node == pfile->spec_nodes.n__endasm1)
        {
          result->flags |= EXIT_ASM;
        }
      /* Convert named operators to their proper types.  */
      else if (result->val.node.node->flags & NODE_OPERATOR)
        {
          result->flags |= NAMED_OP;
          result->type = (enum cpp_ttype) result->val.node.node->directive_index;
        }
      break;

Решение было добавить #pragma preproc_asm - (или же +) в верхней части файла и использовать мультилинию __asm/__endasm блоки.

Эта ссылка: http://www.crossware.com/smanuals/c8051/_t243.html

имеет это сказать о встроенном коде сборки

Код на ассемблере может быть встроен в ваш исходный код на C двумя способами:

using the #asm/#endasm preprocessor directives
using the _asm keyword

Директивы препроцессора #asm и #endasm позволяют включать ассемблерный код в любом месте файла исходного кода C, единственное ограничение заключается в том, что он не может быть расположен в выражении. Все строки между #asm и #endasm передаются напрямую через неизмененный в промежуточный файл, обрабатываемый ассемблером, и поэтому поддерживаются все правила для исходного кода кросс-ассемблера.

Директивы препроцессора #if, #ifdef, #ifndef, #else, #elif и #endif действительны между #asm и #endasm и поэтому могут использоваться для поддержки кода ассемблера, если это необходимо.

Ключевое слово _asm может использоваться только внутри функций. Он используется со следующим синтаксисом:

_как м();

Строковая константа передается напрямую через неизмененную как единственная строка в промежуточный файл, обрабатываемый ассемблером. Поэтому каждый должен быть верной строкой кода ассемблера.

Одним из преимуществ синтаксиса _asm является то, что он подлежит замене токена препроцессором Си. Следовательно, оператор может быть сгенерирован серией макросов.

Также с синтаксисом _asm компилятор поддерживает специальную конструкцию, обеспечивающую легкий доступ к переменным Си. Если имя переменной помещается в строковую константу в фигурных скобках, компилятор заменяет имя переменной (и фигурные скобки) соответствующей подстрокой в ​​зависимости от расположения переменной. Смотрите следующие разделы для более подробной информации.

Компилятор генерирует мнемонику в верхнем регистре, поэтому, если для встроенного кода ассемблера выбран нижний регистр, его можно четко отличить от кода, сгенерированного компилятором, в файле списка.

тем не менее, правильный формат: '_asm(" nop");' потому что мнемоническая инструкция по сборке не может быть первой строкой (эта привилегия для меток)

Другие вопросы по тегам