目录
背景
最近在跟着野火码uCosiii的代码时,感觉非常完美,结果一编译,报了120个莫名其妙的问题,下面是踩过的坑,一起记录下,免得下次又掉进去了~
1. 编译汇编文件,报错 error: unexpected token at start of statement
如果在编译的时候出现大面积相同的错误,可以考虑文字编码、格式、编译器选择的问题。
前两个错误排除,我这里属于编译器设置问题。
像如下这样修改汇编编译的设置项,Rebuild后,此错误消除。
打开“Options for Target XXXX”窗口,点击“Asm”打开汇编配置页面,查看“Assambler Option”项设置的内容,开始时选的是第一个 Auto,报错不认识。
修改为第3个或第4个(asmclang(Asm Syntax)或asmasm)都可以。
这个问题貌似还与KEIL的版本有点关系,如果上面的方法解决不了,考虑是KEIL的版本差异导致。这里的版本是5.30。
2. 编译汇编文件,报错 Error: A1163E: Unknown opcode OSTCBCurPtr , expecting opcode or Macro
这种错误一般是汇编代码的格式问题导致,注意:
ARM汇编指令不支持顶格写,否则不能识别,
所以,除了标号外的代码,在代码前要有空格才可以哦:
例如:
这样写报错:
IMPORT OSTCBCurPtr ; 外部文件引入的参考(1)
这样修改后OK:
IMPORT OSTCBCurPtr ; 外部文件引入的参考(1), 前面加了一个Tab(即:4个空格)
3. 编译汇编文件,报错 Fatal error: A1355U: A Label was found which was in no AREA
出现这个错误的原因有如下几种:
1)汇编代码的格式不对
ARM官网对这个Error的解释如下:
A1355U: A Label was found which was in no AREA
Example:
This can occur where no white-space precedes an assembler directive.
Assembler directives must be indented with white-space, for example:
use(应该这样写):
IF :DEF: FOO
; code
ENDIF
not(不能这样写):
IF :DEF: FOO
; code
ENDIF
Symbols in the left hand column 1 are assumed to be labels, hence the error message.
大体的意思是汇编指令前必须至少有一个空格,这个是编译器规定的,没啥说的。当编译器在编译汇编代码时,在本应为空格的第一列发现了代码,即认为出错,就报这个错误。
解决的办法也很简单,就按照官网说的,在汇编之前加个空格就可以了。
2)将分散加载文件加到了Keil的工程中
如果分散文件 *.sct 加入到了工程中,而分散加载代码不属于C也不属于汇编,所以KEIL调用编译器进行编译时会报错。
知道了原因,解决方法也显而易见,直接将分散加载文件从工程中删除,在KEIL中打开“Options for Target XXXX”窗口,点击“Linke2r”打开链接页面,“Scater File”项后设置路径就可以了。
3)没有定义段
ARM汇编语言程序中,程序是以程序段为单位组织代码的。段是相对独立的指令或者代码序列,拥有特定的名称。段的种类有代码段、数据段和通用段,代码段的内容为执行代码,数据段存放代码运行时需要用到的数据,通用段不包含用户代码和数据,所有通用段共用一个空间。
一个汇编程序至少应该有一个代码段,可以有零或者多个数据段。在格式上,一个汇编程序需要至少有一个ENTRY(关于ENTRY具体内容看伪操作符ENTRY)。如果没有定义段,程序在链接时会报错。
段使用AREA伪操作来定义。
这里,我在汇编中添加如下段定义,重新编译,问题解决:
AREA CODE, CODE, READONLY
未完待续……
参考资料
[1]. https://blog.csdn.net/du103511/article/details/113649071
[2]. https://blog.csdn.net/sdwuyulunbi/article/details/5104977
[3]. https://blog.csdn.net/weixin_30311605/article/details/96679845