嵌入式体系结构及接口技术:第8章 ARM汇编语言与嵌入式C混合编程_精简_第1页
嵌入式体系结构及接口技术:第8章 ARM汇编语言与嵌入式C混合编程_精简_第2页
嵌入式体系结构及接口技术:第8章 ARM汇编语言与嵌入式C混合编程_精简_第3页
嵌入式体系结构及接口技术:第8章 ARM汇编语言与嵌入式C混合编程_精简_第4页
嵌入式体系结构及接口技术:第8章 ARM汇编语言与嵌入式C混合编程_精简_第5页
已阅读5页,还剩61页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、1TM第第8章章 ARM汇编语言与嵌入式汇编语言与嵌入式C混合编程混合编程 本章首先简要的介绍了嵌入式本章首先简要的介绍了嵌入式C语言的编程规语言的编程规范,嵌入式开发中常用的范,嵌入式开发中常用的位运算位运算与控制位域及在嵌与控制位域及在嵌入式入式C程序设计中要注意的问题,为读者进行嵌入式程序设计中要注意的问题,为读者进行嵌入式C程序设计打基础。然后介绍在程序设计打基础。然后介绍在ARM汇编语言与嵌汇编语言与嵌入式入式C语言进行相互调用的标准(语言进行相互调用的标准(AAPCS),),并以并以大量的实例说明了相互调用应注意的问题。大量的实例说明了相互调用应注意的问题。2TM2内容提要内容提要

2、81 嵌入式嵌入式C编程规范编程规范82 嵌入式嵌入式C程序设计中的位运算程序设计中的位运算83 嵌入式嵌入式C程序设计中的几点说明程序设计中的几点说明84 嵌入式嵌入式C程序设计格式程序设计格式85 过程调用标准过程调用标准ATPCS与与AAPCS86 ARM汇编语言与嵌入式汇编语言与嵌入式C混合编程混合编程3TM38.2 嵌入式嵌入式C程序设计中的位运算程序设计中的位运算n在嵌入式程序设计中,位操作是最常用的运算之一在嵌入式程序设计中,位操作是最常用的运算之一,因为在很多情况下要对寄存器中的某位或某个管,因为在很多情况下要对寄存器中的某位或某个管脚进行操作,这些都需要用位操作来完成。脚进行

3、操作,这些都需要用位操作来完成。 位运算符位运算符描描 述述位运算符位运算符描描 述述&按位与按位与取反取反|按位或按位或右移右移4TM48.2.1 按位与操作按位与操作n按位与运算符按位与运算符“&”是把参与运算的两个操作数所对是把参与运算的两个操作数所对应的各个二进制位进行按位相与。只有当对应的两应的各个二进制位进行按位相与。只有当对应的两个二进制位全为个二进制位全为1时,结果才为时,结果才为1,否则为,否则为0。参与。参与运算的两个操作数以补码形式出现。运算的两个操作数以补码形式出现。n例如例如7 & 3,补码分别为,补码分别为0000 0111与与0000 0011 按按位与运算后结果

4、为位与运算后结果为0000 0011等于十进制的等于十进制的3。按位按位与操作可以实现将特定的位清零,也可以用于提取与操作可以实现将特定的位清零,也可以用于提取出某数的指定位。出某数的指定位。5TM58.2.1 按位与操作按位与操作例例8-1 通过取出通过取出LedStatus的特定位进行判断选择对端口的特定位进行判断选择对端口B的数的数据寄存器进行特定的清零,据寄存器进行特定的清零,控制控制LED1和和LED2灯的点亮灯的点亮,其,其中端口中端口B(rPDATAB)第第2、3管脚分别连接管脚分别连接LED1、LED2(管(管脚从脚从0管脚开始编号,管脚开始编号,低电平点亮,低电平点亮,程序不

5、更改其他位)程序不更改其他位)解解:(1)根据根据LedStatus第第0位的状态确定是否点亮位的状态确定是否点亮LED1if(LedStatus&0 x01)=0 x01)rPDATAB=rPDATAB&0 xFFFFFFFB; (2)根据根据LedStatus第第1位的状态确定是否点亮位的状态确定是否点亮LED2if(LedStatus&0 x02)=0 x02)rPDATAB=rPDATAB&0 xFFFFFFF7;6TM68.2.2 按位或操作按位或操作n按位或操作运算符按位或操作运算符“|”是把参与运算的两个操作数是把参与运算的两个操作数对应的各个二进制位进行按位相或。对应的两个二对

