嵌入式系统基础教程第11讲第5章ARM汇编语言程序标准和范例.ppt
《嵌入式系统基础教程第11讲第5章ARM汇编语言程序标准和范例.ppt》由会员分享,可在线阅读,更多相关《嵌入式系统基础教程第11讲第5章ARM汇编语言程序标准和范例.ppt(83页珍藏版)》请在三一办公上搜索。
1、嵌入式系统原理与开发,第11讲南京大学计算机系 俞建新主讲,2008年春季,2008年10月23日,南京大学计算机系,2,第5章 ARM指令集和汇编语言程序,本章主要介绍以下内容:ARM指令集的基本特点与Thumb指令集的区别与x86处理器的区别ARM指令格式ARM寻址方式ARM指令集分类详解ARM汇编语句格式和程序格式ARM汇编语言的指示符ARM汇编程序标准与规范典型ARM汇编语言程序举例,2008年10月23日,南京大学计算机系,3,本讲主要参考文献,ARM公司英文资料:ADS_AssemblerGuide_B.pdfDDI0100E_ARM_ARM.pdf中文图书ARM体系结构与编程,清
2、华大学出版社嵌入式系统基础教程,机械工业出版社,2008年10月23日,南京大学计算机系,4,讲授内容,ATPCS 和AAPCS规范要点ARM编译器保有的特定关键字典型ARM汇编语言程序举例ARM汇编程序基本结构C程序和CPP程序调用ARM汇编子程序ARM汇编程序调用ARM汇编子程序整数除法子程序S3C44B0X处理器的启动代码44BInit.s、option.s、memcfg.s,2008年10月23日,南京大学计算机系,5,5.7 ARM汇编程序规范,寄存器的使用规则堆栈使用规则参数传递规则,2008年10月23日,南京大学计算机系,6,ATPCS,ATPCS(ARM-Thumb Proc
3、edure Call Standard)规定了一些子程序间调用的基本规则,这些规则包括子程序调用过程中寄存器的使用规则,数据栈的使用规则,参数的传递规则。有了这些规则之后,单独编译的C语言程序就可以和汇编程序相互调用。使用ADS的C语言编译器编译的C语言子程序满足用户指定的ATPCS类型。而对于汇编语言来说,则需要用户来保证各个子程序满足ATPCS的要求。,2008年10月23日,南京大学计算机系,7,AAPCS,2007年ARM公司正式推出了AAPCS标准ARM Archtecture Procedure Call StandardAAPCS是ATPCS的改进版目前,AAPCS和ATPCS都
4、是可用的标准,2008年10月23日,南京大学计算机系,8,寄存器的使用规则,子程序间通过寄存器R0R3来传递参数。这时,寄存器R0R3可记作a0a3。被调用的子程序在返回前无需恢复寄存器R0R3的内容。在子程序中,使用寄存器R4R11来保存局部变量。这时,寄存器R4R11可以记作v1v8。如果在子程序中使用了寄存器v1v8中的某些寄存器,则子程序进入时必须保存这些寄存器的值,在返回前必须恢复这些寄存器的值。在Thumb程序中,通常只能使用寄存器R4R7来保存局部变量。寄存器R12用作过程调用中间临时寄存器,记作IP。在子程序之间的连接代码段中常常有这种使用规则。,2008年10月23日,南京
5、大学计算机系,9,寄存器的使用规则(续),寄存器R13用作堆栈指针,记作SP。在子程序中寄存器R13不能用作其他用途。寄存器SP在进入子程序时的值和退出子程序时的值必须相等。寄存器R14称为连接寄存器,记作LR。它用于保存子程序的返回地址。如果在子程序中保存了返回地址,寄存器R14则可以用作其他用途。寄存器R15是程序计数器,记作PC。它不能用作其它用途。,2008年10月23日,南京大学计算机系,10,堆栈使用规则,ATPCS规定堆栈为FD类型,即满递减堆栈,并且对堆栈的操作是8字节对齐。对于汇编程序来说,如果目标文件中包含了外部调用,则必须满足下列条件:(1)外部接口的堆栈必须是8字节对齐
6、的。(2)在汇编程序中使用PRESERVE8伪指令告诉连接器,本汇编程序数据是8字节对齐的。,2008年10月23日,南京大学计算机系,11,参数传递规则,根据参数个数是否固定,可以将子程序分为参数个数固定的子程序和参数个数可变化的子程序。这两种子程序的参数传递规则是不一样的。,2008年10月23日,南京大学计算机系,12,参数个数可变子程序参数传递规则,对于参数个数可变的子程序,当参数个数不超过4个时,可以使用寄存器R0R3来传递参数;当参数超过4个时,还可以使用堆栈来传递参数。在传递参数时,将所有参数看作是存放在连续的内存字单元的字数据。然后,依次将各字数据传递到寄存器R0,R1,R2和
7、R3中。如果参数多于4个,则将剩余的字数据传递到堆栈中。入栈的顺序与参数传递顺序相反,即最后一个字数据先入栈。,2008年10月23日,南京大学计算机系,13,参数个数固定子程序参数传递规则,如果系统不包含浮点运算的硬件部件,浮点参数会通过相应的规则转换成整数参数(若没有浮点参数,此步省略),然后依次将各字数据传送到寄存器R0R3中。如果参数多于4个,将剩余的字数据传送堆栈中,入栈的顺序与参数顺序相反,即最后一个字数据先入栈。在参数传递时,将所有参数看作是存放在连续的内存字单元的字数据。,2008年10月23日,南京大学计算机系,14,子程序结果返回规则,子程序中结果返回的规则如下:结果为一个
8、32位整数时,可以通过寄存器R0返回;结果为一个64位整数时,可以通过寄存器R0和Rl返回;结果为一个浮点数时,可以通过浮点运算部件的寄存器f0、d0或s0来返回;结果为复合型浮点数(如复数)时,可以通过寄存器f0fn或d0dn来返回;对于位数更多的结果,需要通过内存来传递。,2008年10月23日,南京大学计算机系,15,5.7.2 ARM编译器保有的特定关键字,ARM编译器支持一些对ANSI C进行扩展的关键词。这些关键词用于声明变量、声明函数、对特定的数据类型进行一定的限制。,2008年10月23日,南京大学计算机系,16,用于声明函数的关键词(双下划线起头),_asm,内嵌汇编_inl
9、ine,内联展开_irq,声明IRQ或FIQ的ISR_pure,函数不修改该函数之外的数据_softfp,使用软件的浮点连接件_swi,软中断函数_swi_indirect,软中断函数,2008年10月23日,南京大学计算机系,17,用于声明变量的关键词,register声明一个变量,告诉编译器尽量保存到寄存器中。_int64该关键词是long long的同义词。_global_reg将一个已经声明的变量分配到一个全局的整数寄存器中。,2008年10月23日,南京大学计算机系,18,5.8 典型ARM汇编语言程序举例,请参看本课程教材嵌入式系统基础教程中第151页开始的第5.2节。,2008年
10、10月23日,南京大学计算机系,19,5.8.1 条件执行举例,求a和b两整数最大公约数的C程序While a!=b)If(ab)a-=b;else b-=a;,2008年10月23日,南京大学计算机系,20,条件执行举例(续),如果用ARM汇编子程序来实现,就是求r1和r2两个寄存器中的两个整数的最大公约数。使用条件执行指令表示只有以下4句代码:gcdcmp r1,r2;cmp与subs功能类似但不存结果subgtr1,r1,r2;如果r1r2执行此指令subltr2,r2,r1;如果r1r2则转gcd标号注:函数结束时r1=r2,都可以用作返回值。,2008年10月23日,南京大学计算机系
11、,21,5.8.2 32位地址送入一个寄存器中,下面指令段中的load指令根据输入参数决定调用那个函数。具体做法是将函数的绝对地址通过LDR指令存入在r4寄存器中,由于是32的绝对地址,LDR会被解释成以下操作:将函数的绝对地址放入一个文字池(Literal pool,嵌入在代码中的用以存放常数的区域)。产生一条形如:LDR rn pc,#offset to literal pool的指令来将这个绝对地址读入到指定的寄存器中。类似地LDR指令也通过上述方法读入一个32位的绝对数。在下例中,LDR指令将32位绝对数0 x11552634读入到r0寄存器中,用作调用routine1或者routin
12、e2的参数。,2008年10月23日,南京大学计算机系,22,32位地址送入一个寄存器中(续),;void load(int i);void routine1(int 1);void routine2(int 2);AREA LOAD,CODE,READONLYIMPORT routine1IMPORT routine2EXPORT loadloadstmfdr13!,r4,r14ldrr4,=routine1;首先将32位地址存放在附近的区域cmps r0,#1ldrner4,=routine2ldrr0=0 x11552634;函数的第1个int参数bxr4ldmfdr13!,r4,r14
13、bxr14,2008年10月23日,南京大学计算机系,23,5.8.3 从IRQ和FIQ异常处理程序返回,从IRQ和FIQ异常处理程序返回时,返回地址应该是LR-4。有三种不同的编程方法,分别列出如下:返回方式1INT_HANDLERSUBS PC,LR,#4;PC=R14-4,2008年10月23日,南京大学计算机系,24,从IRQ和FIQ异常处理程序返回(2),返回方式2INT_HANDLERSUB R14,R14,#4;R14-=4MOVS PC,LR,2008年10月23日,南京大学计算机系,25,从IRQ和FIQ异常处理程序返回(3),返回方式3INT_HANDLERSUB R14,
14、R14,#4;R14=R14 4STMFD R13!,R0-R3,R14LDMFD R13!,R0-R3,R15,2008年10月23日,南京大学计算机系,26,5.8.4 调用ARM汇编语言子程序,在ARM汇编语言中,子程序调用是通过BL指令完成的。BL指令的语法格式如下:BL subname其中,subname是调用的子程序的名称。BL指令完成两个操作:将子程序的返回地址放在LR寄存器中,同时将PC寄存器值设置成目标子程序的第一条指令地址。在子程序返回时可以通过将LR寄存器的值传送到PC寄存器中来实现。子程序调用时通常使用寄存器R0R3来传递参数和返回结果。,2008年10月23日,南京大
15、学计算机系,27,调用汇编子程序举例,子程序DOADD完成加法运算,操作数放在R0和R1寄存器中,结果放在R0中。AREA EXAMPLE2,CODE,READONLYENTRYstartMOV r0,#10;R0设置输入参数MOV r1,#3;R1设置输入参数BLdoadd;调用子程序doadddoaddADD r0,r0,r1;子程序实体MOVpc,lr;从子程序中返回END,2008年10月23日,南京大学计算机系,28,5.8.5 循环结构,在ARM汇编中,没有专门的指令用来实现循环,一般通过跳转指令加条件码的形式来实现。可以采用比较指令CMP或者减法指令SUB等实现。参看下面的指令段
16、:LOOPADDR4,R4,R0ADDR0,R0,#1CMPR0,R1BLELOOP;R0小于等于R1场合跳转在做完了两次加法操作后,比较R0,R1的值,影响条件标志。最后的条件跳转语句根据CMP指令执行的结果来决定是否进行循环。,2008年10月23日,南京大学计算机系,29,5.8.6 数据块复制示范程序,本程序将数据从源数据区复制到目标数据区复制时,以8个字为单位进行。对于最后所剩不足8个字的数据,以字为单位进行复制,这时程序跳转到copywords处执行。在进行以8个字为单位的数据复制时,保存了所用的8个工作寄存器。程序清单如下面所示。,2008年10月23日,南京大学计算机系,30,
17、数据块复制示范程序(1),;设置本段程序的名称(Block)及属性AREA Block,CODE,READONLY;设置将要复制的字数num EQU 20;标识程序入口点 ENTRYStart;r0寄存器指向源数据区srcLDR r0,=src;r1寄存器指向目标数据区dstLDR r1,=dst,2008年10月23日,南京大学计算机系,31,数据块复制示范程序(2),;r2指定将要复制的字数MOV r2,#num;设置数据栈指针(r13),用于保存工作寄存器数值MOV sp,#0 x400;进行以8个字为单位的数据复制blockcopy;需要进行的以8个字为单位的复制次数MOVS r3,r
18、2,LSR#3;对于剩下不足8个字的数据,跳转到copywords,以字为单位复制BEQ copywords;保存工作寄存器,压栈STMFD sp!,r4r11,2008年10月23日,南京大学计算机系,32,数据块复制示范程序(3),octcopy;从源数据区读取8个字的数据,放到8个寄存器中,并更新目标数据区指针r0LDMIA r0!,r4-r11;将这8个字数据写入到目标数据区中,并更新目标数据区指针r1STMIA r1!,r4-r11;将块复制次数减1SUBS r3,r3,#1;循环,直到完成以8个字为单位的块复制BNE octcopy;恢复工作寄存器值,出栈LDMFD sp!,r4-
19、r11,2008年10月23日,南京大学计算机系,33,数据块复制示范程序(4),copywords;剩下不足8个字的数据的字数ANDS r2,r2,#7;数据复制完成BEQ stopwordcopy;从源数据区读取1个字的数据,放到r3寄存器中,并更新目标数据区指针r0,后索引偏移LDR r3,r0,#4;将这r3中数据写入到目标数据区中,并更新目标数据区指针r1,后索引偏移STR r3,r1,#4,2008年10月23日,南京大学计算机系,34,数据块复制示范程序(5),;将字数减1SUBS r2,r2,#l;循环,直到完成以字为单位的数据复制BNE wordcopy;定义数据区Block
20、DataAREA BlockData,DATA,READWRITE;定义源数据区src及目标数据区dstsrc DCD 1,2,3,4,5,6,7,8,1,2,3,4,5,6,7,8,1,2,3,4dst DCD 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0;结束汇编END,2008年10月23日,南京大学计算机系,35,5.8.7 内嵌汇编,内嵌汇编(inline assembly)的语法如下:_asm指令;指令/*注释*/指令,2008年10月23日,南京大学计算机系,36,内嵌汇编的指令用法,内嵌在C或者C+程序中的ARM汇编指令与普通(ADS)格式的A
21、RM汇编指令有所不同。其主要原因在于C/C+编译器在编译C/C+源代码的同时要兼顾处理内嵌汇编程序,因此CPU的内部寄存器资源使用有额外约束。以下讲解内嵌ARM汇编指令的用法。,2008年10月23日,南京大学计算机系,37,ARM内嵌汇编程序的操作数,内嵌汇编指令中作为操作数的寄存器和常量可以是表达式。这些表达式可以是char,short或int类型,而且这些表达式都是作为无符号数进行操作。若需要带符号,用户需要自己处理与符号有关的操作。编译器将会计算这些表达式的值,并为其分配寄存器。,2008年10月23日,南京大学计算机系,38,ARM内嵌汇编程序的物理寄存器,内嵌汇编程序中使用物理寄存
22、器有以下限制。不能直接向PC寄存器赋值,程序跳转只能使用B或BL指令实现不要使用过于复杂的C表达式,因为将会需要较多的物理寄存器,这将导致与其他指令中用到的物理寄存器产生使用冲突。编译器可能会使用R12或R13存放编译的中间结果,在计算表达式的值时可能会将寄存器R0R3,R12和R14用于子程序调用。因此在内嵌的汇编指令中不要将这些寄存器同时指定为指令中的物理寄存器。通常内嵌的汇编指令中不要指定物理寄存器,因为这可能会影响编译器分配寄存器,进而影响代码的效率。,2008年10月23日,南京大学计算机系,39,其他内嵌汇编程序的编写注意点,常量:在内嵌汇编指令中,常量前面的“#”可以省略。指令展
23、开:内嵌汇编指令中,如果包含常量操作数,该指令可能被内嵌汇编器展开成几条指令。标号:C程序中的标号可以被内嵌的汇编指令使用,但是只有指令B可以使用C程序中的标号,而指令BL则不能使用。内存单元的分配:所有的内存分配均由C编译器完成,分配的内存单元通过变量供内嵌汇编器使用。内嵌汇编器不支持内嵌程序中用于内存分配的伪指令。,2008年10月23日,南京大学计算机系,40,内嵌汇编程序中的SWI和BL指令,SWI和BL指令:在两个指令使用到内嵌汇编中,除了正常的操作数域外,还必须增加以下3个可选的寄存器列表:用于输入参数的寄存器列表。用于存储返回结果的寄存器列表。用于表示那些寄存器将有可能会被修改的
24、寄存器列表。,2008年10月23日,南京大学计算机系,41,内嵌汇编代码举例字符串复制(1),#includevoid str_cpy(const char*src,char*dst)int ch;_asmloop:/普通ARM汇编代码中的标号后面不能跟冒号。C程序中/的标号可以被内嵌的汇编指令使用。ARM内嵌汇编代码中/只有B指令可以使用C的标号,而BL指令不能够使用C代码/的标号。C程序的标号后面跟冒号,由Goto语句转向标号处。LDRBch,src,#1STRBch,dst,#1CMPch,#0BNEloop,2008年10月23日,南京大学计算机系,42,内嵌汇编代码举例字符串复制(
25、2),int main(void)const char*a=Hello world!n;char b20;/do inline assembly routine str_cpy(a,b)_asmMOV R0,a/将串a的串首地址送到R0寄存器MOV R1,b/将串b的串首地址送到R1寄存器BL str_cpy,R0,R1/调用C函数str_cpy()printf(Original string:%sn,a);printf(Copied string:%sn,b);/半主机方式显示复制前后的两个串return(0);,2008年10月23日,南京大学计算机系,43,5.8.8 ARM汇编、C和C
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 嵌入式 系统 基础教程 11 ARM 汇编语言 程序 标准 范例

链接地址:https://www.31ppt.com/p-5395502.html