ARM实验5_嵌入式C与汇编混合编程

合集下载

五、c语言与汇编语言混合编程

五、c语言与汇编语言混合编程
9
2、 C程序调用汇编程序
第一步:建立汇编源文件Factorial.s
/* Factorial.s */ AREA Fctrl, CODE, READONLY EXPORT Factorial Factorial MOV R8 , R0 MOV R9 , #0 SUB R0,R8,#1 Loop MOV R1 , R9 UMULL R8 , R9 , R0 , R8 MLA R9 , R1 , R0 , R9 SUBS R0 , R0 , #1 BNE Loop LDR R0,=0xFFFFFFF0 STMIA R0,{R8,R9} MOV PC,LR MOV PC,LR ; 声明代码段 Fctrl

在ARM开发工具编译环境下设计程序,用ARM 汇编语言调用C语言实现20!的阶乘操作,并将 结果保存到寄存器R0中。
4ห้องสมุดไป่ตู้
1、汇编程序调用C程序
然后建立C语言源文件factorial.c
/* factorial.c */ long long Factorial(char N) { char i; long long Nx=1; for(i=1;i<=N;i++)Nx=Nx*i; return Nx; }
初始化过程
初始化存储器及 SDRAM 初始化堆栈
设置异常向量 初始化C语言运行环 境:设置参数 改变CPU运行模式为用 户模式(User Mode) 运行C程序
15
//内嵌汇编标识
13
本章提要
一 ARM微处理器体系结构 二 ARM 微处理器指令集 三 C语言与汇编语言的混合编程 四 ARM处理器初始化分析
14
应用示例-系统初始化
复位动作

嵌入式实验(汇编和C语言混合编程实验)

嵌入式实验(汇编和C语言混合编程实验)

嵌入式实验(汇编和C语言混合编程实验)汇编和C语言混合编程实验7.1实验目的①掌握C程序中内嵌指令的使用方法。

②理解汇编程序调用C程序函数和变量的方法。

7.2 实验环境①硬件:PC机②软件:ADS1.27.3 实验内容①使用内嵌汇编的方法设计允许和禁止中断程序。

②验证汇编程序调用C程序函数和访问C程序变量的执行过程。

7.4 实验过程1、实验7-1 允许和禁止中断程序本实验使用内嵌汇编的方法完成允许和禁止中断程序设计,这里使用Armulator 作为调试的目标机。

(1)新建ARM工程exp7_1启动ADS开发环境,选择File→New(Project)选项,使用ARM Executable Image工程模板创建一个工程exp5_1.(2) 新建汇编程序文件exp7_1_1.c,并将其添加到工程exp7_1中选择File→New(File)选项,新建汇编源程序文件exp7_1_1.c并添加到工程exp7_1中,exp7_1_1.c源程序的参考代码如下: #include__inline void enable_IRQ(void) {int tmp;__asm {MRS tmp, CPSRBIC tmp, tmp, #0x80 MSR CPSR_c, tmp } }__inline void disable_IRQ(void) {int tmp; __asm{MRS tmp, CPSR ORR tmp, tmp, #0x80 MSR CPSR_c, tmp } }int main(void) {enable_IRQ( ); disable_IRQ( ); return 0;}(3) 设置工程exp7_1的编译和链接选项选择Edit→DebugRel Settings选项,打开DebugRel Settings对话框,设置工程编译和链接选项,在Language Settings→ARM Assembler选项中,选择Target选项卡,修改处理器类型为ARM920T. (4) 编译和链接工程在工程exp7_1窗口中,选择Make工具按钮,编译和链接工程exp7_1,如果有错误提示,请检查修改程序中的语法错误,直到编译和链接通过。

arm学习笔记五(cc++与arm汇编混合编程)

arm学习笔记五(cc++与arm汇编混合编程)

