微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > SPMC75和ASM(汇编)混合编程的应用

SPMC75和ASM(汇编)混合编程的应用

时间:10-21 来源:互联网 点击:

3、操作符约束符
  约束符的作用在于指示GCC,使用在汇编指令模板中的操作数的存储类型。表1-1列出了一些约束符和它们分别代表的操作数不同的存储类型,也列出了用在操作数约束符之间的两个约束符前缀。

表 1-1 操作数存储类型约束符及约束符前缀

约束符

操作数存储类型

约束符前缀及含义解释

r

寄存器中的数值

m

存储器中的数值

为操作数赋值

操作数在赋值前先参加运算

i

立即数

p

全局变量操作数

4.2 应用举例
利用嵌入式汇编实现对端口寄存器的操作。

//===================================================================

asm(".include Spmc75_regs.inc"); ( 1 )

//===================================================================

//-------------------------------------

asm("[P_IOD_Attrib_ADDR] = %0 \n\t" \ ( 2 )

"[P_IOD_Dir_ADDR] = %0 \n\t" \ ( 3 )

"[P_IOD_Buffer_ADDR] = %0 \n\t" \ ( 4 )

"[P_IOD_Data_ADDR] = %1 \n\t" \ ( 5 )

: \ ( 6 )

:"r"(0xFFFF),"r"(0x0000) \ ( 7 )

:"1"); ( 8 )

//-------------------------------------

  在C的嵌入式汇编中,当使用端口寄存器时,需要在C文件中加入汇编的包含头文件,(1)所示。那么可以使用端口寄存器的名称,而不必去使用端口的实际地址;(2)、(3)、(4)和(5)分别对端口寄存器的各个属性赋值初始化;(6)没有输出参数;(7)操作数%0=0xFFFF,%1=0x0000,操作数的存储类型都是寄存器中的数值;(8)clobber参数,在寄存器传递实参的时候不能使用寄存器R1。

利用嵌入式汇编实现对端口寄存器的位值读取。

A .

//-------------------------------------

asm("r1 = %1; \n\t" \ ( 1.a )

"tstb [r1],%2; \n\t" \ ( 2.a )

"jz 2; \n\t" \ ( 3.a )

"%0 = 0x01; \n\t" \ ( 4.a )

"jmp 1; \n\t" \ ( 5.a )

"%0 = 0x00; \n\t" \ ( 6.a )

:"=r"(result) \ ( 7 )

:"i"(P_IOD_Buffer),"i"(14) \ ( 8 )

:"1","2"); ( 9 )

//-------------------------------------

B .

//-------------------------------------

// GCC inline ASM start

r1 = 28793; ( 1.b )

tstb [r1],14; ( 2.b )

jz 2; ( 3.b )

R3 = 0x01; ( 4.b )

jmp 1; ( 5.b )

R3 = 0x00; ( 6.b )

// GCC inline ASM end

  上面A、B分别是嵌入式汇编和实际编译出来的代码。首先需要清楚一点%0=i、%1=P_IOD_Buffer、%2=14,通过(7)和(8)行可以了解。(1.a)将端口IOD的地址存放到R1中;(2.a)测试IOD的14位;(3.a)如果等于零跳过两行,即跳过(4.a)和(5.a)在(6.a)中为输出参数赋值0x00;如果不等于零则顺序执行(4.a)为输出参数赋值0x01;(5.a)跳过一行,即跳过(6.a)。通过上面的过程可以应用嵌入式汇编实现对端口位的测试,将测试的结果保存在变量result中,行(7)所示。行(9)clobber参数,约束行(7)的"r"在编译时不能使用R1和R2,所以可以在(4.b)和(6.b)中看到使用了R3。但如果行(9)是":"1","2","3");",那么编译出来的(4.b)和(6.b)中只能使用R4,由此可知":"1","2","3","4");"是绝对不允许的。

典型的应用方式。
  通常的应用是用宏汇编的形式定义出来,使用的时候就象函数一样来使用。

//================================================================

//Function: SETB Function

//Example: SETB(_P_IOA_Data,0x8);

//================================================================

#define SETB(Addr,Num) \

asm( \

"r1=%0;\n\t" \

"r2=%1;\n\t" \

"setb [r1],r2\n\t" \

: \

:"i"(Addr),"i"(Num) \

:"1","2" \

);

SETB ( P_IOD_Data , 14 ); // 置位 IOD14

SETB ( P_IOB_Data , 10 ); // 置位 IOB10

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top