6、应的各个二进制位进行按位相或。对应的两个二进制位中只要有一个为进制位中只要有一个为1,结果就为,结果就为1,当两个对应,当两个对应的二进制位都为的二进制位都为0时,结果位为时,结果位为0。参与运算的两个。参与运算的两个操作数均以补码形式出现。操作数均以补码形式出现。n例如例如7 | 3,7的补码为的补码为0000 0111,3的补码为的补码为0000 0011,结果为,结果为0000 0111。按位与操作可以实现将按位与操作可以实现将特定位的置位操作,特定位的置位操作,也可以用于提取出某数的指定也可以用于提取出某数的指定位。位。7TM78.2.2 按位或操作按位或操作例例8-2 通过取出通过取

7、出LedStatus的特定位进行判断选择对端口的特定位进行判断选择对端口B的数的数据寄存器进行特定的置据寄存器进行特定的置1,控制,控制LED1和和LED2灯的熄灭,其灯的熄灭,其中端口中端口B(rPDATAB)第第2、3管脚分别连接管脚分别连接LED1、LED2(管(管脚从脚从0管脚开始编号,低电平点亮,程序不更改其他位)管脚开始编号,低电平点亮,程序不更改其他位)解解:(1)根据根据LedStatus第第0位的状态确定是否熄灭位的状态确定是否熄灭LED1if(LedStatus&0 x01)!=0 x01)rPDATAB=rPDATAB&0|0 x4; (2)根据根据LedStatus第第

8、1位的状态确定是否熄灭位的状态确定是否熄灭LED2if(LedStatus&0 x02)!=0 x02)rPDATAB=rPDATAB|0 x8;8TM88.2.3 按位异或操作按位异或操作n按位异或运算符按位异或运算符“”是将参与运算的两个操作数对是将参与运算的两个操作数对应的各个二进制位进行相异或,当对应的两个二进应的各个二进制位进行相异或,当对应的两个二进制位相异时,结果位为制位相异时,结果位为1,相同时为,相同时为0。参与运算的。参与运算的两个操作数均以补码形式出现。两个操作数均以补码形式出现。n例如例如7 | 3,7的补码为的补码为0000 0111,3的补码为的补码为0000 00

9、11,结果为,结果为0000 0100。9TM9例例8-3 按位异或操作可以实现将特定位的值取反按位异或操作可以实现将特定位的值取反,也可以实现,也可以实现在不引入第三个变量的情况下,交换两个变量的内容。在不引入第三个变量的情况下,交换两个变量的内容。(1)改变端口)改变端口B的数据寄存器的第的数据寄存器的第2位的值,如果原来为位的值,如果原来为1则则清零,如果原来为清零,如果原来为0则置则置1:rPDATAB = rPDATAB 0 x04(2)将)将rPDATAB 与变量与变量tmp的值进行交换的值进行交换 rPDATAB = rPDATAB tmptmp = tmp rPDATAB rP

10、DATAB = rPDATAB tmp 8.2.3 按位异或操作按位异或操作10TM108.2.4 取反操作取反操作n取反运算符取反运算符“”实现对参与运算的操作数对应的各实现对参与运算的操作数对应的各个二进制位按位求反。取反运算符个二进制位按位求反。取反运算符“”具有右结合具有右结合性。所有性。所有1变为变为0,0变为变为1n例如例如(0101 1001) = 1010 0110。在程序中主要用。在程序中主要用于将操作数的某位或某些位取反,为其他操作提供于将操作数的某位或某些位取反,为其他操作提供数据准备。数据准备。ntmp = tmp & 1 作用是什么?作用是什么?11TM118.2.5

