第五章 C/C++及汇编语言的混合编程 5.1 ARM C/C++编译器 5.2 在C/C++程序中内嵌汇编指令

Slides:



Advertisements
Similar presentations
C++语言程序设计教程 第5章 构造数据类型 第6章 C++程序的结构.
Advertisements

现代电子技术实验 ——综合实验之单片机部分
ARM 编程技巧.
C语言程序设计 主讲教师 :张群燕 电话:
親愛的老師您好 感謝您選用本書作為授課教材,博碩文化準備本書精選簡報檔,特別摘錄重點提供給您授課專用。 說明: 博碩文化:
第一章 C语言概述 计算机公共教学部.
微机原理与接口技术 第二章 ARM微处理器硬件结构
C语言程序设计 第八章 函数.
第5章 函数与预处理 《 C语言程序设计》 (Visual C++ 6.0环境) 本章导读
主讲教师:吴琼 微信群:C语言2016 QQ群: 密码scu2016 昵称:“真名+学号”
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
College of Computer Science & Technology
第四章 BootLoader开发 附-s3c2410/s3c2440中断控制器介绍
程序设计专题一 结构化程序设计与递归函数 主讲教师: 刘新国.
第4章 汇编语言程序设计 汇编语言源程序格式 汇编语言上机过程 汇编语言与C语言混合编程技术.
第7章 编译预处理 本章要求: 本章重点: 本章难点: 掌握用#define定义无参数宏和带有参数宏定义和调用方法;
6 使用者函數 6.1 函數定義 宣告函數 呼叫函數 呼叫多個函數 6-6
C语言 程序设计基础与试验 刘新国、2012年秋.
期中考试成绩分布 《程序设计》-2017年秋.
嵌入式系统教案 武汉创维特信息技术有限公司 2019/1/18.
(第2版).
切換Dev c++顯示語言 工具->環境選項(V)->介面->language (Chinese TW)
2.1 C语言的数据类型 2.2 常量与变量 2.3 变量赋初值 2.4 各类数值型数据间的混合运算 2.5 C语言的运算符和表达式
第5章 目录 1.简介 2.引脚配置 3.存储器寻址 4.系统控制模块 5.存储器加速模块 6.外部存储器控制器 7.引脚连接模块
(第2版).
授课老师:龚涛 信息科学与技术学院 2016年3月 教材:《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
第九章 预处理命令.
第六次全国人口普查 近期数据处理工作部署 夏雨春 2010年12月28日.
第1章 概述 本章要点: C语言程序结构和特点 C语言程序的基本符号与关键字 C语言程序的编辑及运行 学习方法建议:
Holtek C Compiler V3--advanced
第1讲 C语言基础 要求: (1) C程序的组成 (2) C语言的标识符是如何定义的。 (3) C语言有哪些基本数据类型?各种基本数
C语言大学实用教程 第5章 函数与程序结构 西南财经大学经济信息工程学院 刘家芬
ARM及Thumb指令集 (练习).
C语言复习3----指针.
第3章 ARM微處理器的指令集.
第 二 章 数据类型、运算符与表达式.
ARM Developer Suite 介 绍.
单片机原理与应用 主讲人:张荣刚 福建师范大学福清分校.
C语言复习2----函数.
第一章 程序设计和C语言 主讲人:高晓娟 计算机学院.
C语言程序示例: 1.输入10个数,按从小到大的顺序排序。 2.汉诺塔问题。.
Main() { Dfas Asdfasf fasdfa } #include <stdio.h> void main( ) {
ARM指令集 Author : Steve Furber Advisor: Mei-Ling Chiang Speaker: 徐翔宇
嵌入式系统教案 武汉创维特信息技术有限公司 2019/4/29.
Oop8 function函式.
7.1 C程序的结构 7.2 作用域和作用域规则 7.3 存储属性和生存期 7.4 变量的初始化
第十四章 若干深入问题和C独有的特性 作业: 函数指针 函数作参数 函数副作用 运算 语句 位段 存储类别 编译预处理
開放電腦計劃 報告人:陳鍾誠 2011 年 8 月 20 日 台灣開源人年會 COSCUP 2011 – 中研院
C程序设计.
C语言程序设计 李祥 QQ:
C++语言程序设计教程 第2章 数据类型与表达式 第2章 数据类型与表达式 制作人:杨进才 沈显君.
第2章 认识C语言 教学要点 2. 1 项目二C语言程序识读 2 .2 项目三班级成绩排名 2 .3 知识链接 返回.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第2章 数据类型、运算符与表达式 本章要点: 基本数据类型 常量和变量 算术运算符和算术表达式 关系运算符和关系表达式
第6章 预 处 理.
第二章 类型、对象、运算符和表达式.
单片机原理及应用 实践部分 主讲人:刘 强 四川工商学院单片机教学团队 单片机原理及应用 实践部分 主讲人:刘 强
第二章 基本数据类型 ——数据的表示.
ARM简介及BootLoader介绍 黄大荣
本节内容 函数嵌套调用的内存布局 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ: QQ交流群 : 联系电话:
挑戰C++程式語言 ──第9章 函數.
#include <iostream.h>
第二章ADS1.2开发环境创建与简介.
《数据结构与算法设计》第一部分 面向对象的C++程序设计基础.
单片机应用技术 (C语言版) 第4章 C51程序设计入门
第3章 目录 1.简介 2.ARM7TDMI 3.ARM7TDMI的模块和内部框图 4.体系结构直接支持的数据类型 5.处理器状态
基本資料型態 變數與常數 運算子 基本的資料處理 授課:ANT 日期:2014/03/03.
第三章 流程控制 程序的运行流程 选择结构语句 循环结构语句 主讲:李祥 时间:2015年10月.
嵌入式系统教案 武汉创维特信息技术有限公司 2019/10/1.
Presentation transcript:

