f2812的语言与标准c不同,F2812中C语言调用汇编函数(续)

本文详细介绍了如何在TMS320系列DSP上使用C语言调用汇编编写延时函数,包括函数定义、全局声明、参数传递规则,并提供实例演示。同时涵盖了C语言与汇编间变量引用的技巧,帮助开发者理解和实践跨语言编程。
摘要由CSDN通过智能技术生成

参考资料:

(1) SPRU514 ---- TMS320F28x Optimizing C/C++ Compiler User’s Guide.pdf;

(2) spru430d ---- TMS320C28x DSP CPU and Instruction Set Reference Guide;

(3) spru513c ---- TMS320C28x Assembly Language Tools User's Guide.

一、编写C语言能调用的.asm文件

以delay.asm为例:

1、将文件保存为.asm文件;

2、在文件中编写如下代码:

;*********************************************************************/

;* 鲍正华 */

;* 2010.07.09 */

;*********************************************************************/

;//###########################################################################

; @FunctionName:        Delay_asm

;

; @Brief:    延时1s

;

; @Param:  unsigned long cnt 传给 ACC

;

; @Return: 无

;//###########################################################################

.def _Delay_asm

.global  _Delay_asm

.sect".delayasmpage"

_Delay_asm:

SUB    ACC,#1       ;1 clk

BF     _Delay_asm,GEQ  ;4/4 clk,  Loop if ACC >= 0

LRETR    ;4 clk

;There is a 9/10 cycle overhead and each loop

;takes five cycles. The LoopCount is given by

;the following formula:

;  DELAY_CPU_CYCLES = 9 + 5*LoopCount

; LoopCount = (DELAY_CPU_CYCLES - 9) / 5

; The macro DELAY_US(A) performs this calculation for you

;***********************************************************************/

;        No     more

;***********************************************************************/

3、在步骤2中:

.def _Delay_asm用来定义函数名;

.global  _Delay_asm将函数名全局化,以便在C文件中能够调用;

.sect".delayasmpage"将函数定位到定义的段中,也可以是.text,可以灵活运用;

_Delay_asm:为函数标号,注意一定在前面加上下划线_否则C文件不能调用;

LRETR是函数返回,采用了RPC时必须用该指令。

4、在C文件中对函数原型进行声明:

extern void Delay_asm(unsigned long cnt);

5、在C 文件中以C语言形式调用汇编函数:

//延时1s

Delay_asm(18000000L);

6、上边的参数unsigned long cnt传递给了累加器ACC。

二、C语言调用汇编函数时的参数传递

参考(1) SPRU514 ---- TMS320F28x Optimizing C/C++ Compiler User’s Guide.pdf中的page168~169中的内容。

要点:

1、如果汇编语言中修改了XAR1、XAR2和XAR3的值,必须对它们进行保护:

;保存XAR1、XAR2、XAR3,以防程序修改, 若程序没有修改可以不用压栈保护

PUSH XAR1         ;1 clk

PUSH XAR2         ;1 clk

PUSH XAR3         ;1 clk

.

.

.

;恢复XAR1、XAR2、XAR3

POP XAR3  ;1 clk

POP XAR2  ;1 clk

POP XAR1  ;1 clk

2、16位参数从左至右依次传递给:AL、AH、XAR4、XAR5;

3、指针参数依次传递给:XAR4、XAR5,其它指针参数放到stack中;

4、32位的参数传递给累加器ACC(AH/AL),其它32位参数放到stack中。

例子:

(1)汇编代码:

;//###########################################################################

; @FunctionName:        _Xintf_memcpy_asm

;

; @Brief:    copy指定xintf

;

; @Param:  dest_addr, src_addr, length

;

; @Return: 无

;//###########################################################################

.def _Xintf_memcpy_asm      ;函数定义

.global  _Xintf_memcpy_asm         ;函数全局声明,以便C能够调用

.sect".xintfmemcpyasmpage"         ;以下为代码段

_Xintf_memcpy_asm:   ;标号必须从第1列开始,而汇编语言助记符不能从第1列开始

;保存XAR1、XAR2、XAR3,以防程序修改, 若程序没有修改可以不用压栈保护

;PUSH XAR1        ;1 clk

;PUSH XAR2        ;1 clk

;PUSH XAR3        ;1 clk

;copy指定区域(从XAR4指定区域copy到XAR5指定区域)

$1:

MOV AR6, *XAR5++     ;4 clk

MOV *XAR4++, AR6     ;1 clk

SUB ACC, #1       ;1 clk

BF $1, GT   ;4/4 clk, 大于则跳转

;恢复XAR1、XAR2、XAR3

;POP XAR3 ;1 clk

;POP XAR2 ;1 clk

;POP XAR1 ;1 clk

LRETR       ;4 clk, 程序返回

(2)C文件中对函数原型的声明:

extern void Xintf_memcpy_asm(unsigned int* dest_addr, unsigned int* src_addr, unsigned long length);

(3)C文件中以函数原型形式对汇编函数进行调用:

Xintf_memcpy_asm((unsigned int*)ZONE6ADDRESS, (unsigned int*)ZONE2ADDRESS, 102400L);

(4)这里参数传递过程是:ZONE6ADDRESS 传递给XAR4, ZONE2ADDRESS 传递给XAR5, 102400L 传递给ACC

三、C语言与汇编语言之间的变量引用

1、C语言引用汇编语言中定义的变量:

(1)访问在.bss段中定义的变量

汇编语言:

;变量定义,需要在变量前加下划线:_

.bss _var, 1

.global _var

C语言:

//变量声明,不要在变量前加下划线:_

extern unsigned int var;

//变量使用

var = 0x0006;

注意:在变量窗口中var表示变量地址0x 000080A3,要看变量的值,可以将该地址值0x000080A3输入到view memory中观看,其值为0x0006。

51943512_1.jpg

2、汇编语言引用C语言中定义的变量:

C语言:

//变量定义,不要在变量前加下划线:_

unsigned int asmdata;

//给变量赋值

asmdata = 0x0023;

汇编语言:

;变量引用,需要在变量前加下划线:_

.global _asmdata

;调用C中定义的变量

MOVL XAR6, #_asmdata       ;将asmdata变量地址存于XAR6中

MOV AL, *XAR6  ;将变量asmdata值存于AL中

;重新给asmdata赋值

MOV *XAR6, #0x2222

MOV AL, *XAR6

注意:这里在变量窗口中可以直接观察变量asmdata的值0x2222。

51943512_2.jpg

3、汇编语言引用C语言中定义的数组:

C语言:

//数组定义并初始化,不要在变量前加下划线:_

unsigned int asm_var1[4] = {1,2,3,4};

汇编语言:

;变量引用,需要在变量前加下划线:_

.global _asm_var1

;调用C中定义的数组,将其首地址存到XAR7中

MOVL XAR7, #_asm_var1

;zone2

MOVL XAR4, #0x080000 ;将zone2起始地址存入XAR4

;4 words

MOV @AR0, #0x0000      ;zone2写长度计数存入AR0

;写zone2

LOOP1:

;写1

MOV AL, *XAR7++       ;1 clk

MOV *XAR4++, AL

;写2

MOV AL, *XAR7++       ;1 clk

MOV *XAR4++, AL

;写3

MOV AL, *XAR7++       ;1 clk

MOV *XAR4++, AL

;写4

MOV AL, *XAR7++       ;1 clk

MOV *XAR4++, AL

BANZ LOOP1, AR0--    ;4/2 clk

注意:运行结果如下,可见zone2依次写入了数据:1、2、3、4。

51943512_3.jpg

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值