内嵌汇编的注意事项

时间:2022-05-22 12:11:32

在了解内嵌汇编的具体使用方法之后,还有几点事项必须在编程时注意。

(1)必须小心使用物理寄存器。

在使用内嵌汇编程序设计方法时,必须要小心使用物理寄存器,主要指R0~R3、PC、LR寄存器,以及CPSR中的N、Z、C和V标志位等。因为在计算汇编代码中的C表达式时,可能会使用这些物理寄存器,并会修改N、Z、C和V标志位。

例如:

__asm

{

MOV  var,x

ADD  y,var,x/y

           }

计算x/y时R0会被修改。内嵌汇编器探测到隐含的寄存器冲突就会报错。

(2)不要使用寄存器代替变量。

尽管有时寄存器明显对应某个变量,但也不能直接使用寄存器代替变量。

例如:

int bad_f(int x)    //x存放在R0中

{

__asm

{

ADD R0,R0,#1   

      //发生寄存器冲突,实际上R0的值没有变化

}

  return(x);

 }

尽管根据编译器的编译规则R0对应x,但这样的代码会使内嵌汇编器认为发生了寄存器冲突。用其他寄存器代替R0存放参数x,使得该函数将x原封不动地返回。

这段代码的正确写法如下:

int bad_f(int x)

{   __asm

   {

     ADD x,x,#1

     return(x);

}

}

(3)使用内嵌汇编无须保存和恢复寄存器。

事实上,除了CPSR和SPSR寄存器以外,对物理寄存器先读后写都会引起汇编器报错。

例如:

int f(int x)

{

__asm

{

STMFD SP!,{R0}  //保存R0,先读后写,汇编出错

ADD R0,x,ll

EOR x,R0,x

LDMFD SP!,{R0}

}

return(x);

}

(4)LDM和STM指令的寄存器列表中只允许使用物理寄存器。

内嵌汇编可以修改处理器模式、协处理器模式及FP、SL、SB等APCS寄存器。但是编译器在编译时并不了解这些变化,因此必须保证在执行C代码前恢复相应被修改的处理器模式。

(5)汇编语言中的“,”号作为操作数分隔符。

如果有C表达式作为操作数,若表达式中包含有“,”,则必须使用符号“(”和“)”将其归约为一个汇编操作数。

例如:

__asm

ADD x,y,(f(),z)   //"f(),z"为一个带有","的C表达式

}

关于ARM汇编语言编程中的ARM汇编伪指令介绍,以及ARM程序设计中的模块化程序设计、ARM汇编和C/C++的混合语言编程的介绍如上所述。接下来将分别探讨基于ARM处理器的底层驱动开发的方式。