11、 移位操作移位操作n移位操作分为左移操作与右移操作。左移运算符移位操作分为左移操作与右移操作。左移运算符“”实现将实现将“”左边的操作数的各个二进制位向左边的操作数的各个二进制位向左移动左移动“”右边操作数所指定的位数,高位丢弃右边操作数所指定的位数,高位丢弃,低位补,低位补0。其值相当于乘以。其值相当于乘以2左移位数左移位数。 n应用:设置相应的位应用:设置相应的位#define BIT_UTXD1 (0 x12)#define BIT_UTXD0 (0 x1”实现将实现将“”左边的操作数的各个左边的操作数的各个二进制位向右移动二进制位向右移动“”右边操作数所指定的位数右边操作数所指定的位数

12、。对于空位的补齐方式,无符号数与有符号数是有。对于空位的补齐方式,无符号数与有符号数是有区别的。对无符号数进行右移时,低位丢弃,高位区别的。对无符号数进行右移时,低位丢弃,高位用用0补齐,其值相当于除以补齐,其值相当于除以2右移位数右移位数。 n对有符号数进行右移时,根据处理器的支持不同,对有符号数进行右移时,根据处理器的支持不同,有的采取逻辑右移,有的则采取算术右移。有的采取逻辑右移,有的则采取算术右移。8.2.5 移位操作移位操作13TM138.3 嵌入式嵌入式C程序设计中的几点说明程序设计中的几点说明n8.3.1 volatile限制符限制符n8.3.2 地址强制转换地址强制转换与多级指

13、针与多级指针n8.3.3 预处理的使用预处理的使用14TM148.3.1 volatile限制符限制符nvolatile的本意为的本意为 “暂态的暂态的”或或“易变的易变的”,该说明符起到,该说明符起到抑制编译器优化抑制编译器优化的作用。的作用。 n对于一个变量,如果编译器发现赋值后没有变化,编译器就对于一个变量,如果编译器发现赋值后没有变化,编译器就可能优化代码,直接从内部高速缓存可能优化代码,直接从内部高速缓存CACHE或寄存器获取或寄存器获取数据,而不是从内存中读取。如果这段时间里,变量被中断数据,而不是从内存中读取。如果这段时间里,变量被中断服务或外围设备输入等编译器未知的原因更改,程

14、序可能没服务或外围设备输入等编译器未知的原因更改,程序可能没有获得最新的值而导致运行结果异常有获得最新的值而导致运行结果异常 15TM158.3.1 volatile限制符限制符n如果在声明时用如果在声明时用“volatile”关键进行修饰,遇到这个关键字关键进行修饰,遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供从而可以提供特殊地址的稳定访问特殊地址的稳定访问。 n下列情况应该使用下列情况应该使用volatile限制符:限制符:存储器映射的硬件寄存器;存储器映射的硬件寄存器;中断服务程序中修改的供其他程序检测

15、的变量;中断服务程序中修改的供其他程序检测的变量;多任务环境下各任务间共享的标志。多任务环境下各任务间共享的标志。16TM168.3.1 volatile限制符限制符n例:例:(1)硬件端口寄存器读取)硬件端口寄存器读取char x=0,y=0,z=0;/读取读取I/O空间空间0 x5400000端口的内容存入端口的内容存入x变量变量x=ReadChar(0 x5400000);y=x;/再次读取再次读取I/O空间空间0 x5400000端口的内容存入端口的内容存入x变量变量x=ReadChar(0 x5400000);z=x;17TM178.3.1 volatile限制符限制符n例:例:(1

16、)硬件端口寄存器读取)硬件端口寄存器读取上面的程序很可能被编译器优化为:上面的程序很可能被编译器优化为:x=ReadChar(0 x5400000);y=x;z=x;因此声明时应改为:因此声明时应改为:volatile char x;char y=0,z=0;18TM188.3.1 volatile限制符限制符n例:例:(2)中断服务程序中修改供其他程序检测的变量)中断服务程序中修改供其他程序检测的变量static char flg=0;main(void)while(1)if(flg) /程序块程序块A else /程序块程序块B 19TM198.3.1 volatile限制符限制符n例:例

