版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
嵌入式系统设计西安邮电大学计算机学院王忠民基于ARMCortexM3IP核的程序设计(1)4.1ARM汇编语言的程序结构4.2ARM汇编器伪指令 4.2.1段定义伪指令 4.2.2数据定义伪指令 4.2.3过程定义伪指令 4.2.4宏定义伪指令 4.2.5其他伪指令4.3ARM汇编语言程序设计
4.3.1顺序程序
4.3.2分支程序
4.3.3循环程序
4.3.4过程(子程序)调用第4章基于ARMCortexM3IP核的程序设计---学习内容基于ARMCortexM3IP核的程序设计(2)4.4C与汇编混合编程
4.4.1ARM架构过程调用标准AAPCS (ARMArchitectureProcedureCallStandard)
4.4.2C程序内嵌汇编代码 4.4.3C程序调用汇编过程 4.4.4汇编程序调用C函数 4.4.5C与汇编程序变量互访
第4章基于ARMCortexM3IP核的程序设计---ARM架构过程调用标准AAPCS
ARM架构过程调用标准AAPCSC程序内嵌汇编代码 C程序调用汇编过程
汇编程序调用C函数C与汇编程序变量互访
如果工程比较小,使用纯汇编常常是可行的,而且你能随心欲地优化和控制程序。不过,你的开发周期会变长。尤其是当工程变大,需要处理比较复杂的数据结构,以及要管理函数库时,你将发现汇编会使工作量激增。各种地址和间接引用千头万绪;bug劈头盖脸;甚至好几天都改不完,简直就是自虐。当然,如果你想成为系统开发的大虾(大咖),就必须以“我不下地狱谁下地狱”的决心,去勇敢面对,后天下乐而乐。不论如何,时间宝贵。我们应该以C来实现程序的大框架,而本着好钢用在刀刃上的原则来使用汇编,因为只有在不多的特殊场合是非使用汇编语言不可的,它们是:无法用C写成的函数,如操作特殊功能寄存器,以及实施互斥访问。在危急关头执行的程序(如,NMI服务例程)。存储器极度受限,只有使用汇编才可能把程序或数据挤进去。执行频率非常高的子程,如操作系统的调度程序。与处理器体系结构相关的子程序,如上下文切换。
对性能要求极高的应用,如防空炮的火控系统。第4章基于ARMCortexM3IP核的程序设计---为什么要C与汇编混合编程第4章基于ARMCortexM3IP核的程序设计---为什么要C与汇编混合编程
在进行ARM嵌入式系统开发时,混合使用C和汇编语言进行软件设计的原因主要有以下几点:性能优化:汇编语言是直接与机器硬件打交道的编程语言,它能够精确控制CPU的每一个操作。在某些需要高性能的场景下,如中断处理、实时控制等,使用汇编语言可以编写出更高效的代码。而C语言虽然抽象层次较高,易于编写和理解,但在某些情况下可能无法达到汇编语言所能提供的性能。因此,在关键部分使用汇编语言,而在非关键部分使用C语言,可以在保证代码可读性和可维护性的同时,实现性能的优化。硬件操作:某些硬件操作,特别是与底层硬件紧密相关的操作,如直接访问内存地址、设置寄存器值等,使用汇编语言会更加方便和高效。这些操作在C语言中可能难以直接实现,或者实现起来较为复杂。通过使用汇编语言,可以直接编写与硬件相关的代码,实现对硬件的精确控制。系统启动:在嵌入式系统的启动过程中,往往涉及到对硬件的初始化、操作系统的加载等复杂操作。这些操作通常需要使用汇编语言来完成,因为汇编语言能够直接操作硬件,并且在系统启动的早期阶段,C语言运行环境可能还没有完全建立。代码移植性:虽然汇编语言与特定的硬件平台紧密相关,但在某些情况下,使用汇编语言编写的代码可能更容易在不同的硬件平台之间进行移植。这是因为汇编语言直接反映了硬件的特性和指令集,只要目标平台支持相同的指令集,汇编代码通常只需要进行少量的修改就可以在新的平台上运行。C语言与汇编语言分别有各自的优缺点。采用C语言进行算法设计和程序编写时,是面向过程的,整个流程清晰,实现起来较容易,且提供很多接口函数,但编译时生成的可执行文件大,因此实时性难以控制,也不能对硬件进行直接的操作。采用汇编语言进行程序设计时,比C语言的流程更不容易理解和设计,但汇编语言汇编生成的可执行文件小,执行速度快,实时性高,且能对内存,外设端口进行直接的读写操作。如果将二者结合起来进行开发,能简化编程难度,保证实时性,并能对硬件进行访问。第4章基于ARMCortexM3IP核的程序设计---ARM架构过程调用标准AAPCSARM架构过程调用标准AAPCS(ARMArchitectureProcedureCallStandard)是ARM公司制定的一套用于ARM处理器体系结构的函数调用和返回机制的标准。它旨在确保编译器生成的代码在ARM架构上的不同模块之间具有良好的互操作性和兼容性。通过遵循AAPCS,开发者可以更加高效地使用ARM架构的寄存器和堆栈资源,减少潜在的兼容性问题,提高代码的可移植性和可维护性。Thumb-2指令集在过程调用时,参数的传递遵循AAPCS过程调用标准。更早期的程序调用标准ATPCS(ARMThumbProcedureCallStandard)是为Thumb指令集定义的一种过程调用标准,随着ARM架构的发展和Thumb-2指令集的引入,AAPCS逐渐取代了ATPCS,成为更广泛接受的程序调用标准。推出AAPCS的主要目的是为了定义ARM架构中过程调用和返回的约定,确保不同编译器生成的代码之间的兼容性,以及不同模块之间的互操作性。它规定了一些过程间调用的基本规则,包括过程调用过程中寄存器的使用规则、数据栈的使用规则、参数的传递规则等。这些规则有助于确保单独编译的C语言程序能够和汇编程序相互调用,提高了代码的兼容性和互操作性。根据AAPCS规定,在参数传递过程中,主要考虑以下几种情况:1.参数传递2.返回值传递3.堆栈使用4.函数调用中的寄存器使用第4章基于ARMCortexM3IP核的程序设计---参数传递(1)通过寄存器传递
AAPCS规定,前四个整数或指针类型的参数通常通过寄存器R0-R3进行传递。这种机制有效地提高了函数调用的效率,因为寄存器访问通常比堆栈访问更快。对于64位的数据类型(如longlong),低32位放在R0或R2中,高32位放在R1或R3中。举例:假设有一个函数intmultiply(inta,intb),它接受两个整数参数并返回它们的乘积。在调用multiply函数时,参数a和b会分别被放置在R0和R1寄存器中。
(2)通过堆栈传递当参数数量超过四个时,额外的参数将通过堆栈进行传递。系统会自动将这些参数推送到堆栈上,并确保它们按照正确的顺序排列。堆栈的增长方向通常是向低地址方向,这意味着新的参数会被推送到当前堆栈指针以下的地址。第4章基于ARMCortexM3IP核的程序设计---返回值传递(1)通过寄存器返回函数的返回值通常保存在R0寄存器中。如果返回值是32位或以下的整型、指针或单精度浮点数,那么它就直接放在R0中;对于64位的返回值(如longlong或双精度浮点数),R0保存低32位,R1保存高32位;对于更大的数据结构(如结构体),返回值通常是通过指针传递的,该指针指向由调用者分配的内存空间,函数将结果写入这块内存。举例:考虑一个函数longlongmultiply64(longlonga,longlongb),它接受两个64位整数并返回它们的乘积。在调用multiply64函数后,其64位返回值会被保存在R0和R1寄存器中,其中R0保存低32位,R1保存高32位。(2)通过内存返回对于非常大的返回值或不适合通过寄存器传递的数据结构,通常的做法是通过指针返回。函数接收一个指向预先分配好的内存的指针作为参数,然后将结果写入该内存区域。第4章基于ARMCortexM3IP核的程序设计---函数调用中的寄存器使用(1)调用者保存的寄存器
R0-R3、R12属于调用者保存的寄存器,意味着调用者需要确保这些寄存器在调用函数前后的值保持不变。(2)被调用者保存的寄存器函数或子程序应该保持R4-R11、R13和R14的数值不变。若这些寄存器在函数或子程序执行期间被修改,则其应该保持在栈中并在返回调用代码前恢复。这些寄存器被称为“被调用者保存寄存器”。第4章基于ARMCortexM3IP核的程序设计---C与汇编混合编程ARM架构过程调用标准AAPCSC程序内嵌汇编代码 C程序调用汇编过程
汇编程序调用C函数C与汇编程序变量互访
第4章基于ARMCortexM3IP核的程序设计---C程序内嵌汇编代码 在KeilMDK5开发环境中,使用Thumb-2指令系统时,可以使用内嵌汇编(InlineAssembly)来直接在C语言程序中插入汇编指令。允许执行一些低级的、C语言无法直接处理的操作,或者优化某些关键代码段。在KeilMDK5中,C语言程序中内嵌汇编语句格式如下:__asm //asm前面使用的是双下划线{
汇编语句1
汇编语句2
汇编语句3
……}需要说明的是,在内嵌汇编中,一般不要直接指定物理寄存器,而要让编译器自动分配;如果一定要使用物理寄存器,要注意以下原则:R12与R13常用于存放中间编译结果,不能使用;R0~R3在过程调用中用于传递参数,不能使用;R14用于过程调用的返回,也不能使用。第4章基于ARMCortexM3IP核的程序设计---C程序内嵌汇编代码 例:编写一个由startup.s和My_C_Functions.c两个文件组成的工程,在C函数中嵌套汇编语句实现三个变量相加。
一个由汇编启动文件和C用户程序构成的工程第4章基于ARMCortexM3IP核的程序设计---C程序内嵌汇编代码 li4_10_C_embedded_asm工程中的C文件My_C_Functions.c代码如下:int addxyz(intx,inty,intz);//声明函数addxyz()int My_C_Functions(void){ int sum; sum=addxyz(1,2,3); //调用addxyz()函数
return0; }intaddxyz(intx,inty,intz) //函数addxyz()的三个实参1,2,3分别传递给x,y,z {__asm { add x,x,y //根据AAPCS参数传递规则,x,y,z分别对应寄存器R0,R1,R2 add x,x,z } return(x); }注意参数如何传递第4章基于ARMCortexM3IP核的程序设计---C函数中内嵌汇编指令(C工程不讲)1111_C_Embeded_Asm#include<stdio.h>#include<string.h>#defineITM_Port8(n)(*((volatileunsignedchar*)(0xE0000000+4*n)))#defineITM_Port16(n)(*((volatileunsignedshort*)(0xE0000000+4*n)))#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intbadf(intx);intmax(inta,intb,intc);intfputc(intch,FILE*f){ if(DEMCR&TRCENA) { while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}
intmain(void){int ch;int x;ch=badf(10);printf("ch=%d",ch);x=max(4,1,20);printf("\nmax=%d",x);return0;}intbadf(intx){__asm {addx,x,1} return(x);}intmax(inta,intb,intc){ intmaxtem; __asm {mov maxtem,a cmp maxtem,b bhi loop1 mov maxtem,bloop1: cmp maxtem,c bhi loop2 mov maxtem,cloop2: mov a,maxtem } return(a);}
问题描述:在C工程的main()文件中定义了二个函数:badf()—加1;max()—求三个数最大数。两个函数中均使用了内嵌汇编指令实现相关功能第4章基于ARMCortexM3IP核的程序设计---C调用汇编过程ARM架构过程调用标准AAPCS
C程序内嵌汇编代码
C程序调用汇编过程
汇编程序调用C函数C与汇编程序变量互访
C程序中调用汇编过程的具体步骤如下:(1)在C文件中用关键字extern声明要调用的汇编过程的原型,并定义好形参,然后就可以在C程序中调用该过程了。(2)在汇编程序中用伪指令EXPORT导出要调用的过程名,并定义该过程,使用BXLR返回;(3)如果在调用时需传递参数,参数1,2,3,4默认使用寄存器R0~R3传递,如果参数个数多于4个,则使用堆栈传递;(4)如果有返回值,则默认用R0返回。第五章CortexM3汇编语言程序设计基础---C调用汇编过程*.c(C文件)externintaddxy(intx,inty);….a=addxy(a,b);……*.asm(汇编文件) EXPORT addxyaddxy proc…… BX LR endp图C程序中调用汇编过程示意例:在C文件My_C_Functions.c中调用在汇编程序addxy.s中定义的过程addxy,实现将在C中定义的两个变量a和b相加。第五章CortexM3汇编语言程序设计基础---C调用汇编过程图C调用汇编过程的工程组成汇编程序addxy.s的代码如下: AREA armxy,CODE,READONLY EXPORT addxyaddxyproc ADD R0,R0,R1 BX LR endp
endC文件My_C_Functions.c代码如下: externintaddxy(intx,inty); intMy_C_Functions(void){ inta=1,b=2; a=addxy(a,b); return0; } li4_11_C_Call_Asm1例:
在C文件My_C_Functions.c中定义了一个十个元素的整型数组变量intn[],调用在汇编程序max_v.s中定义的过程N_Paixu,实现将在C中定义的数组n用冒泡法实现从小到大排序。第五章CortexM3汇编语言程序设计基础---C调用汇编过程汇编程序max_v.s的代码如下:
AREA MAX, CODE, READONLY EXPORT N_PaixuN EQU 10 N_Paixu PROC MOV R1,#0 MOV R2,#0 LOOPI ADD R3,R0,R1,LSL#2 MOV R4,R3 ADD R2,R1,#1 MOV R5,R4 LDR R6,[R4] LOOPJ ADD R5,R5,#4 LDR R7,[R5] CMP R6,R7 BLT NEXT LDR R7,[R5] STR R6,[R5] MOV R6,R7 NEXT ADD R2,R2,#1 CMP R2,#N BLT LOOPJ LDR R7,[R3] STR R6,[R3] ADD R1,R1,#1 CMP R1,#N-1 BLT LOOPI BX LR ENDP ENDC文件My_C_Functions.c代码如下:
externintN_Paixu(int*num); intMy_C_Functions(void){ intn[]={10,9,8,7,6,5,4,3,2,1}; N_Paixu(n); return(0); }li4_12_C_Call_Asm2在主调程序C中用EXTERN关键字声明被调用的外部汇编过程;在被调的汇编过程中使用EXPORT作声明本过程可以被外部调用。1111_C_Call_Asm1#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f)//???????{ if(DEMCR&TRCENA) { while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}externintadd_s(intx,inty);intmain(){ inta=1,b=2,c; printf("\na=%d",a); printf("\nb=%d",b);
c=add_s(a,b); printf("\na+b=%d",c); return0;}
AREAARM_add,CODE,READONLY
EXPORTadd_sadd_s ADDr0,r0,r1 MOVpc,lr end第五章CortexM3汇编语言程序设计基础---C调用汇编过程(C工程不讲)
问题描述:在C工程的main()函数中定义了三个变量(inta=1,b=2,c;),要求编写汇编过程实现c=a+b
在主调程序C中用EXTERN关键字声明被调用的外部汇编过程;在被调的汇编过程中使用EXPORT作声明本过程可以被外部调用。1111_C_Call_Asm3#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f)//???????{ if(DEMCR&TRCENA) {while(ITM_Port32(0)==0); ITM_Port8(0)=ch;} return(ch);}externintmax_v(int*num);intmain(){ intn[]={10,9,8,7,6,5,4,3,2,1}; intI; printf("TheOriginalNum:\n"); for(i=0;i<10;i++) {printf("n[%d]=%d",i,n[i]);}
max_v(n); printf("\nTherearrangedNum:\n"); for(i=0;i<10;i++) {printf("n[%d]=%d",i,n[i]);} return(0);}
AREAMAX, CODE, READONLY
EXPORTmax_vNEQU10 max_v
MOV R1,#0 MOV R2,#0 LOOPI ADD R3,R0,R1,LSL#2 MOV R4,R3 ADD R2,R1,#1 MOV R5,R4 LDR R6,[R4] LOOPJ ADD R5,R5,#4 LDR R7,[R5] CMP R6,R7 BLT NEXT ;SWP R7,R6,[R5] ldr r7,[r5] str r6,[r5] MOV R6,R7 NEXT ADD R2,R2,#1 CMP R2,#N BLT LOOPJ ldr r7,[r3] str r6,[r3] ADD R1,R1,#1 CMP R1,#N-1 BLT LOOPI BX LR END第五章CortexM3汇编语言程序设计基础---C调用汇编过程(C工程不讲)
问题描述:在C工程的main()函数中定义了一个十个元素的整型数组变量(intn[]),要求编写汇编过程实现冒泡排序第4章基于ARMCortexM3IP核的程序设计---C与汇编混合编程典型的开发流程---Cortex‐M3权威指南---第十章Cortex-M3的低层编程
ARM架构过程调用标准AAPCS
C程序内嵌汇编代码
C程序调用汇编过程
汇编程序调用C函数C与汇编程序变量互访
第4章基于ARMCortexM3IP核的程序设计--汇编调用C函数2025/11/28*.s(汇编程序)IMPORT My_C_Functions….LDR R0,=My_C_FunctionsBLX R0*.c(C程序)externintN_Paixu(int*num);intMy_C_Functions(void){ ……return(0); }汇编程序中调用C函数示意在汇编文件中,用伪指令IMPORT将要调用的C函数引用;在C文件中不需要做任何声明;如果在函数调用时需传递参数,参数1,2,3,4默认使用寄存器R0~R3传递,如果参数个数多于4个,则使用堆栈传递;如果函数有返回值,则默认用R0返回。应用场景:汇编调C这种情况在嵌入式系统开发中相对少见,但在某些特殊情况下,汇编代码可能需要调用C函数。例如,在启动代码或底层初始化代码中,可能需要调用一些用C语言编写的库函数。li4_13_ASM_CALL_C1第4章基于ARMCortexM3IP核的程序设计--汇编调用C函数2025/11/28例4-13在汇编编写的启动文件startup.s文件中,通过R0、R1、R2传递参数,调用在C程序中定义的求和函数,实现将三个变量的值相加。一个由汇编启动文件调用用户C程序的工程intaddxyz(inta,intb,intc){ intsum=0; sum=a+b+c; returnsum;}li4_14_ASM_CALL_C2第4章基于ARMCortexM3IP核的程序设计--汇编调用C函数(C工程不讲)2025/11/28例4.14C工程构建举例。在汇编启动文件startup.s文件中编写系统复位过程Reset_Handler,调用C语言编写的main()函数,以main()函数作为工程的入口。该工程中main()函数代码如下:externintaddxy(inta,intb);intmain(void){ inta=1; intb=2; intc; c=addxy(a,b); return0;}main函数入口的工程构建1110_asm_call_c1第4章基于ARMCortexM3IP核的程序设计--汇编调用C函数2025/11/28在汇编工程的主调汇编程序中,使用IMPORT声明要调用的C函数;C函数中不需要做任何声明注意参数传递遵循相关标准:R0,R1,R2,R3作为C函数传递的前4个参数,若还有更多参数,需通过堆栈传递…STACK_TOP EQU 0x20005000
IMPORT fun1 AREA RESET, CODE DCD STACK_TOP DCD start ENTRY start mov r0,5 LDR R10,=fun1 BLX R10deadloop B deadloop ENDintfun1(intn){
inti,sum=0; for(i=0;i<=n;i++) { sum=sum+i; } returnsum;}
问题描述:在汇编工程的汇编程序中,声明一个外部C函数,实参按相关标准,C函数实现累加和,其中n由r0传递。目前函数完成:1+2+……5
1110_asm_call_c2第4章基于ARMCortexM3IP核的程序设计--汇编调用C函数(不讲)在汇编工程的主调汇编程序中,使用IMPORT声明要调用的C函数;C函数中不需要做任何声明注意参数传递遵循相关标准:R0,R1,R2,R3作为C函数砂的前4个参数,若还有更多参数,需通过堆栈传递…STACK_TOP EQU 0x20005000
IMPORT fun1 AREA RESET, CODE DCD STACK_TOP DCD start ENTRY start mov r0,1 mov r1,2 mov r2,3 mov r3,4 mov r4,10 LDR R10,=fun1 BLX R10deadloop B deadloop END#include<stdio.h>#include<string.h>#defineITM_Port8(n)(*((volatileunsignedchar*)(0xE0000000+4*n)))#defineITM_Port16(n)(*((volatileunsignedshort*)(0xE0000000+4*n)))#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f){ if(DEMCR&TRCENA) { while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}intfun1(intn1,intn2,intn3,intn4,intn5){ printf("\nn1=%d",n1); printf("\nn2=%d",n2); printf("\nn3=%d",n3); printf("\nn4=%d",n4); printf("\nn5=%d",n5); intsum=0; sum=n1+n2+n3+n4+n5; printf("\nsum=%d",sum); returnsum;}只能传4个参数!
问题描述:在汇编工程的汇编程序中,声明一个外部C函数,实参按相关标准,C函数实现四个参数相加。---sum=1+2+3+4=10
第4章基于ARMCortexM3IP核的程序设计---C与汇编混合编程典型的开发流程---Cortex‐M3权威指南---第十章Cortex-M3的低层编程
ARM架构过程调用标准AAPCS
C程序内嵌汇编代码
C程序调用汇编过程
汇编程序调用C函数
C与汇编程序变量互访
在C和汇编混合编程的工程中,经常需要在两种语言之间共享数据。这通常涉及到在C和汇编之间传递变量或访问共享的内存区域。C与汇编程序变量互访使得两种语言能够无缝地协同工作。它允许开发者在C代码中定义变量,并在汇编代码中直接访问这些变量;或者在汇编代码中定义变量,并在C代码中读取或修改这些变量的值。这种互访能力极大地提高了混合编程的灵活性和效率。下面分两种情况进行介绍:汇编调C文件中的变量,C调用汇编文件中的变量。第4章基于ARMCortexM3IP核的程序设计--汇编访问C中全局变量*.cintc_var=1;//定义全局变量*.asmIMPORTc_var;获取c_var的地址,读取变量LDRR0,c_varLDRR1,[R0];写入变量c_varSTRR1,[R0]汇编访问C文件中的变量汇编文件访问C文件中的变量其具体方法:(1)在C文件中定义全局变量var;(2)在汇编程序中用IMPORT引入变量var;(3)使用伪指令LDR获取变量var变量的地址;(4)使用指令LDR获取变量var的值。1112_Asm_Access_CVariables1第4章基于ARMCortexM3IP核的程序设计--汇编访问C中全局变量(C工程不讲)在C工程的主调C程序中,定义全局变量;用EXTERN声明一个汇编过程;在汇编过程中使用IMPORT声明要使用的C中的外部变量;用EXPORT声明汇编中定义的过程可以被外部访问…#include<stdio.h>#include<string.h>#defineITM_Port8(n)(*((volatileunsignedchar*)(0xE0000000+4*n)))#defineITM_Port16(n)(*((volatileunsignedshort*)(0xE0000000+4*n)))#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f)//???????{ if(DEMCR&TRCENA) {while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}externintadd_v(intaddnum);intglobvar=3;intmain(){ intchangedglobvar; intaddn=255; printf("globvar=%d",globvar); changedglobvar=add_v(addn); printf("\nchangedglobvar=%d",changedglobvar); return(0);}AREAEX4_57,CODE,READONLYEXPORTadd_vIMPORTglobvaradd_v mov r10,r0 LDR R1,=globvarLDR R0,[R1]ADD R0,R0,R10STR R0,[R1]MOV PC,LREND
问题描述:在C工程中定义一个全局变量globvar=3,定义一个外部汇编过程intadd_v(intaddnum),实现globvar+addnum目前完成:3+255=2581112_Asm_Access_CVariables2第4章基于ARMCortexM3IP核的程序设计--汇编访问C中全局变量(C工程不讲)在C工程的主调C程序中,定义全局变量;用EXTERN声明一个汇编过程;在汇编过程中使用IMPORT声明要使用的C中的外部变量;用EXPORT声明汇编中定义的过程可以被外部访问…#include<stdio.h>#include<string.h>#defineITM_Port8(n)(*((volatileunsignedchar*)(0xE0000000+4*n)))#defineITM_Port16(n)(*((volatileunsignedshort*)(0xE0000000+4*n)))#defineITM_Port32(n)(*((volatileunsignedlong*)(0xE0000000+4*n)))#defineDEMCR(*((volatileunsignedlong*)(0xE000EDFC)))//DebugExceptionandMonitorControlRegister,DEMCR#defineTRCENA0x01000000struct__FILE{inthandle;};FILE__stdout;FILE__stdin;intfputc(intch,FILE*f)//???????{ if(DEMCR&TRCENA) {while(ITM_Port32(0)==0); ITM_Port8(0)=ch; } return(ch);}intn[]={10,9,8,7,6,5,4,3,2,1}externintmax_v(int*num);intmain(){ printf("TheOriginalNum:\n"); for(inti=0;i<10;i++) {printf("n[%d]=%d",i,n[i]); } max_v(n); printf("\nTherearrangedNum:\n"); for(inti=0;i<10;i++) {printf("n[%d]=%d",i,n[i]); } return(0);}AREAMAX,CODE,READONLY
EXPORTmax_vIMPORTnNEQU10max_v LDR R0,=n MOV R1,#0 MOV R2,#0 LOOPI ADD R3,R0,R1,LSL#2 ;ÍâÑ»·Ê×µØÖ··ÅÈëR3 MOV R4,R3 ADD R2,R1,#1 MOV R5,R4 LDR R6,[R4] LOOPJ ADD R5,R5,#4 LDR R7,[R5] CMP R6,R7 BLT NEXT ;SWP R7,R6,[R5] ldr r7,[r5] str r6,[r5] MOV R6,R7 NEXT ADD R2,R2,#1 CMP R2,#N BLT LOOPJ ;SWP R7,R6,[R3] ldr r7,[r3] str r6,[r3] ADD R1,R1,#1 CMP R1,#N-1 BLT LOOPI BX LR END
问题描述:在C工程中定义一个全局变量intn[]={10,9,8,7,6,5,4,3,2,1},定义一个外部汇编过程max_v(int*num),实现排序li4_15_ASM_CALL_Cvariable2025/11/28例4.15汇编访问C文件中变量举例。在C文件中定义一个全局变量globvar并赋初值,定义一个外部汇编过程intaddxy(inta,intb),实现a+b+globvar。第4章基于ARMCortexM3IP核的程序设计--汇编访问C中全局变量汇编中调用C中的变量globvar第4章基于ARMCortexM3IP核的程序设计--C调用汇编文件中的变量C调用汇编文件中的变量具体方法:(1)在汇编文件中,用伪指令“EXPORT”定义变量x1;(2)C文件中用extern引入该变量;(3)在C文件中用变量名访问该变量。*.cexternintx1;intmain(void){ inta=1; a=a+x1; return0;}EXPORT x1 AREAMYDATA,DATA,READONLYx1 dcd0xFF endC调用汇编文件中的变量举例li4_16_C_CALL_ASMVariable概览
C函数调用汇编过程
C函数中内嵌汇编指令汇编调用C函数汇编访问C中全局变量典型的开发流程第4章基于ARMCortexM3IP核的程序设计典型的开发流程---Cortex‐M3权威指南---第十章Cortex-M3的低层编程
在开发基于CM3的应用程序时,常常有多种源程序和库,有些是自己写的,有些是别人已经写好的(尤其是底层的软件)。上述这些开发工具,在代码生成的流程都差不离。对于最基本的应用,也至少需要C编译器,连接器以及二进制文件处理工具。如果使用的是ARM的工具,如RVDS或RealView编译器工具(RVCT),则它们的流程如下图所示。其中的“分散加载脚本”是可选的,但是当存储器映射变得比较复杂时,则需要它。图
使用ARM工具链时的典型开发流程第4章基于ARMCortexM3IP核的程序设计---典型的开发流程
本章为提供了若干汇编写的例子,在实际应用中,这些程序都会用C写。但是以汇编的方式呈现,有助于让读者更深更好地理解CM3的工作内幕,以便在以后用C开发时心里更有底。这里给的程序都用ARM的汇编器(armasm)来汇编,其它工具可能对语法格式有些不同的要求。
而且实际上,开发工具几乎都会把启动工作为你做好,让你根本不用去想还有启动代码的事(不过,这也妨碍了我们学习得更深入)。下面,就隆重请出本书第一个完整的示例程序(请参考向量表来阅读)第4章基于ARMCortexM3IP核的程序设计---典型的开发流程STACK_TOPEQU0x20002000 ;SP初始值,常数 AREA|HeaderCode|,CODE DCDSTACK_TOP ;栈顶(MSP的) DCDStart ;复位向量 ENTRY ;指示程序从这里开始执行Start ;主程序开始 ;初始化寄存器 MOVr0,#10 ;加载循环变量的初值 MOVr1,#0 ;初始化运算结果的值 ;计算10+9+8+...+1loop ADDr1,r0;R1+=R0 SUBSr0,#1 ;R0自减,并且根据结果更新标志(有”S”后缀) BNEloop ;if(R0!=0)gotoloop; ;现在,运算结果在R1中deadloop Bdeadloop;工作完成后,进入无穷循环 END;标记文件结束第4章基于ARMCortexM3IP核的程序设计---典型的开发流程
重温一下我们的第一个例子:在我们做到程序连接这一步时,我们手工指定了读/写区的位置。那么我们该如何把数据放到那里呢?正点的解决方法是:在汇编源文件中定义一个相应的数据区。让连接器把数据区中的内容分派到我们指定的位置——从0x20000000(SRAM区的起始)处开始的内存。第4章基于ARMCortexM3IP核的程序设计---典型的开发流程STACK_TOPEQU0x20002000 ;SP初始值,常数 AREA|HeaderCode|,CODE DCDSTACK_TOP ;栈顶(MSP的) DCDStart ;复位向量 ENTRY ;指示程序从这里开始执行Start MOVr0,#10 ;加载循环变量的初值 MOVr1,#0 ;初始化运算结果的值loop ADDr1,r0 ;R1+=R0 SUBSr0,#1 ;R0自减,并且根据结果更新标志(有”S”后缀) BNEloop ;if(R0!=0)gotoloop; LDRr0,=MyData1 STRr1,[r0] ;把结果存入MyData1deadloop Bdeadloop ;工作完成后,进入无穷循环 AREA|HeaderData|,DATA ALIGN4 MyData1 DCD0 ;Destinationofcalculationresult MyData2 DCD0 END;文件结束标记在连接阶段,连接器要把DATA区放入读/写存储器中,因此MyData1的地址就将是我们指定的0x2000_0000。第4章基于ARMCortexM3IP核的程序设计---典型的开发流程本次课内容就介绍完了,同学们,再见!在CM3上编程,既可以使用C也可以使用汇编。可能还有其它语言的编译器,但是大多数人还是会在C与汇编的世界里游弋。C与汇编都有尺短寸长,不能互相取代。使用C能开发大型程序,而汇编则用于执行特种任务。
TheCortex-M3canbeprogrammedusingei
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 房地产行业深度报告:地产与AI工具系列报告之二基于OpenClaw的房地产股票投研生产力提升实践
- 企业文化建设在企业管理中的重要性探究
- (新)《医院感染管理制度》测试题及答案
- 2026年保密宣传月保密知识真题试卷+参考答案
- 2026年湖南张家界中小学教师招聘考试试题题库及答案
- 2026年保密教育线上培训题库及一套完整答案
- 2026年安徽省马鞍山市重点学校小升初英语考试真题及参考答案
- 高中Unit 3 The world of science教学设计
- 第3节 创意涂鸦教学设计初中信息技术(信息科技)第二册粤教版(广州)
- 2026年诉状土地合同(1篇)
- 《儿童青少年“五健”促进行动计划(2026-2030年)》核心要点解读课件
- 无人机应用于施工巡检方案
- 羊水栓塞指南2025版
- 2025西部科学城重庆高新区招聘急需紧缺人才35人参考笔试题库及答案解析
- 2025辽宁葫芦岛市总工会招聘工会社会工作者5人笔试考试参考试题及答案解析
- 经济学的思维方式全套课件
- 郑钦文事迹介绍
- 中外舞蹈史课程大纲
- 载人飞艇系留场地净空要求细则
- 大棚螺旋桩施工方案
- 中数联物流科技(上海)有限公司招聘笔试题库2025
评论
0/150
提交评论