snifer

[原创]ADI ADuC7026内嵌汇编一次出错的启发

0
阅读(4403)

上午有个同学给我提交了分配给他的任务,在使用ADuC7026时,遇到以下问题:
将P4.1口输出一个高一个低电平,C和汇编的指令要完成的功能是一样的,只是个测试。
测试后,C这两句输出正常,可运行汇编的却没有任何反映。仔细单步观察相关寄存器,C运行时和汇编运行时完全一样,即GP4DAT都是先是0xFE020002,然后是0xFE000000
      GP4SET = #0x00020000;
GP4CLR = #0x00020000;

asm("LDR R9,0xFFFFF460");
asm("ORR R9,R9,#0x00020000");
asm("STR R9,0xFFFFF460");
asm("BIC R9,R9,#0x00020000");
asm("STR R9,0xFFFFF460");


在主程序和一些子程序中嵌入后出现错误:
Error[Og006]: Syntax error in inline assembly: "Error[401]: Operand syntax error" I:\ADuC702x\code2\IAR Code Examples\whq\UART_whq.c 50  

下面我针对这个问题写一下相关的问题,讲完了估计大家就明白了。

在C程序中嵌入汇编程序可以实现一些高级语言没有的功能,并可以提高执行效率。
__asm指令[;指令]);
ARM C汇编器使用关键字__asm"。如果有多条汇编指令需要嵌入,可以用{}将它们归为一条语句。如:
 
__asm
指令[;指令]
[指令]
需要特别注意的是__asm是两个下划线。
内嵌的汇编指令的特点:
 
操作数可以是寄存器、常量或C表达式。它们可以是char、short或者int类型,而且是作为无符号数进行操作。 内嵌的汇编指令中使用物理寄存器有一些限制。 常量前的符号“#”可以省略 只有指令B可以使用C程序中的标号,指令BL不能使用C程序中的标号。 不支持汇编语言中用于内存分配的伪操作。 指令中如果包含常量操作数,该指令可能会被汇编器展开成几条指令。
注意事项:
1内嵌汇编器不支持通过“·”指示符或PC获取当前指令地址;
2不支持LDR Rn,= expression伪指令,而使用MOV Rn,expression指令向寄存器赋值;
3不支持标号表达式;
4不支持ADR和ADRL伪指令;
5不支持BX和BLX指令;
6不可以向PC赋值;
7使用0x前缀替代“&”表示十六进制数。
严重提示:
1必须小心使用物理寄存器,如R0~R3LRPC
 
*2不要使用寄存器寻址变量。
*3使用内嵌汇编时,编译器自己会保存和恢复它可能用到的寄存器,用户无须保存和恢复寄存器。
*4LDMSTM指令的寄存器列表只允许物理寄存器。
*5汇编语言用作为操作数分隔符
 明白了以上几点相信就明白了为什么会出错了,学习中要把一个原理吃透才能学以致用,灵活处理,每个人都会有不一样的收获。