17、:(2)中断服务程序中修改供其他程序检测的变量)中断服务程序中修改供其他程序检测的变量/*中断服务程序中断服务程序*/void ISR_INT1(void) flg=1; 上页的代码很可能被优化为:上页的代码很可能被优化为:static char flg=0;main(void)while(1) /程序块程序块B 20TM208.3.2 地址强制转换与多级指针地址强制转换与多级指针 1. 地址强制转换地址强制转换n在在C程序设计中,绝对地址程序设计中,绝对地址0 x0FA00只是被当成只是被当成一个整型数,如果要把它当成一个地址来使用就一个整型数,如果要把它当成一个地址来使用就需要进行地址强制

18、转换。需要进行地址强制转换。n如定义一个整形指针如定义一个整形指针int *p,然后把绝对地址,然后把绝对地址0 x0FA00转换成一个整形的地址值赋给这个整形转换成一个整形的地址值赋给这个整形指针,指针,p = (int *)0 x0FA00。 21TM21 在嵌入式程序设计中,经常可以可以看到寄存器在嵌入式程序设计中,经常可以可以看到寄存器用如下方式进行定义:用如下方式进行定义:#define rPCONA(*(volatile unsigned *)0 x1D20000)#define rPDATA(*(volatile unsigned *)0 x1D20004)其中,其中,0 x1D

19、20000为为S3C44B0端口端口A的控制寄存器地址,的控制寄存器地址,0 x1D20004为为S3C44B0端口端口A的数据寄存器地址。的数据寄存器地址。8.3.2 地址强制转换与多级指针地址强制转换与多级指针 22TM228.3.3 预处理的使用预处理的使用n常见预处理命令:常见预处理命令:#define#undef#include#ifdef#ifndef#if#elif#else#endif23TM238.3.3 预处理的使用预处理的使用1. 宏定义宏定义(#define)(1) 不带参数的宏不带参数的宏 不带参数的宏定义的一般形式为:不带参数的宏定义的一般形式为:#define 宏

20、名宏名 宏体宏体功能:用指定表示符(宏名)代替字符序列(宏体)功能:用指定表示符(宏名)代替字符序列(宏体),可以定可以定义在任何位置,一般定义在函数外面。如果没有使用义在任何位置,一般定义在函数外面。如果没有使用#undef,它的作用域是从定义命令开始到文件的结束,它的作用域是从定义命令开始到文件的结束为止。为止。#undef语法格式:语法格式:#undef 宏名宏名24TM248.3.3 预处理的使用预处理的使用1. 宏定义宏定义(#define)(1) 不带参数的宏不带参数的宏 例:例:#define YES 1#define NO 0if(x=YES) printf(“welcome!

