3

我在 Eclipse IDE 中使用GCC(更正)SDCC 来为 8051 架构嵌入式目标编译 C 代码。我需要插入一些 NOP 进行计时,而且我无法让编译器接受内联汇编代码。

使用__asm__ ("; This is a comment\nlabel:\n\tnop");(如下所示)或变体,我收到警告 112: function '__asm__' implicit declaration然后错误 101: too many parameters,就好像我正在尝试调用未声明的函数一样。我也尝试了SDCC 手册第 3.14 节中的所有其他选项。__asm ... __endasm给出一个语法错误__asm,与单个下划线相同,并且空格、换行符或同一行的组合没有帮助。

如果我将 Makefile 中的命令行正确拼凑在一起(没有#include 路径),SDCC 命令行上的 CFLAGS 为:

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

4

2 回答 2

1

从评论中移出

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

于 2014-12-31T23:55:41.123 回答
0

此链接: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 语法的一个优点是它可以被 C 预处理器替换。因此,该语句可以由一系列宏生成。

此外,使用 _asm 语法,编译器还支持一种特殊的构造,可以轻松访问 C 变量。如果变量名放在大括号内的字符串常量中,编译器会根据变量的位置用适当的子字符串替换变量名(和大括号)。有关详细信息,请参阅以下部分。

编译器生成大写助记符,因此如果为内联汇编代码选择小写,则可以清楚地区分它与列表文件中编译器生成的代码。

但是,正确的格式是:'_asm("nop");' 因为助记汇编指令不能是一行的第一件事(该特权用于标签)

于 2014-12-31T04:17:08.010 回答