第6章 C语言程序设计与混合编程

更新时间:2023-05-13 17:05:01 阅读量: 实用文档 文档下载

说明:文章内容仅供预览,部分内容可能不全。下载后的文档,内容与下面显示的完全一致。下载之前请确认下面内容是否您想要的,是否完整无缺。

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程

第6章 C语言程序设计与混合编程6.1 C语言程序设计6.2 用C语言和汇编语言混合编程 本章小结 习 题

2013年8月6日3时59分

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 C54x DSP软件设计的方法通常有三种: (1) 用汇编语言开发。此方式代码效率高,程序执行速度快, 可读性较差,可移植性较差,软件的修改和升级困难。 (2) 用C语言开发。CCS平台包括优化ANSI C编译器,从而可

可以充分合理地利用芯片提供的硬件资源。但程序编写比较烦琐,

以在C源程序级进行开发调试,增强软件的可读性,提高了软件的开发速度,方便软件的修改和移植。然而,C编译器无法实现 在任何情况下都能够合理地利用DSP芯片的各种资源。 (3) C语言和汇编语言混合编程开发。采用混合编程的方法 能更好地达到设计要求,完成设计任务。2013年8月6日3时59分 2

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程

6.1 C语言程序设计 6.1.1 C语言特点及语法1. C语言特点 C语言是国际上广泛流行的、很有发展前途的计算机高级语 言。它适合于作为系统描述语言,既可以用来编写系统软件, 也可以用来编写应用软件。 汇编语言依赖于计算机硬件,程序的可读性和可移植性比 较差。而高级语言具有很好的可移植性,但是难以实现汇编语 言的某些功能。因为C语言仍然需要通过编译、连接才能得到可 执行目标程序,所以是一种高级语言。但C语言允许访问物理地 址,能进行位操作,能实现汇编语言的大部分功能,能直接对 硬件进行操作。C语言正是一种既可以访问物理地址又可以进行 位操作的高级语言,这也是其与别的高级语言不同的地方。2013年8月6日3时59分 3

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 C语言具有如下基本特点: (1) 语言简洁、紧凑,使用方便、灵活。 (2) 运算符丰富,表达式类型多样化。 (3) 数据结构类型丰富,具有现代化语言的各种数据结构。

(4) 具有结构化的控制语句。(5) 语法限制不太严格,程序设计自由度大。 (6) C语言允许访问物理地址,能进行位操作,能实现汇编 语言的大部分功能,能直接对硬件进行操作。

2013年8月6日3时59分

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 2. C语言基本语法概述(1) 限定词 可由字母、数字和下划线组成。限定词必须以字母或下划线开头。区分 大小写。 (2) 常量 常量包括整型常量(八进制、十进制、十六进制、长整型),字符常量, 实型常量(小数形式、指数形式),字符串常量,表达式,算术表达式(整型表 达式、实型表达式),逻辑表达式,字位表达式,强制类型转换表达式,逗号 表达式(顺序表达式),赋值表达式,条件表达式,

指针表达式。 (3) 数据定义 数据类型(int、short、long、unsigned、char、float、double、struct、 union、enum)用ty-pedef定义的类型名,存储类型(auto、static、register、 extem)变量的定义形式为: 存储类别 数据类型 变量列表; 例如:static float a,b,c;2013年8月6日3时59分 5

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程

(4) 函数定义函数的定义形式为: 存储类别 函数体 (5) 语句 数据类型 函数名(形参表别)

语句包括表达式语句、函数调用语句、控制语句、复合语 句、空语句。其中控制语句包括if语句、while语句、for语句 和switch语句以及break语句、continue语句、return语句、 goto语句。(6) 预处理命令 预处理命令主要是指define和include语句。2013年8月6日3时59分 6

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 6.1.2 系统堆栈的使用 C系统的堆栈可以完成的主要功能如下: * 分配局部变量; * 传递函数参数; * 保存所调用函数的返回地址; * 保存临时结果。 运行堆栈的增长方向是从高地址到低地址, 即入栈则地址 减少,出栈则地址增加。堆栈的管理者是堆栈指针SP。堆栈的 容量由链接器(Linker)设定。 如:在链接命令文件(.cmd文件)中加入选项