21、n”);else if(x=NO) printf(“error!n”);展开后展开后:if(x=1) printf(“welcome!n”);else if(x=0) printf(“error!n”);25TM258.3.3 预处理的使用预处理的使用1. 宏定义宏定义(#define)(1) 不带参数的宏不带参数的宏 引号内与宏名相同的内容不进行替换,如:引号内与宏名相同的内容不进行替换,如:#define PI 3.14printf(“2 * PI = %fn”,PI*2);展开后:展开后:printf(“2 * PI = %fn”,3.14*2);26TM268.3.3 预处理的使用预处

22、理的使用(2) 带参数的宏定义带参数的宏定义带参数的宏定义一般形式为:带参数的宏定义一般形式为:#define 宏名宏名(参数表参数表) 宏体宏体注意:宏名与后面的括号之间没有空格;宏的展开是注意:宏名与后面的括号之间没有空格;宏的展开是将形参用实参进行替换,其他字符保留,宏体及各将形参用实参进行替换,其他字符保留,宏体及各形参一般应加括号()。形参一般应加括号()。27TM278.3.3 预处理的使用预处理的使用(2) 带参数的宏定义带参数的宏定义例:例:#define POWER(x) x*xx=4;y=6;z=POWER(x+y);展开后展开后28TM288.3.3 预处理的使用预处理的

23、使用2. 文件包含文件包含(#include) n文件包含的功能是使得一个源文件可以将另一个源文件包含的功能是使得一个源文件可以将另一个源文件的内容全部包含进来,它的一般形式为:文件的内容全部包含进来,它的一般形式为: #include “文件名文件名” /先搜索当前目录,再搜索标准目先搜索当前目录,再搜索标准目录,可以指定目录录,可以指定目录#include/直接按标准目录搜索直接按标准目录搜索 一般在头文件(一般在头文件(.h)中包含宏定义、数据结构定义、函)中包含宏定义、数据结构定义、函数说明等,然后在源文件(数说明等,然后在源文件(.c)中使用文件包含命令)中使用文件包含命令29TM2

24、98.3.3 预处理的使用预处理的使用2. 文件包含文件包含(#include) 例例8-9/头文件头文件#define SQR(x) (x)*(x)#define CUBE(x) (x)*(x)*(x)#define QUAD(x) (x)*(x)*(x)*(x)/源文件源文件#include #include ex8_9.h#define MAX_POWER 10int main()int n;printf(numbert exp2t exp3t exp4tn);printf(-t-t-t-n);for(n=1;n1;temp-)result*=temp;return result;42T

25、M428.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调程序相互调用用n怎么在汇编程序中调用怎么在汇编程序中调用C语言程序中定义的函数?语言程序中定义的函数?IMPORT jiechengAREA mainProgram,CODE,READONLYENTRYCODE32MOV R0,#0MOV R1,#0BL jiechengstopB stopEND43TM438.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调程序相互调用用n在汇编程序中将在汇编程序中将C语言函数的函数名视为程序标号语言函数的函数名视为程序标号进行处理。进行处理。n结果是如何返回的?结果是如何返回的?

26、44TM448.5.3 参数传递规则参数传递规则3. 子程序结果返回规则子程序结果返回规则(1)结果为一个)结果为一个32位的整数时,通过寄存器位的整数时,通过寄存器R0返回;结果为一个返回;结果为一个64位整数位整数时,通过寄存器时,通过寄存器R0,R1返回。返回。(2)结果为一个浮点数时,可以通过浮点运算部件的寄存器)结果为一个浮点数时,可以通过浮点运算部件的寄存器F0、D0或者或者S0来返回;结果为复合型的浮点数(如复数)时,可以通过寄存器来返回;结果为复合型的浮点数(如复数)时,可以通过寄存器F0Fn或者或者0n来返回。来返回。(3)对于位数更多的结果,需要通过内存来传递。)对于位数更

27、多的结果,需要通过内存来传递。返回值类型寄存器返回值类型寄存器charR032位结构体R0shortR0long longR0,R1int/longR0doubleR0,R1floatR064位结构体R0,R132位指针R045TM458.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调程序相互调用用n能不能传递参数?能不能传递参数? 将上述求阶乘的程序改写为更加通用的方式:求将上述求阶乘的程序改写为更加通用的方式:求n的阶乘的阶乘long long jiecheng(int n)long long result=1;int temp;for(temp=n;temp1;temp-)r

28、esult*=temp;return result;46TM468.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调程序相互调用用n汇编程序中调用汇编程序中调用C语言程序时如何给参数语言程序时如何给参数n传值?传值?IMPORT jiechengAREA mainProgram,CODE,READONLYENTRYCODE32MOV R0,#10MOV R1,#0BL jiechengstopB stopEND47TM478.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调程序相互调用用nR0传给了传给了n?n调用多个参数的子程序时如何传递参数?调用多个参数的子程序时如何传