arm学习笔记五(cc++与arm汇编混合编程)混合编程常见⽅式:1 在c/c++程序中嵌⼊汇编指令语法格式:__asm{汇编语⾔程序}2 在汇编程序中访问c/c++定义的全局变量⽰例代码如下:test.c#include <stdio.h>int gVar_1=12;extern asmDouble(void)int main(void){printf("original value of gVar_1 is %d",gVar_1);admDouble();printf("modified value of gVar_1 is %d",gVar_1);return 0;}test.sAREA asmfile,CODE,READONLYEXPORT asmDouble;声明全局引⽤标号IMPORT gVar_1;引⽤asmDoubleldr r0,=gVar_1ldr r1,[r0]mov r2,#2mul r3,r1,r2str r3,[r0]mov pc,lrEND3 在c/c++程序中调⽤汇编函数⽰例代码如下:test1.sAREA asmfile,COCE,READONLYEXPORT asm_strcpy;声明全局引⽤标号asm_strcpy;函数名loop:ldrb r4,[r0],#1cmp r4,#0beq overstrb r4,[r1],#1b loopover:mov pc,lr;⽤于函数返回ENDtest1.c#include <stdio.h>extern void asm_strcpy(const char *src,char *dest);int main(){const char *s ="hello world";char d[32];asm_strcpy(s,d);printf("source:%s",s);printf("destination: %s",d);return 0;}上⾯程序jni的味道有⽊有?4 汇编程序中调⽤c/c++函数⽰例代码如下:test2.cint cFun(int a,int b,int c){return a+b+c;}test2.sEXPORT asmfileAREA asmfile,CODE,READONLY IMPORT cFun;引⽤函数ENTRY;指定应⽤程序⼊⼝mov r0,#11mov r1,#22mov r2,#33BL cFun;返回END。

ARM汇编语言与C_C_语言混合编程实现方法_王茹

ARM汇编语言与C_C_语言混合编程实现方法_王茹

ARM汇编语言与C_C_语言混合编程实现方法_王茹一、ARM汇编语言与C语言编译器在ARM汇编语言与C语言混合编程中,我们需要用到ARM汇编语言编写的程序和C语言编写的程序。

然而,C语言编译器无法直接编译ARM汇编语言,所以我们需要一个汇编编译器将汇编语言转换为机器码。

ARM汇编语言的编译器有很多种,其中常用的有GNU汇编器(gas)和ARM汇编器(armasm)。

GNU汇编器是GNU工具链中的一部分,可以将汇编语言转换为机器码。

ARM汇编器是ARM公司提供的一款汇编编译器,也可以将汇编语言转换为机器码。

我们可以通过在终端中输入命令来使用GNU汇编器将汇编语言编译为机器码,如下所示:```gcc -c assembly.s -o assembly.o```其中,`gcc`是GCC编译器的命令,`-c`参数表示只编译不连接,`assembly.s`是要编译的汇编文件,`-o`参数指定编译输出的目标文件为`assembly.o`。

二、ARM汇编语言与C语言的接口在ARM汇编语言与C语言混合编程中,我们通常需要在汇编语言和C 语言之间传递数据。

为了能够在汇编语言中访问C语言变量,我们需要定义一个接口。

在C语言中,我们可以使用`extern`关键字声明一个C语言变量,以供汇编语言调用。

例如,我们可以在C语言程序中定义一个全局变量`int var`,并使用`extern`关键字声明这个变量,如下所示:```cint var;extern int asm_function(; // 声明汇编语言函数```在汇编语言中,我们可以通过`IMPORT`伪指令引入C语言变量,以供汇编语言使用。

例如,我们可以在汇编语言程序中使用`IMPORT`伪指令引入C语言变量`var`,如下所示:```assemblyIMPORT var```在汇编语言中,我们可以通过`EXPORT`伪指令将汇编语言函数暴露给C语言使用。

例如,我们可以在汇编语言程序中使用`EXPORT`伪指令将汇编语言函数`asm_function`暴露给C语言使用,如下所示:```assemblyEXPORT asm_function```三、ARM汇编语言与C语言的调用汇编语言函数,或者在汇编语言中调用C语言函数。