-stack 0x1000则堆栈的容量被设为1000H个字。2013年8月6日3时59分 7

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 6.1.3 存储器模式及分配 1. 存储器模式 C54x DSP定点处理器有两种类型的存储器模式:程序存储器 和数据存储器。前者主要用于装载可执行代码,后者主要用于装 载外部变量、静态变量、系统堆栈以及一些中间运算结果。 C54x DSP的程序代码或数据以段的形式装载于存储器中。C 语言程序经C编译器编译后,生成七个可重定位的段,其中四个被 称为已初始化段,三个被称为未初始化段。 四个已初始化段分别是: * .text段 包括可执行代码、字符串和编译器产生的常量。 * .cinit段 包括初始化变量和常量表。 * .const段 包括字符串常量和以const关键字定义的常量。 * .switch段 为.const语句建立的表格。2013年8月6日3时59分 8

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 三个未初始化段分别是: * .bss段 保留全局和静态变量空间。在程序开始运行时,C的 引导(boot)程序将数据从.cinit段拷贝到.bss段。 * .stack段 为C的系统堆栈分配存储空间,用于变量的传递。 * .sysmem段 为动态存储器函数malloc、calloc、realloc分配存 储器空间。若C程序未用到此类函数,则C编译器不产生该段。

在编写链接命令文件(.cmd文件)时, .text、.cinit、.switch段通 常可以链接到系统的ROM或者RAM中去,但是必须放在程序段 (page0);.const段通常可以链接到系统的ROM或者RAM中去, 但是必须放在数据段(pagel);而.bss、.stack和.sysmem段必

须链 接到系统的RAM中去,并且必须放在数据段(pagel)。由实验程 序所建的某工程的链接命令文件(.cmd文件),如例6.1所示。2013年8月6日3时59分 9

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程

【例6.1】某工程的链接命令文件(.cmd文件)MEMORY { PAGE 0 : HPIRAM: origin = 0x100, length = 0x200 /* TMS320C54x DSP存储器分配 */

PROG:PAGE 1 : DARAM1:

origin = 0x2000,

length = 0x1000

origin = 0x03000, length = 0x1000

PAGE 2 :FLASHRAM: origin = 0x8000, length = 0x7fff }2013年8月6日3时59分 10

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程SECTIONS { /* 由C 定义 */ .vectors : load = PROG page 0 /*中断向量表*/ .text : load = PROG page 0 /*可执行代码*/ .cinit : load = PROG page 0 /*初始化变量和常数表*/ .switch : load = PROG page 0 /*为.constant语句建立的表格*/ .stack : load = DARAM1 page 1 /*C 系统堆栈*/ .const : load = DARAM1 page 1 /*字符串常量和以const关键字定义的常量*/ .bss : load = DARAM1 page 1 /*全局和静态变量空间*/ .dbuffer1024 : {} > DARAM1 page 1, align (1024) .coeffs1024 : {} > DARAM1 page 1, align (1024) .hpibuffer : load = HPIRAM page 0 /*由汇编定义*/ .data : >DARAM1 page 1 /*汇编定义的数据段*/ }2013年8月6日3时59分 11

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 2.存储器分配 C编译器提供的运行支持函数中包含有几个允许在运行时为变 量分配存储器的函数,如malloc、calloc和recalloc。动态分配不是C 语言本身的标准,而是由运行支持函数所提供的。 为全局pool和heap分配的存储器空间定义在.sysmem块 中。.sysmem段的大小可由链接器选项中的-heap项来设定,其方法 是在-heap项后加一个常数。与堆栈类似,连接器也创建一个全局符 号_SYSMEM_SIZE。.sysmem段的大小由_SYSMEM_SIZE的数值来 确定,默认值为l K字。为了在.bss段中保留空间,对于大的数据, 可以用heap为其分配空间,而不将它们说明为全局或静态的。例如,对于原定义的: struct big table[1000] 可以改用指针并调用malloc函数来定义: struct big *table table=(struct big*)malloc(1000*sizeof(struct big));2013年8月6日3时59分 12

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 (1) 静态和全局变量的存储器分配 在C程序中,静态变量被分配一个惟一的连续空间,该空间的 地址由链接器决定。编译器安排这些变量的空间被分配在若干个字 的长度中,以保证每个变量按字边界对准。全局变量分配到数据空

间,在同一模块中定义的变量分配到同一个连续的存储空间。(2) 域/结构的对准 C编译器在为结构分配存储空间时,它分配足够的字以包含所 有的结构成员。一组结构中,每个结构开始于字边界。所有的非域 类型对准于字的边界。对域应分配足够多的比特。相邻域应装入一 个字的相邻比特,不能跨越两个字

,否则整个域会被分配到下一个 字中。2013年8月6日3时59分 13

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 6.1.4 TMS320C54x DSP的C语言规则 1.寄存器规则 在C环境中,定义了严格的寄存器规则。寄存器规则明确

了编译器如何使用寄存器,以及在函数的调用过程中如何保护寄存器。调用函数时,某些寄存器不必由调用者来保护,而由 被调用函数负责保护。如果调用者需要使用没有保护的寄存器, 则调用者在调用函数前必须对这些寄存器予以保护。在编写汇 编语言和C语言的接口程序时,这些规则非常重要。如果编写

时不遵守寄存器的使用规则,则C环境将会被破坏。2013年8月6日3时59分 14

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 寄存器规则概括如下: (1) 辅助寄存器 ARl、AR6、AR7由被调用函数保护,即可