29、递参数?48TM488.5.3 参数传递规则参数传递规则参数个数固定的子程序参数传递规则参数个数固定的子程序参数传递规则 如果系统不包含浮点运算的硬件部件且没有浮点参数时,如果系统不包含浮点运算的硬件部件且没有浮点参数时,则依次将各参数传送到寄存器则依次将各参数传送到寄存器R0R3中,如果参数个数多于中,如果参数个数多于4个,将剩余的字数据通过数据栈来传递;个,将剩余的字数据通过数据栈来传递; 如果参数多于如果参数多于4个,将剩余字数据传送到数据栈中,入栈个,将剩余字数据传送到数据栈中,入栈的顺序与参数顺序相反,即最后一个字数据先入栈。的顺序与参数顺序相反,即最后一个字数据先入栈。 49TM4

30、98.5.3 参数传递规则参数传递规则例例 传递的参数多于传递的参数多于4个时的情况个时的情况 EXTERN sum AREA main,CODE,READONLY ENTRY CODE32start MOV R0,#100 MOV R1,#100 MOV R2,#100 MOV R3,#100 STMFD SP!,R4 MOV R4,#100 STMFD SP!,R4 BL sumexit B exit ENDint sum(int a,int b,int c,int d,int e) return a+b+c+d+e;50TM508.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互

31、调程序相互调用用2 C程序调用汇编程序程序调用汇编程序n在在ARM开发工具编译环境下,开发工具编译环境下, C程序中要用关键字程序中要用关键字extern声明要调用的汇编语言程序。同时也要在汇编程序中使用声明要调用的汇编语言程序。同时也要在汇编程序中使用EXPORT伪操作声明本程序可以被其他程序调用。伪操作声明本程序可以被其他程序调用。n在在GNU ARM编译环境下,在编译环境下,在C程序中要用关键字程序中要用关键字extern声声明要调用的汇编语言程序,同时在汇编程序中要使用明要调用的汇编语言程序,同时在汇编程序中要使用.global伪操作声明汇编程序为全局的函数,可被外部函数伪操作声明汇编

32、程序为全局的函数,可被外部函数调用。调用。51TM518.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调程序相互调用用n例例8-18在在ARM开发工具编译环境开发工具编译环境下设计程序,用下设计程序,用C语言调用语言调用ARM汇编语言实现汇编语言实现20的阶乘(的阶乘(20!)操!)操作,并将作,并将64位结果保存到位结果保存到0 xFFFFFFF0开始的内存开始的内存地址单元,按照小端格式低位数据存放在低地址单地址单元,按照小端格式低位数据存放在低地址单元。元。52TM528.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调用程序相互调用n汇编语言子程序汇编语言子程序A

33、REA Fctrl, CODE, READONLY EXPORT jiechengjiechengMOVR8 , #20MOVR9 , #0SUBR0,R8,#1LoopMOVR1 , R9UMULLR8 , R9 , R0 , R8MLAR9 , R1 , R0 , R9SUBSR0 , R0 , #1BNELoopLDRR0,=0 xFFFFFFF0STMIA R0,R8,R9MOVPC,LREND53TM538.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调用程序相互调用n如果主程序也是汇编语言编写,则用如果主程序也是汇编语言编写,则用BL指令调用子程序指令调用子程序IMPO

34、RT jiechengAREA mainProgram,CODE,READONLYENTRYCODE32BL jiechengstopB stopENDn主程序是主程序是C语言编写,如何转移到汇编程序某标号处执行呢?语言编写,如何转移到汇编程序某标号处执行呢?54TM548.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调用程序相互调用n答案是:以函数调用的方式调用汇编子程序,函数名答案是:以函数调用的方式调用汇编子程序,函数名为汇编程序第一条指令前的标号。为汇编程序第一条指令前的标号。extern void jiecheng(void); main() char N =20; ji

35、echeng(); while(1);55TM55n程序运行结果如下:程序运行结果如下:56TM568.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调用程序相互调用nC语言程序调用汇编语言子程序时如何传递参数?语言程序调用汇编语言子程序时如何传递参数?如何返回结果?如何返回结果?57TM578.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调用程序相互调用n汇编语言子程序汇编语言子程序AREA Fctrl, CODE, READONLY EXPORT jiechengjiechengMOVR8 , R0MOVR9 , #0SUBR0,R8,#1LoopMOVR1 , R9