ARM汇编与C混合编程

ARM汇编与C混合编程

ARM汇编与C混合编程内联汇编即在C中直接使用汇编语句进行编程,使程序可以在C程序中实现C语言不能完成的一些工作,例如,在下面几种情况中必须使用内联汇编或嵌入型汇编程序中使用饱和算术运算(Saturating ArithmeTIc)程序需要对协处理器进行操作在C程序中完成对程序状态寄存器的操作__asm__ __volaTIle__("asm code":output:input:changed registers);Note:使用__asm__和__volaTIle__表示编译器将不检查后面的内容,而是直接交给汇编器。

如果希望变压器你优化,__volaTIle__可以不加没有asm code也不能省略""没有前面的和中间的部分,不可以相应的省略:没有changed 部分,必须相应的省略:最后的;不能省略,对于C语言来说这是一条语句汇编代码必须放在一个字符串内,且字符串中间不能直接按回车换行,可以写成多个字符串,注意中间不能有任何符号,这样就会将两个字符串合并为一个指令之间必须要换行,还可以使用\t使指令在汇编中保持整齐asm code"mov r0, r0\n\t""mov r1,r1\n\t""mov r2,r2"output(asm->C):"constraint" (variable)"constraint"用于定义variable的存放位置:r表示使用任何可用的寄存器m表示使用变量的内存地址+可读可写=只写">input(C->asm):"constraint" (variable/immediate)"constraint"用于定义variable的存放位置:r表示使用任何可用的寄存器(立即数和变量都可以)m表示使用变量的内存地址i表示使用立即数。

关于在ARM中(MDK下)C与汇编混合编程的问题

