共1条
1/1 1 跳转至页
针对Ti的DSP C语言编程(2)
For [C6000]!
C编译器在编译处理函数调用时,有一套非常
之严格的规则,所有的函数调用:C语言编写的函
数调用汇编语言编写的函数、汇编语言编写的函
数调用C语言编写的函数、C语言编写的函数调用
C语言编写的函数、汇编语言编写的函数调用汇
编语言编写的函数,都必须遵守这套规则,否则
就有可能破坏运行的上下文环境,导致程序运行
失败。
一、一个函数调用另外一个函数需要做些什么?
------------------------------------------
1.为被调用的函数准备好参数
参数的传递有一套规则:被调用的函数前十个参
数是通过下面十个寄存器来传递:A4,B4,A6,B6,
A8,B8,A10,B10,A12,B12,如果参数不足十个,
那么按照它们的次序来使用,不能出现A4没有使
用就是用B4及其类似的情况;如果参数是longs、
doubles或者long doubles类型,那么它们用寄
存器对来传递:A5:A4,B5:B4,A7:A6等等,这样
的寄存器对共计10个;如果参数的数目多于十个,
那么剩下的参数通过堆栈来传递,在传递之前,
这些参数必须进行调整:如果一个参数的大小小
于int型的大小,也就是说不足32bit,那么该参
数调整成int型压到堆栈中去;如果一个参数是
float型,那么要调整成double型压入堆栈。如
果参数是结构体,那么传递的是结构体变量的地
址;如果一个函数定义为可变个参数的函数,那
么明确定义的最后一个参数及其后面的参数通过
堆栈来传递,前面的通过寄存器来传递。例如:
int func1(int a, int b, int c)
A4 A4 B4 A6
int func2(int a, float b, int *c, struct A d,float e, int f, int g)
A4 A4 B4 A6 B6 A8 B8 A10
int func3(int a, double b, float c, long double d)
A4 A4 B5:B4 A6 B7:B6
int vararg(int a, int b, int c, int d, ...);
A4 A4 B4 A6 stack ...
struct A func4( int y);
A3 A4
2.A0-A9和B0-B9中,被使用的寄存器需要压栈保
护;
3.执行被调用的函数;
4.如果调用的函数是C语言编写的,那么不存在这
步,因为编译器在编译C代码的时候会自动生成这
样的代码,而且在C函数返回之前就已经调整好了;
但是如果调用的函数是汇编语言编写的,那么就
要调整堆栈指针以回收用来传递参数的堆栈空间;
二、一个函数被调用,那么该函数需做些什么?
------------------------------------------
1.在堆栈中分配足够的空间,这些空间是用作该
函数体内出现的局部变量、临时存储单元、可能
调用的函数的参数空间等等;
有两种情况需要做下面的处理:通过堆栈传递参
数和分配的空间超过128K,那么就需要使用A15
作为帧指针。
把A15的值压入堆栈保存--->把B15(SP)的值赋给
A15作为新的帧指针--->调整SP的值来分配足够
的空间;
2.如果该函数里面还调用了别的函数,那么寄存
器B3里的数据必须压栈保存;另外,如果函数体
中需要用到寄存器B3,那么也要做同样的处理;
在函数返回的时候再从堆栈中恢复B3的值;否则
函数不能正常返回,因为函数的返回地址就保存
在B3寄存器里面;
3.如果函数体要使用寄存器A10-A15,B10-B15的
话,那么这些寄存器中的值必须保存起来,否则
其中的值将遭受不可恢复性的破坏;
4.如果该函数有参数为结构体,从前面的说明我
们知道实际传给函数的是该结构体变量的指针,
我们需要分两种情况来处理:一种是该函数需要
修改该结构体的内容,那么我们就要在堆栈中为
该结构体分配一个空间,并把结构体的内容给复
制过来;如果该函数只引用该结构,而不修改该
结构体的内容,那么我们只需要通过传递进来的
结构体地址(也就是指针)来访问这个结构体中
的内容即可;
5.执行函数主体代码;
6.函数返回值问题:如果函数返回的是char、int、
pointer、float、short、enum型数据,那么返
回值放在A4中;如果函数返回的值是long、double
类型,那么返回值应该放在A5:A4中。
如果返回的是一个结构体,那么调用该函数的函
数为这个结构分配空间,并且把这个结构体变量
的地址放在A3中作为一个特殊的参数传递给该函
数,该函数在返回前把结构体的指拷贝到A3所指
向的那个结构体中去;其实有一个更好的表示方
法,就是给该函数添加一个结构体指针型参数,
然后把调用者中分配的结构体变量的地址传进去
即可。
7.恢复被保存的寄存器的值,A10-A15,B10-B15,
B3;8.如果A15被用作帧指针,那么A15的值被恢
复,然后通过调整B15(SP)的值回收被分配的
堆栈空间;
9.从函数中返回,返回地址存放在B3中;
关键词: 针对 语言编程 函数 写的 一个 参数 传递 寄存
共1条
1/1 1 跳转至页
回复
有奖活动 | |
---|---|
【有奖活动】分享技术经验,兑换京东卡 | |
话不多说,快进群! | |
请大声喊出:我要开发板! | |
【有奖活动】EEPW网站征稿正在进行时,欢迎踊跃投稿啦 | |
奖!发布技术笔记,技术评测贴换取您心仪的礼品 | |
打赏了!打赏了!打赏了! |
打赏帖 | |
---|---|
【笔记】生成报错synthdesignERROR被打赏50分 | |
【STM32H7S78-DK评测】LTDC+DMA2D驱动RGBLCD屏幕被打赏50分 | |
【STM32H7S78-DK评测】Coremark基准测试被打赏50分 | |
【STM32H7S78-DK评测】浮点数计算性能测试被打赏50分 | |
【STM32H7S78-DK评测】Execute in place(XIP)模式学习笔记被打赏50分 | |
每周了解几个硬件知识+buckboost电路(五)被打赏10分 | |
【换取逻辑分析仪】RA8 PMU 模块功能寄存器功能说明被打赏20分 | |
野火启明6M5适配SPI被打赏20分 | |
NUCLEO-U083RC学习历程2-串口输出测试被打赏20分 | |
【笔记】STM32CUBEIDE的Noruletomaketarget编译问题被打赏50分 |