我在Eclipse IDE中使用 GCC (更正)SDCC来编译8051架构嵌入式目标的C代码。我需要插入几个NOP用于计时,我不能让编译器接受内联汇编代码。
使用__asm__ ("; This is a comment\nlabel:\n\tnop");
(如下所示)或变体,我得到警告112:功能' __ asm __'隐式声明然后错误101:参数太多,就像我试图调用未声明的函数一样。我还尝试了SDCC manual第3.14节中的所有其他选项。 __asm ... __endasm
在__asm
上提供了语法错误,与单个下划线相同,并且空格,换行符或同一行的组合无法提供帮助。
如果我正确拼接Makefile中的命令行(没有#include路径),SDCC命令行上的CFLAGS是:
-Wp,-MD,$(@:%.rel=%.d),-MT,$@,-MP --disable-warning 110 -Wa,-p --model-medium
答案 0 :(得分:1)
已从comment
移出在sources of SDCC 3.1.0的词法分析器中,我看到支持_asm/_endasm
和__asm/__endasm
。我还没有注意到解析器中对__asm("string")
的支持。
同样在lexer的代码中,内联汇编令牌的lexing类型" 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
块。
答案 1 :(得分: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");'因为助记符汇编指令不能是一行中的第一件事(该特权是标签)