关于在ARM中(MDK下)C与汇编混合编程的问题
{
loopLDRBr2,[r0],#1//R0保存第一个参数
STRBr2,[r1],#1//R1保存第二个参数
CMPr2,#0
BNEloop
BLXlr//返回指令须要手动加入
}
intmain(void)
{
constchar*a=“Helloworld!”;
charb[20];
my_strcpy(a,b);
关于在ARM中(MDK下)C与汇编混合编程的问题
于:bbs.21ic/icview-156494-1-1.html([微控制器/MCU]小窍门:Cortex-M3
在MDK C语言中嵌入汇编语言的方法)
==================================
==========================
如果须要访问C程式中的变量,可以使用_cpp关键字,编译器如LDRr0,=__cpp(&some_variable)
LDRr1,=__cpp(some_function)
BL__cpp(some_function)
MOVr0,#__cpp(some_constant_expr)
**********************************
***************************
在传统的ARM处理器中(ARM7/ARM9),如果要在C程式中嵌入汇编,可以有
两种方法:
一、内联汇编的方式方法如下:intPCBsheji(inti)
{
intr0;
__asm
{
ADDr0,i,1
EORi,r0,i
}
returni;
}
在汇编语句可以直接做用C语言中的变量.编译器会对这些代码进一步优化,

ARM汇编语言与嵌入式C混合编程

ARM汇编语言与嵌入式C混合编程

TM
13
8.2.2按位或操作
按位或操作运算符“|”是把参与运算的两个 操作数对应的各个二进制位进行按位相或。 对应的两个二进制位中只要有一个为1,结果 就为1,当两个对应的二进制位都为0时,结 果位为0。参与运算的两个操作数均以补码形 式出现。
TM
14
14
例如7 | 3,7的补码为0000 0111,3的补码 为0000 0011,结果为0000 0111。按位与操 作可以实现将特定位的置位操作,也可以用 于提取出某数的指定位。
{
...
// 程序代码 B
TM
5
5
8.1.2 命名规则
(1)标识符的名称要简明,能够表达出确切的含义 ,可以使用完整的单词或通常可以理解的缩写。
(2)如果在命名中使用特殊约定或缩写,则要进 行注释说明。
(3)对于变量命名,一般不取单个字符 ,例如i、j 、k...
(4)函数名一般以大写字母开头;所有常量名字 母统一用大写。
优秀的代码还要具备易读性、易维护性、具 有可移植和高可靠性。
TM
3
3
8.1.1 嵌入式C程序书写规范
排版规则如下: (1)程序块要采用缩进风格编写 (2)较长的语句(例如超过80个字符)要分成多行书写 (3)循环、判断等语句中若有较长的表达式或语句,则要
进行适应的划分 (4)若函数或过程中参数较长,也要进行适当的划分。 (5)每行一般只写一条语句 (6)程序块的分界符语句的大括号“{”与“}”一般独占一
TM
6
6
8.1.3 注释说明
注释有助于程序员理解程序的整体结构,也便于以 后程序代码的维护与升级。常用的规则如下:
(1)注释语言必须准确、简洁且容易理解; (2)程序代码源文件头部应进行注释说明 ; (3)函数头部应进行注释; (4)程序中所用到的特定含义的常量、变量,在

基于ARM的C语言与汇编语言混合编程

基于ARM的C语言与汇编语言混合编程

基于ARM的C语言与汇编语言混合编程2009-07-30 19:12:34| 分类:ARM学习| 标签:|字号大中小订阅1、C语言与汇编语言混合编程应遵守的规则ARM编程中使用的C语言是标准C语言,ARM的开发环境实际上就是嵌入了一个C语言的集成开发环境,只不过这个开发环境与ARM的硬件紧密相关。

在使用C语言时,要用到和汇编语言的混合编程。

若汇编代码较为简洁,则可使用直接内嵌汇编的方法;否则要将汇编程序以文件的形式加入到项目中,按照ATPCS(ARM/Thumb过程调用标准,ARM/Thumb Procedure Call Standard)的规定与C程序相互调用与访问。

在C程序和ARM汇编程序之间相互调用时必须遵守ATPCS规则。

ATPCS规定了一些子程序间调用的基本规则,哪寄存器的使用规则,堆栈的使用规则和参数的传递规则等。

1)寄存器的使用规则子程序之间通过寄存器r0~r3来传递参数,当参数个数多于4个时,使用堆栈来传递参数。

此时r0~r3可记作A1~A4。

在子程序中,使用寄存器r4~r11保存局部变量。

因此当进行子程序调用时要注意对这些寄存器的保存和恢复。

此时r4~r11可记作V1~V8。

寄存器r12用于保存堆栈指针SP,当子程序返回时使用该寄存器出栈,记作IP。

寄存器r13用作堆栈指针,记作SP。

寄存器r14称为链接寄存器,记作LR。

该寄存器用于保存子程序的返回地址。

寄存器r15称为程序计数器,记作PC。

2)堆栈的使用规则ATPCS规定堆栈采用满递减类型(FD,Full Descending),即堆栈通过减小存储器地址而向下增长,堆栈指针指向内含有效数据项的最低地址。

3)参数的传递规则整数参数的前4个使用r0~r3传递,其他参数使用堆栈传递;浮点参数使用编号最小且能够满足需要的一组连续的FP寄存器传递参数。

子程序的返回结果为一个32位整数时,通过r0返回;返回结果为一个64位整数时,通过r0和r1返回;依此类推。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

昆明理工大学信息工程与自动化学院学生实验报告(2011 —2012 学年第 1 学期)课程名称:ARM嵌入式系统结构开课实验室:信自楼443 2012 年12月27日一、实验目的●掌握建立基本完整的ARM工程,包含启动代码,连接脚本等;●阅读Embest S3CEV40启动代码,观察处理器启动过程;●学会使用Embest IDE 辅助信息窗口来分析判断调试过程和结果;●学会在Embest IDE环境中编写、编译与调试汇编和C语言相互调用的程序。