以在函数执行过程中修改,但在函数返回时必须恢复。在C54xDSP中,编译器将ARl和AR6用作寄存器变量。其中,AR1被用 作第一个寄存器变量,AR6被用作第二个寄存器变量,其顺序 不能改变。另外五个辅助寄存器AR0、AR2、AR3、AR4、 AR5则可以自由使用,即在函数执行过程中可以对它们进行修 改,不必恢复。 (2) 栈指针SP 堆栈指针SP在函数调用时必须予以保护,但 这种保护是自动的,即在返回时,压入堆栈的内容都将被弹出。2013年8月6日3时59分 15

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 (3) ARP 在函数进入和返回时,必须为0,即当前辅助寄 存器必须为AR0,而函数执行时则可以是其他值。

(4) OVM 在默认情况下,编译器总认为OVM是0。因此,若在汇编程序中将OVM置为1,则在返回C环境时,必须将其

恢复为0。(5) 其他状态位和寄存器可以任意使用,不必恢复。

2013年8月6日3时59分

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程

2.函数调用规则(1) 参数传递 在函数调用前,将参数以逆序压入运行堆栈。 所谓逆序,即最右边的参数最先压入栈,然后自右向左将参数 依次压入栈,直至第二个参数入栈完毕。对第一个参数,则不 需压入堆栈,而是放入累加器A中,由A进行传递。若参数是长 整型和浮点数时,则低位字先压入栈,高位字后压入栈。若参 数中有结构,则调用函数先给结构分配空间,而该空间的地址 则通过累加器A传递给被调用函数。

一个典型的函数调用图如图6.1所示。在该例中,我们可以 看出,参数传递到函数,同时该函数使用了局部变量并调用另 一个函数。第一个参数不由堆栈传递,而是放入累加器A中传 递。(如图6.1(b)、图6.1(c)所示)。2013年8月6日3时59分 17

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程另外,从这个例子中,我们看到了函数调用时局部帧的产生过程:函数

调用时,编

译器在运行堆栈中建立一个帧用以存储信息。当前函数帧成为局部帧,C环境利用局部帧来保护调用者的有关信息、传递参数和为局部变量分 配存储空间。每调用一个函数,就建立一个新的局部帧。局部帧空间的一部

分用于分配参数区(局部参数区),被传递的参数放入局部参数区,即压入堆栈,再传递到其他被调用的函数中。 (2) 被调用函数的执行过程 被调用函数依次执行以下几项任务: * 如果被调用函数修改了寄存器(如AR1、AR6、AR7),则必须将它们压 栈保护。 * 当被调用函数需分配内存来建立局部变量及参数区时,SP向低地址移 动一个常数(即SP减去一个常数),该常数的计算方法如下: 常数=局部变量长度+参数区中调用其他函数的参数长度2013年8月6日3时59分 18

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程调用前 低 低 传递函数 调用函数 低 SP 局部 参数区 局部帧 SP 返回地址 调用者 参数区 高 调用者 局部变量 SP 参数2… 参数n 高 调用者 局部变量 参数1 累加器A 高 返回地址 参数2… 参数n 调用者 局部变量 参数1 累加器A 传递函数 调用函数

(a)

(b)

(c)

图6.1 函数调用时堆栈的使用2013年8月6日3时59分 19

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程* 被调用函数执行程序。 * 如果被调用函数修改了寄存器ARl、AR6和AR7,则必须予以恢复。 将函数的返回值放入累加器A中。整数和指针在累加器A的低16位中返回, 浮点数和长整型数在累加器A的32位中返回。如果函数返回一个结构体,则 被调用函数将结构体的内容拷贝到累加器A所指向的存储器空间。如果函数 没有返回值,则将累加器A置0,撤销为局部帧开辟的存储空间。ARP在从函 数返回时,必须为0,即当前辅助寄存器为AR0。参数不是由被调用函数弹 出堆栈的,而是由调用函数弹出的。 * SP向高地址移动一个常数(即SP加上一个常数),该常数即为图6.1(b) 所确定的常数,这样就又恢复了帧和参数区。 * 被调用函数恢复所有保存的寄存器。 * 函数返回。 当C程序编译成汇编后, 上述过程如例6.2所示。2013年8月6日3时59分 20

C语言程序设计与混合编程

第6章 C语言程序设计与混合编程 【例6.2】 be_called: ;函数入口

pshm AR6pshn AR7 frame # -16

;保存AR6;保存AR7 ;分配帧和参数区

...frame #16 pshm AR7 pshm AR6 ret2013年8月6日3时59分

;函数主体;恢复原来的帧和参数区 ;恢复AR7 ;恢复AR6 ;函数返回21

本文来源:https://www.bwwdw.com/article/n5ge.html

Top