36、UMULLR8 , R9 , R0 , R8MLAR9 , R1 , R0 , R9SUBSR0 , R0 , #1BNELoopLDRR0,=0 xFFFFFFF0STMIA R0,R8,R9MOVPC,LREND58TM588.6.2 ARM汇编语言与嵌入式汇编语言与嵌入式C程序相互调用程序相互调用extern void jiecheng(char x); main() char N = 4; jiecheng(N); while(1);59TM598.5 过程调用标准过程调用标准ATPCS与与AAPCSn过程调用标准过程调用标准ATPCS(ARM-Thumb Produce Call S

37、tandard)规定了子程序间相互调用的基本规则,)规定了子程序间相互调用的基本规则, ATPCS规定子程序调用过程中规定子程序调用过程中寄存器的使用规则、数据栈的使用规寄存器的使用规则、数据栈的使用规则及参数的传递规则则及参数的传递规则。 n2007年,年,ARM公司推出了新的过程调用标准公司推出了新的过程调用标准AAPCS(ARM Architecture Produce Call Standard),它只是改进它只是改进了原有的了原有的ATPCS的二进制代码的兼容性。的二进制代码的兼容性。 60TM608.5.1 寄存器使用规则寄存器使用规则(1)子程序间通过寄存器子程序间通过寄存器R0

38、R3传递参数,传递参数,寄存器寄存器R0R3可记作可记作A1A4。被调用的子程序在返回前无须恢复寄存器。被调用的子程序在返回前无须恢复寄存器R0R3的内容。的内容。(2)在子程序中,在子程序中,ARM状态下使用寄存器状态下使用寄存器R4R11来保存局来保存局部变量,部变量,寄存器寄存器R4R11可记作可记作V1V8;Thumb状态下只状态下只能使用能使用R4R7来保存局部变量。来保存局部变量。 61TM618.5.1 寄存器使用规则寄存器使用规则(3)寄存器)寄存器R12用作子程序间调用时临时保存栈指针,函数用作子程序间调用时临时保存栈指针,函数返回时使用该寄存器进行出栈,记作返回时使用该寄存

39、器进行出栈,记作IP;在子程序间的链接;在子程序间的链接代码中常有这种使用规则。代码中常有这种使用规则。(4)通用寄存器)通用寄存器R13用作数据栈指针,记作用作数据栈指针,记作SP。在子程序中。在子程序中R13不能用于其他用途。不能用于其他用途。SP在进入子程序时的值和退出子程在进入子程序时的值和退出子程序时的值必须相等。序时的值必须相等。 (5)通用寄存器)通用寄存器R14用作链接寄存器用作链接寄存器 。如果在子程序中保存。如果在子程序中保存了返回地址,如果了返回地址,如果R14可用于其他用途。可用于其他用途。(6)通用寄存器)通用寄存器R15用作程序计数器,记作用作程序计数器,记作PC

40、,不能用于其,不能用于其他用途。他用途。62TM628.5.2 数据栈使用规则数据栈使用规则n 过程调用标准规定数据栈为过程调用标准规定数据栈为FD类型,并且对数据栈的操作类型,并且对数据栈的操作时要求时要求8字节对齐字节对齐(通过伪操作通过伪操作PRESERVE8来设置来设置)。 n相关概念:相关概念:数据栈指针数据栈指针SP:最后一个写入栈的数据的内存地址;:最后一个写入栈的数据的内存地址;数据栈基地址:数据栈的最高地址;数据栈基地址:数据栈的最高地址;数据栈界限:可使用的最低的地址单元;数据栈界限:可使用的最低的地址单元;已占用的数据栈:基地址和已占用的数据栈:基地址和SP之间的内存区域;之间的内存区域;未占用的数据栈:未占用的数据栈:SP和数据栈界限之间的内存区域;和数据栈界限之间的内存区域;数据栈中的数据帧:为子程序分配的用来保存寄存器和数据栈中的数据帧:为子程序分配的用来保存寄存器和局部变量的区域。局部变

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论