●掌握通过memory/register/watch/variable窗口分析判断结果。

二、实验原理1. ARM异常向量表当正常的程序执行流程挂起时,称之为异常。

在处理异常之前,必须保存当前的处理器状态,以便从异常程序返回时可以继续执行当前的程序。

ARM异常向量表如表2-2所示。

由上可见,复位(Reset)入口是整个程序的实际入口点。

因此,编写代码时,第一条语句在0x00000000处开始执行。

2. ARM过程调用ATPCS(ARM)ATPCS是一系列用于规定应用程序之间相互调用的基本规则。

程序只要遵守ATPCS相应规则,就可以使用不同的源代码来编写程序。

程序间的相互调用最主要的是解决参数传递问题。

应用程序之间使用中间寄存器及数据栈来传递参数,其中第1~4个参数使用R0~R3,多于4个参数的则使用数据栈进行传递。

用不同语言编写的应用程序在调用时可以自定义参数传递的约定。

使用具有一定意义的形式来传递,可以很好地解决参数个数问题。

常用方法是把第1个或最后1个参数(包括个数本身)传递给应用程序。

ATPCS中寄存器的对应关系如表2-3所列。

表2-3 ATPCS规则中寄存器列表3. 链接脚本文件所有的链接都是通过链接脚本来控制实现的。

这些链接脚本文件使用链接命令语言编写。

链接脚本的最主要作用是描述我们编写的文件中这么多个部分应该如何的相应摆放在输出文件中,并控制存储区如何定位这些输出文件。

同时,如果需要,我们还可以使用链接脚本文件实现其它功能。

大部分链接脚本文件都是很简单的。

最简单的链接脚本只有一行命令:SECTIONS。

使用SECTIONS命令来告诉存储区应该如何摆放输出文件。

4.Embest IDE开发调试辅助窗口使用Embest IDE嵌入式开发环境,用户可以使用源代码编辑窗口编写源文件程序。

使用反汇编窗口观察程序代码的执行,使用Register窗口观察程序操作及CPU状态,使用外围寄存器窗口观察当前处理器的设置,使用Memory窗口观察内存单元使用情况,使用Watch 或Variables窗口观察程序变量,使用操作控制台执行特殊命令。

加上调试状态下丰富的右键快捷菜单功能,用户可以使用IDE实现或发现任何一部分应用软件,修改任何一个开发或运行时的错误。

三、实验内容1. 使用汇编完成一个随机数产生函数,通过C语言调用该函数,产生一系列随机数,存放到数组里面。

2. 下面是ARM的启动文件init.s及链接脚本文件ldscript的参考程序:参考程序init.s:#.arm.global _start.text_start:# 设置中断/异常向量B Reset_HandlerUndefined_Handler: B Undefined_HandlerSWI_Handler: B SWI_HandlerPrefetch_Handler: B Prefetch_HandlerAbort_Handler: B Abort_HandlerNOPIRQ_Handler: B IRQ_HandlerFIQ_Handler: B FIQ_HandlerReset_Handler: LDR sp, =0x00002000#----------------------------------------------------------------#- Branch on C code Main function (with interworking)#- Branch must be performed by an interworking call as either an ARM or Thumb #- main C function must be supported. This makes the code not position-#- independant. A Branch with link would generate errors#----------------------------------------------------------------.extern __mainldr r0, = __mainmov lr, pcbx r0#----------------------------------------------------------------#- Loop for ever#- End of application. Normally, never occur.#- Could jump on Software Reset ( B 0x0 ).#----------------------------------------------------------------End: B End.end链接脚本文件ldscript:SECTIONS{. = 0x0;.text : { *(.text) }.data : { *(.data) }.rodata : { *(.rodata) }.bss : { *(.bss) }}四、实验步骤:1.创建新的工程,工程名为:explasm;2.编写源代码文件并分别保存为randtest.c,init.s,random.s和ldscript,并加入工程里;3.按照编译、汇编器配置->链接器配置->调试器配置设置新工程;并编译链接工程;4.选择Debug菜单Remote Connect 进行连接软件仿真器,执行Download命令下载程序,并打开寄存器窗口。