第五章 C/C++及汇编语言的混合编程 5.1 ARM C/C++编译器 5.2 在C/C++程序中内嵌汇编指令

5.1 ARM C/C++编译器 ARM集成开发环境中包含的C/C++编译器。 编译器 名称 种类 源文件 类型 后缀 输出目标文件类型 tcc 32位Thumb代码 armcpp C++ C/C++ *.C/*.C++ tcpp

5.1 ARM C/C++编译器 ARM集成开发环境中C/C++语言的库包括: ARM C语言库: ARM C语言库包括标准的C语言函数集。 Rogue Wave C++库:包含标准C++函数及基本C++对象。 支持库: 支持库提供了对不同种类的体系及处理器的支持。

5.2 在C/C++程序中内嵌汇编指令 在C\C++程序中使用内嵌的汇编指令的语法格式: 在ARM C语言程序中,使用关键字__asm来标识一段汇 编指令程序。 __asm { 汇编语言程序 ~~~~~~~~ } 其中:如果一行中有多个汇编指令,指令之间使用分号(;)分开。 在一条指令占多行,要使用续行符号(\).

5.2 在C/C++程序中内嵌汇编指令 在C/C++程序中内嵌汇编指令注意事项: 必须小心使用物理寄存器,如R0~R3,IP,LR 和CPSR 中的N,Z,C,V 标志位.因为计算汇编代码中的C 表达式时,可能会使用这些物理寄存器,并会修改N,Z,C,V标志位。 __asm { MOV R0,x ADD y,R0,x/y //计算x/y 时R0 会被修改 } 在计算x/y 时R0 会被修改,从而影响R0+x/y 的结果.用一个C 程序的变量代替 R0就可以解决这个问题: MOV var,x ADD y,var,x/y 内嵌汇编器探测到隐含的寄存器冲突就会报错.

5.2 在C/C++程序中内嵌汇编指令 在C/C++程序中内嵌汇编指令注意事项: 不要使用寄存器代替变量.尽管有时寄存器明显对应某个变量,但也不能直接使用寄存器代替变量. int bad_f(int x) //x 存放在R0 中 { __asm ADD R0,R0,#1 //发生寄存器冲突,实际上x 的值没有变化 } return(x); 尽管根据编译器的编译规则似乎可以确定R0 对应x,但这样的代码会使内嵌汇编器认为 发生了寄存器冲突.用其他寄存器代替R0 存放参数x,使得该函数将x 原封不动地返回. 这段代码的正确写法如下: int bad_f(intx) ADD x,x,#1 return(x)

5.3 从汇编程序中访问C程序变量 在C程序中声明的全局变量可以被汇编程序通过地址间接访问。具体 访问方法如下: 使用IMPORT伪指令声明这个全局变量 使用LDR指令读取该全局变量的内存地址,通常该全局变量的内存地址存放在程序的数据缓冲池中。 根据该数据类型,使用相应的LDR指令读取该全局变量的值;使用相 应的STR指令修改该全局变量的值 AREA globals,CODE,READONLY EXPORT asmsub IMPORT glovbvar;声明外部变量glovbvar asmsub LDR R1,=glovbvar;装载变量地址 LDR R0,[R1] ;读出数据 ADD R0,R0,#1;加1 操作 STR R0,[R1];保存变量值 MOV PC LR END

5.4 汇编程序、C程序及C++程序相互调用 在C++程序中使用C程序头文件 在C++程序中使用C程序的系统头文件 例:// C++ code //这是一个C++程序 #include <studio>//使用C程序的系统头文件 Int main() //时可以直接调用 { ~~~~~~~ Return 0; }

5.4 汇编程序、C程序及C++程序相互调用 在C++程序中使用C程序头文件 在C++程序中使用C程序的用户定义头文件 // C++ code //这是一个C++程序 Extern { //在C++程序中使用伪指令 extern “C”{} #include “my-cheader1.h” } Int main() { ~~~~~~ Return 0;

5.4 汇编程序、C程序及C++程序相互调用 C 程序调用汇编程序: 汇编程序的设置要遵循ATPCS 规则,保证程序调用时参数的正确传递。 在汇编程序中使用EXPORT 伪指令声明本子程序,使其它程序可以调用此子程序。 在C 语言程序中使用extern 关键字声明外部函数(声明要调用的汇编子程序),即可调用此汇编子程序。

5.4 汇编程序、C程序及C++程序相互调用 C程序调用汇编程序 调用汇编的C 函数: #include <stdio.h> extern void strcopy(char *d,const char *s) //声明外部函数,即要调用的汇编子程 //序 int main(void) { const char *srcstr=“First string-source”; //定义字符串常量 char dstsrt[] =“Second string-destination”;//定义字符串变量 printf(“Before copying:\n”); printf(“’%s’\n ‘%s\n,”srcstr,dststr); //显示源字符串和目标字符串的内容 strcopy(dststr,srcstr); //调用汇编子程序,R0=dststr,R1=srcstr printf(“After copying:\n”) printf(“’%s’\n ‘%s\n,”srcstr,dststr); //显示strcopy 复制字符串结果 return(0); }

5.4 汇编程序、C程序及C++程序相互调用 C程序调用汇编程序 被调用汇编子程序: AREA SCopy,CODE,READONLY EXPORT strcopy ;声明汇编程序strcopy,以便外部程序引 ;用 strcopy ;R0 为目标字符串的地址 ;R1 为源字符串的地址 ; LDRB R2,[R1],#1 ;读取字节数据,源地址加1 STRB R2,[R0],#1 ;保存读取的1 字节数据,目标地址加1 CMP r2,#0 ;判断字符串是否复制完毕 BNE strcopy ;没有复制完毕,继续循环 MOV pc,lr ;返回 END

5.4 汇编程序、C程序及C++程序相互调用 汇编程序调用C程序 汇编程序的设置要遵循ATPCS 规则,保证程序调用时参数的正确传递. 在汇编程序中使用IMPORT 伪指令声明将要调用的C 程序函数. 在调用C 程序时,要正确设置入口参数,然后使用BL 调用.

5.4 汇编程序、C程序及C++程序相互调用 汇编程序调用C程序 汇编调用C 程序的C 函数: /*函数sum5()返回5 个整数的和*/ int sum5(int a,lit b, int c,int d,int e) { return(a+b+c+d+e); //返回5 个变量的和 }

5.4 汇编程序、C程序及C++程序相互调用 汇编程序调用C程序 汇编调用C 程序的汇编程序 AREA sample, CODE,READONLY IMPORT sum5 ;声明外部标号sum5,即C 函数sum5() CALLSUM STMFD SP! {LR} ;LR 寄存器放栈 ADD R1,R0,R0 ;设置sum5 函数入口参数,R0 为参数a ADD R2,R1,R0 ;R1 为参数b,R2 为参数c ADD R3,R1,R2, STR R3,[SP,# -4]! ;参数e 要通过堆栈传递 ADD R3,R1,R1 ;R3 为参数d BL sum5 ;调用sum5(),结果保存在R0 ADD SP,SP#4 ;修正SP 指针 LDMFD SP,PC ;子程序返回 END

5.5 嵌入式C编程 概述: C语言的优点是运行速度快、编译效率高、移植性好和可读性强。因此在嵌入式程序设计中经常会用到C语言程序设计。 嵌入式C语言程序设计是利用基本的C语言知识,面向嵌入式工程实际应用进行程序设计。也就是说它首先是C语言程序设计,因此必须符合C语言基本语法,只是它是面向嵌入式的应用而设计的程序。

5.5 嵌入式C编程 C语言的“预处理伪指令”在嵌入式程序设计中的应用。 1、文件包含伪指令 格式: #include <头文件名.h> ;标准头文件 #include “头文件名.h” ;自定义头文件 2、宏定义伪指令 其格式如下: # define 宏标识符 宏体 例: #define U32 unsigned int #define U16 unsigned short #define S32 int #define S16 short int #define U8 unsigned char #define S8 char

5.5 嵌入式C编程 C语言的“预处理伪指令”在嵌入式程序设计中的应用。 3、条件宏:先测试是否定义过某宏标识符,然后决定如何处理。这样做是为了避免重复定义。 格式: #ifdef 宏标识符 #undef 宏标识符 #define 宏标识符 宏体 #else #endif 例: #ifdef INCLUDE_SERIAL #undef NUM_TTY #define NUM_TTY N_UART_CHANNELS #undef CONSOLE_TTY #define CONSOLE_TTY 0 #undef CONSOLE_BAUD_RATE #define CONSOLE_BAUD_RATE 115200

5.5 嵌入式C编程 C语言的“预处理伪指令”在嵌入式程序设计中的应用 4、条件编译伪指令 格式 #if(条件表达式1) … #elif(条件表达式2) #elif(条件表达式n) #else #endif 这样,编译时,编译器仅对#if()…#endif之间满足某一条件表达式 的源文件部分进行编译。

5.5 嵌入式C编程 使用寄存器变量 当对一个变量频繁被读写时,需要反复访问内存,从而花费大量的存取时 间。为此,C语言提供了一种变量,即寄存器变量。这种变量存放在CPU的寄存 器中,使用时,不需要访问内存,而直接从寄存器中读写,从而提高效率。寄存 器变量的说明符是register。对于循环次数较多的循环控制变量及循环体内反复 使用的变量均可定义为寄存器变量,而循环计数是应用寄存器变量的最好候选者。 例: /* 求1+2+3+….+n的值 */ WORD Addition(BYTE n) {  register i,s=0; for(i=1;i<=n;i++)  {   s=s+i;  }  return s; }

5.5 嵌入式C编程 活用位操作 使用C语言的位操作可以减少除法和取模的运算。在计算机程序中数 据的位是可以操作的最小数据单位,理论上可以用“位运算”来完成所有的 运算和操作,因而,灵活的位操作可以有效地提高程序运行的效率 。 例: /* 方法1 */ int i,j; i = 879 / 16; j = 562 % 32; /* 方法2 */ int i,j; i = 879 >> 4; j = 562 - (562 >> 5 << 5);

5.5 嵌入式C编程 活用位操作 C语言位运算除了可以提高运算效率外,在嵌入式系统 的编程中,它的另一个最典型的应用,而且十分广泛地正在 活用位操作   C语言位运算除了可以提高运算效率外,在嵌入式系统 的编程中,它的另一个最典型的应用,而且十分广泛地正在 被使用着的是位间的(&)、(|)、非(~)操作,这跟嵌 入式系统的编程特点有很大关系。 例: rGPCDAT=(rGPCDAT&0xFFFFFFF0)|0x0E rINTMSK&=~(BIT_TIMER1)

5.5 嵌入式C编程 数据指针 在嵌入式系统的编程中,常常要求在特定的内存单元读写内容,汇编有对应 的MOV指令,而除C/C++以外的其它编程语言基本没有直接访问绝对地址的能 力。在嵌入式系统的实际调试中,多借助C语言指针所具有的对绝对地址单元内 容的读写能力。以指针直接操作内存多发生在如下几种情况: 某I/O芯片被定位在CPU的存储空间而非I/O空间,而且寄存器对应于 某特定地址; 两个CPU之间以双端口RAM通信,CPU需要在双端口RAM的特定单 元(称为mail box)书写内容以在对方CPU产生中断; 读取在ROM或FLASH的特定单元所烧录的汉字和英文字模。 例: int *p = (int *)0xF000FF00 ; *p=0xABCD; #define rGPACON (*(volatile unsigned *)0x56000000); rGPACON=0x1234;

5.5 嵌入式C编程 关键字volatile 一般这个修饰符用来告知编译器,被修饰的变量是个“易 都不会被优化。 用法 1、中断服务程序中修改的供其它程序检测的变量需要加volatile。 2、多任务环境下各任务间共享的标志应该加volatile。 3、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义。