5.下载调试文件,打开memory/register/watch/variable/call stack窗口,单步执行程序,并通过以上窗口,跟踪程序运行,观察分析运行结果,通过实验学会使用Embest IDE进行应用程序的开发与调试。

/********************************* Init.s*****************************/# *******************************************************# * NAME : 44BINIT.S *# * Version : 10.April.2000 *# * Description: *# * C start up codes *# * Configure memory, Initialize ISR ,stacks *# * Initialize C-variables *# * Fill zeros into zero-initialized C-variables *# *******************************************************#程序入口,arm汇编#.arm.global _start.text_start:# --- Setup interrupt / exception vectorsB Reset_HandlerUndefined_Handler:B Undefined_HandlerSWI_Handler:B SWI_HandlerPrefetch_Handler:B Prefetch_HandlerAbort_Handler:B Abort_HandlerNOP /* Reserved vector */IRQ_Handler:B IRQ_HandlerFIQ_Handler:B FIQ_HandlerReset_Handler:LDR sp, =0x00002000#------------------------------------------------------------------------------ #- Branch on C code Main function (with interworking)#----------------------------------------------------#- Branch must be performed by an interworking call as either an ARM or Thumb #- main C function must be supported. This makes the code not position-#- independant. A Branch with link would generate errors#------------------------------------------------------------------------------ .extern mainldr r0, = mainmov lr, pcbx r0#------------------------------------------------------------------------------ #- Loop for ever#---------------#- End of application. Normally, never occur.#- Could jump on Software Reset ( B 0x0 ).#------------------------------------------------------------------------------ End:b End.global __gccmain__gccmain:mov pc, lr.end/***********************************Ldscript*****************************/ SECTIONS{. = 0x0;.text : { *(.text) }.data : { *(.data) }.rodata : { *(.rodata) }.bss : { *(.bss) }}/***********************************random.s*****************************/ # Random number generator## This uses a 33-bit feedback shift register to generate a pseudo-randomly # ordered sequence of numbers which repeats in a cycle of length 2^33 - 1 # NOTE: randomseed should not be set to 0, otherwise a zero will be generated # continuously (not particularly random!).## This is a good application of direct ARM assembler, because the 33-bit# shift register can be implemented using RRX (which uses reg + carry).# An ANSI C version would be less efficient as the compiler would not use RRX.# AREA |Random$$code|, CODE, READONLY.GLOBAL randomnumberrandomnumber:# on exit:# a1 = low 32-bits of pseudo-random number# a2 = high bit (if you want to know it)LDR ip, seedpointerLDMIA ip, {a1, a2}TST a2, a2, LSR#1 /* to bit into carry */MOVS a3, a1, RRX /* 33-bit rotate right */ADC a2, a2, a2 /* carry into LSB of a2 */EOR a3, a3, a1, LSL#12 /* (involved!) */EOR a1, a3, a3, LSR#20 /* (similarly involved!)*/STMIA ip, {a1, a2}MOV pc, lrseedpointer:.LONG seed.DATA.GLOBAL seedseed:.LONG 0x55555555.LONG 0x55555555# END/*********************************randtest.c*****************************/ /* Random number generator demo programCalls assembler function 'randomnumber' defined in random.s*///#include <stdio.h>/* this function prototype is needed because 'randomnumber' is external */ extern unsigned int randomnumber( void );int main(){int i;int nTemp;unsigned int random[10];for( i = 0; i < 10; i++ ){nTemp = randomnumber();random[i] = nTemp;}return( 0 );}五、思考题:从汇编语言中调用C函数:使用C语言完成一个随机数产生函数,通过汇编语言调用该函数,产生一系列随机数,存放到数组里面。

相关文档
最新文档