ARM指令汇编语言

ARM指令汇编语言
ARM指令汇编语言

ARM经典汇编程序

1冒泡排序的ARM汇编程序ORG 09B0H QUE:MOV R3,#50H QUE1:MOV A,R3 MOV R0,A MOV R7,#0AH CLR 00H MOV A,@R0 Q12:INC R0 MOV R2,A CLR C MOV 22H,@R0 CJNE A,22H,Q13 SETB C Q13:MOV A,R2 JC Q11 SETB 00H XCH A,@R0 DEC R0 XCH A,@R0 INC R0 Q11:MOV A,@R0 DJNZ R7,Q12 JB 00H,QUE1 SJMP $ END

2 ARM汇编希尔排序法对10个带符号数进行排序Code: void shell(int src[],int l,int r){ int ih; r++; for(ih=1;ih<(r-l)/9;ih=ih*3+1); //eax,ih //ebx,il //ecx,ir //edx,cmps _asm{ push eax push ebx push ecx push edx push esi push edi;貌似这堆进栈用处不大哎 mov edi,src mov eax,dword ptr [ih] LIH: cmp eax,0 jna EXIH mov ebx,eax dec ebx LLH: cmp ebx,dword ptr [r] jnb EXLLH mov ecx,ebx mov edx,dword ptr [edi+ecx*4]

LCMP: mov esi,eax dec esi cmp ecx,esi jna EXCMP push ecx sub ecx,eax cmp edx,dword ptr [edi+ecx*4] pop ecx jnb EXCMP push ebx push ecx sub ecx,eax mov ebx,dword ptr [edi+ecx*4] pop ecx mov dword ptr [edi+ecx*4],ebx pop ebx sub ecx,eax jmp LCMP EXCMP: mov dword ptr [edi+ecx*4],edx inc ebx jmp LLH EXLLH: push ecx mov ecx,3 push edx cdq

ARM伪指令详述

1、AREA 语法格式: AREA 段名属性1,属性2,…… AREA伪指令用于定义一个代码段或数据段。其中,段名若以数字开头,则该段名需用―|‖括起来,如|1_test|。 属性字段表示该代码段(或数据段)的相关属性,多个属性用逗号分隔。常用的属性如下:— CODE属性:用于定义代码段,默认为READONL Y。 — DATA属性:用于定义数据段,默认为READWRITE。 — READONL Y属性:指定本段为只读,代码段默认为READONL Y。 — READWRITE属性:指定本段为可读可写,数据段的默认属性为READWRITE。—ALIGN属性:使用方式为ALIGN 表达式。在默认时,ELF(可执行连接文件)的代码段和数据段是按字对齐的,表达式的取值范围为0~31,相应的对齐方式为2表达式次方。—COMMON属性:该属性定义一个通用的段,不包含任何的用户代码和数据。各源文件中同名的COMMON段共享同一段存储单元。 一个汇编语言程序至少要包含一个段,当程序太长时,也可以将程序分为多个代码段和数据段。 使用示例: AREA Init,CODE,READONL Y 指令序列 ;该伪指令定义了一个代码段,段名为Init,属性为只读 2、ALIGN 语法格式: ALIGN {表达式{,偏移量}} ALIGN伪指令可通过添加填充字节的方式,使当前位置满足一定的对其方式|。其中,表达式的值用于指定对齐方式,可能的取值为2的幂,如1、2、4、8、16等。若未指定表达式,则将当前位置对齐到下一个字的位置。偏移量也为一个数字表达式,若使用该字段,则当前位置的对齐方式为:2的表达式次幂+偏移量。 使用示例: AREA Init,CODE,READONL Y,ALIEN=3 ;指定后面的指令为8字节对齐。 指令序列 END 3、CODE16、CODE32 语法格式: CODE16(或CODE32) CODE16伪指令通知编译器,其后的指令序列为16位的Thumb指令。 CODE32伪指令通知编译器,其后的指令序列为32位的ARM指令。 若在汇编源程序中同时包含ARM指令和Thumb指令时,可用CODE16伪指令通知编译器其后的指令序列为16位的Thumb指令,CODE32 伪指令通知编译器其后的指令序列为32位的ARM指令。因此,在使用ARM指令和Thumb指令混合编程的代码里,可用这两条伪指令进行切换,但注意他们只通知编译器其后指令的类型,并不能对处理器进行状态的切换。使用示例: AREA Init,CODE,READONL Y …… CODE32 ;通知编译器其后的指令为32位的ARM指令

ARM的汇编指令讲解

汇编知识点的要求: 1、能看的懂 2、可以做修改 3、不需要用汇编直接编写程序 汇编代码的应用场合: 1、ARM的启动代码必须要汇编,如:uboot最开始初始化硬件的代码 2、内核在最开始初始化的位置。。。。 一、ARM汇编指令的编码格式 1、编码格式 ARM汇编指令编译成机器码以后,机器码的长度是32bits,这32bits的编码有一个固定的格式。不同ARM 汇编指令,编码格式不同。 2、举例 C: if(a==10) a++; else a--;

汇编1: CMP R0, #10; ADDEQ R0,R0,#1 SUBNE R0,R0,#1 汇编2 SUBS R1, R0, #10; //S ---运算的结果会影响条件码标志位:CPSR:NZCV ADDEQ R0,R0,#1 SUBNE R0,R0,#1 提示: 空指令NOP,实际上是占用CPU的时间,但是执行后,没有什么意义。 NOP ---- MOV R0,R0 3、条件码标识 10 -10 Z = 1 C = 0 N = 0 V = 0 ================================================================================= 二、ARM的寻址方式 1、立即数寻址 操作数,有立即数。 ADD R0,R0,#1

MOV R1,#10 ORR R1,R1,#0xf @ R1=R1 | 0xf BIC R1,R1,#0xf @R1 = R1&(~(0xf)) 错误: ADD R1,#1,#2 注意:立即数合法的条件 在ARM汇编指令中,并不是所有的立即数,立即数是有一定的限制的。 什么样的立即数是合法的??? 1、如果一个立即数是小于256的(即该立即数是8bits以内的,0~255),该立即数是合法的。 2、如果一个立即数是大于等于256,该立即数经过循环左移偶数位,可以得到一个小于256的数,则该立即数合法。 256 = 0x100 ------→左移20位0x10000000----→左移4 0x1 合法 0x111 非法 0x102 非法 0x104 合法 0xfff 0xff00 0x12000 0x450000 0xab 原因: 在数据处理指令编码的时候,立即数用12bits来表示: 高4bits:循环左移左移偶数位除以2 低8bits:循环左移后的结果。 重要问题: ADD R1,R0,#0xffff 非法 解决: LDR R2,=0xffff // R2=0xffff,将立即数0xffff的值传送给R2 ADD R1, R0, R2 2、寄存器寻址 所有的操作数都是寄存器,没有立即数 ADD R0,R0,R1 MOV R1,R0 ORR R1,R1,R0 @ R1=R1 | 0xf BIC R1,R1,R0 @R1 = R1&(~(0xf))

ARM汇编语言源程序格式

ARM汇编语言源程序格式ARM汇编语言源程序格式2010-11-16 13:52 来源:MCU嵌入式领域 常用ARM源程序文件类型 汇编语言程序的结构1 汇编语言程序的结构2 汇编语言程序的结构3 汇编语言程序的结构4 ARM的汇编语言程序一般由几个段组成,每个段均由AREA伪操作定义。 段可以分为多种,如代码段、数据段、通用段,每个段又有不同的属性,如代码段的默认属性为READONLY,数据段的默认属性为READWRITE。 本程序定义了两个段,第一个段为代码段codesec,它在存储器中存放用于程序执行的代码以及main函数的本地字符串;第二个段为数据段constdatasec,存放了全局的字符串,由于本程序没有对数据进行写操作,该数据段定义属性为READONLY。 汇编语言的行构成1 格式: [标签]指令/伪操作/伪指令操作数[;语句的注释] 所有的标签必须在一行的开头顶格写,前面不能留空格,后面也不能跟C 语言中的标签一样加上":";

ARM汇编器对标识符的大小写敏感,书写标号及指令时字母的大小写要一致; 注释使用";"符号,注释的内容从";"开始到该行的结尾结束 汇编语言的行构成2 标签 标签是一个符号,可以代表指令的地址、变量、数据的地址和常量。 一般以字母开头,由字母、数字、下划线组成。 当符号代表地址时又称标号,可以以数字开头,其作用范围为当前段或者在下一个ROUT伪操作之前。 指令/伪操作 指令/伪操作是指令的助记符或者定义符,它告诉ARM的处理器应该执行什么样的操作或者告诉汇编程序伪指令语句的伪操作功能。 汇编语言的标号1 标号代表地址。 标号分为段内标号和段外标号。段内标号的地址值在汇编时确定,段外编号的地址值在链接时确定。 在程序段中,标号代表其所在位置与段首地址的偏移量。根据程序计数器(PC)和偏移量计算地址即程序相对寻址。 在映像中定义的标号代表标号到映像首地址的偏移量。映像的首地址通常被赋予一个寄存器,根据该寄存器值与偏移量计算地址即寄存器相对寻址。 例如:

伪指令

A51汇编解释---伪指令 2011-05-11 17:51:46| 分类:默认分类| 标签: |举报 |字号大 中 小订阅 一:定义符号的伪指令 1)SEGMENT 格式: 段名符号 SEGMENT 段类型 [再定位类型] SEGMENT指令可声明一个可再定位(区别于CSEG,DSEG,XSEG,BSEG,ISEG等定义的在相对应的空间固定地址定义的绝对段—在连接的过程中不允许重新定位)的段符号和一个可选的再定位类型,段符号可以用来定义段,L51连接器可将多个模块内的具有相同段名和再定位类型的几个段合成为一个段.段类型说明了段所处的地址空间. 如果是编写的汇编程序要与C源程序接口,即被C源程序调用,则全部的汇编子程序所命名的定义的代码段的段名必须是可用SEGMENT来定义的,而且名字的命名的方法也应该参照C51编译器产生的局部段的段名的转换规则.段名的作用主要是在汇编的时候用RSEG来激活的,在连接定位的时候用到的.与段名相应的是用于存储和传递参数的别名,可以在汇编源程序中直接应用局部段的别名,这个别名主要是在传递函数参数的时候用的.在汇编程序中要用PUBLIC 声明被其他模块引用的全局符号. DATA (可直接寻址的内部RAM空间) IDATA (可间接寻址的内部RAM空间) XDATA (外部数据存储空间) BIT (内部RAM低地址区的可位寻址的空间) CODE (程序存储器空间) 可选的再定位类型定义了L51连接时的定位方式,再定位类型: UNIT:定义一个可开始于任一单元的段对于BIT型的段,一个单元是一个位, 其它所有的段一个单元是一个字节. PAGE:定义一个起始地址必须是256的整数倍的段,段的绝对地址由L51自己计算,该类型只允许用于XDATA和CODE类型段. INPAGE:定义一个由L51连接后必须包含在256B的块中,只适用于XDATA和CODE段. INBLOCK:定义一个L51连接后必须包含在2KB中的段,只适用于CODE段. OVERLAYABLE:定义一个可与其他段交叠的覆盖段,其段名符号必须按C51或者PL/M51的规则命名.C51把局部数据段和局部位段定义成?DT?FUNCTIONNAME?MODULENAME 和?BI?FUNCTIONNAME?MODULENAME这是在small模式下.其他的模式略有不同。BITADDRESSABLE:定义一个L51连接后位于可位寻址的区,段长不能超过16B. 2) EQU 格式: 符号名 EQU 表达式 符号名 EQU 寄存器名 EQU伪指令定义一表示数值或寄存器的符号,该符号可用于表达式或助记符指令的操作数,EQU指令定义的符号不能被改变或重新定义,其段类型取决于表达式中的操作数类型类型,无类型的EQU符号可用于任何表达式中. LIMIT EQU 200 VALUE EQU LIMIT-100+’A’

ARM汇编伪指令宏的用法详解_MACRO-MEND_.

ARM 汇编伪指令宏的用法详解(MACRO-MEND 宏是一段独立的程序代码,它是通过伪指令定义的,在程序中使用宏指令即可调用宏。当程序被汇编时,汇编程序将对每个调用进行展开,用宏定义取代源程序中的宏指令。 MACRO 、MEND 语法格式: MACRO [$ label] macroname{ $ parameter1, $ parameter,…… } 指令序列 MEND MACRO 伪操作标识宏定义的开始,MEND 标识宏定义的结束。用MACRO 及MEND 定义一段代码,称为宏定义体,这样在程序中就可以通过宏指令多次调用该代码段。 其中, $ label在宏指令被展开时,label 会被替换成相应的符号,通常是一个标号。在一个符号前使用$表示程序被汇编时将使用相应的值来替代$后的符号。 macroname 为所定义的宏的名称。 $parameter为宏指令的参数。当宏指令被展开时将被替换成相应的值,类似于函数中的形式参数,可以在宏定义时为参数指定相应的默认值。 宏指令的使用方式和功能与子程序有些相似,子程序可以提供模块化的程序设计、节省存储空间并提高运行速度。但在使用子程序结构时需要保护现场,从而增加了系统的开销,因此,在代码较短且需要传递的参数较多时,可以使用宏汇编技术。首先使用MACRO 和MEND 等伪操作定义宏。包含在 MACRO 和 MEND 之

间的代码段称为宏定义体,在MACRO 伪操作之后的一行声明宏的原型(包含宏名、所需的参数),然后就可以在汇编程序中通过宏名来调用它。在源程序被汇编时,汇编器将宏调用展开,用宏定义体代替源程序中的宏定义的名称,并用实际参数值代替宏定义时的形式参数。 宏定义中的$label是一个可选参数。当宏定义体中用到多个标号时,可以使用类似$label.$internallabel的标号命名规则使程序易读。 MACRO 、 MEND 伪操作可以嵌套使用。 使用示例: MACRO $HandlerLabel HANDLER $HandleLabel ;宏的名称为HANDLER ,有1个参数$HandleLabel $HandlerLabel sub sp,sp,#4 stmfd sp!,{r0} ;decrement sp(to store jump address ;PUSH the work register to stack(lr does not push because it return to original address ;load the address of HandleXXX to r0 ;load the contents(service routine start address of HandleXXX ;store the contents(ISR of HandleXXX to stack ;POP the work register and pc(jump to ISR ldr r0,=$HandleLabel ldr r0,[r0] str r0,[sp,#4] ldmfd sp!,{r0,pc} MEND ;在程序中调用该宏

ARM常用的伪指令

在线学习好工作https://www.360docs.net/doc/b12968758.html,/ ARM常用的伪指令 AREA就是常见的伪指令之一。AREA是声明区域段,数据区,代码区等等。什么是数据段呢?数据段是来定义数据结构体的。格式是AREA test,CODE,READONLY。还有指令CODE16、CODE32,格式就直接写上就是。目的是声明以下是32位还是16位指令,注意不是切换arm和thunmb模式。如果是16位,那就是thunmb指令。 操作:这是之前的,如果在这里做一个声明,CODE32,也就是表示ARM指令。如果这里CODE16,就表示一下代码是16位指令,也就是thunmb指令, 也就是说在编译的时候会按照thunmb指令来进行汇编。大家注意一点,在这里通过这个切换,并不会改变处理器的运行的处理模式。不会把ARM指令状态切换为thunmb指令状态。这个切换是在状态寄存器里面去切换T。这个地方只是告诉汇编器而已,所以并不会更换运行时候的指令切换方式。 entry:entry伪指令用于指定汇编程序的入口点。在一个完整的汇编程序中至少要一个entry(也可以多个,当有多个entry时,程序的真正入口点由链接器指定),但在一源文件里最多只能有一个entry(可以没有)。 END:END伪指令用于通知编译器已经到了源程序的结尾。 EQU:EQU伪指令用于为程序中的常量、标号等定义一个等效的字符名称,类似于c语言的#define。格式是UARTLCON0EQU.0x3FFD00。比方说:SUNDYCON1

EQU0x3200000,我们定义了一个常量,这个常量可以拿来直接用。这里注意一点,我们编译先看一下。这里就出错了。 未知的操作代码。这是怎么回事?汇编这一块,跟自己的汇编器,编译器是有关系的,有时跟ID的环境都有关。在ARM里面,特别ADS里面,他对是否顶头,和Tab要求非常严格。因为我们这里不是一个标准指令,它会看第一个是什么操作码,这里操作码是不识别的,所以这里就出错认不出来。这是应该怎样做呢?首先把SUNDY顶头,就可以知道只是个伪指令。 EXPOET:export伪指令用于程序中声明一个全局的标号,该标号可在其他的文件中引用。export可用GLOBAL代替。标号在程序中区分大小写,weak选项声明其他的同名标号优先于该标号被引用。 IMPORT相当于静态引用。IMPORT伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前源文件中引用,而且无论当前源文件是否引用该标号,该标号都会被加入到当前源文件的符号表中。 EXTERN相当于动态引用。EXTERN伪指令用于通知编译器要使用的标号在其他的源文件中定义,但要在当前的源文件中引用,如果当前源文件实际未引用该标号,该标号就不会被加到当前源文件的符号表中。 GET相当于引用文件。GET伪指令用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理。可以使用INCLUDE代替GET。 RN:RN伪指令用于给一个寄存器定义一个别名。采用这种方式可以方便程序员记忆该寄存器的功能。其中,名称为给寄存器定义的别名,表达式为寄存器的编码。

ARM汇编指令 对比记忆 (整理)

参考资料: 1. Richard Blum,Professional Assembly Language 2. GNU ARM 汇编快速入门,https://www.360docs.net/doc/b12968758.html,/u/31996/showart.php?id=326146 3. ARM GNU 汇编伪指令简介,https://www.360docs.net/doc/b12968758.html,/jb8164/archive/2008/01/22/41661.aspx 4. GNU汇编使用经验,https://www.360docs.net/doc/b12968758.html,/u1/37614/showart_39009 5.html 5. GNU的编译器和开发工具,https://www.360docs.net/doc/b12968758.html,/blog-htm-do-showone-uid-34335-itemid-81387-type-blog.html 6. 用GNU工具开发基于ARM的嵌入式系统,https://www.360docs.net/doc/b12968758.html,/liren0@126/blog/static/32897598200821211144696/ 7. objcopy命令介绍,https://www.360docs.net/doc/b12968758.html,/junhua198310/archive/2007/06/27/1669545.aspx 从网上找到一些关于ARM伪指令的资料,现整理如下: 一. Linux汇编行结构 任何汇编行都是如下结构: [:] [} @ comment [:] [} @ 注释 Linux ARM 汇编中,任何以冒号结尾的标识符都被认为是一个标号,而不一定非要在一行的开始。 【例1】定义一个"add"的函数,返回两个参数的和。 .section .text, “x” .global add @ give the symbol add external linkage add: ADD r0, r0, r1 @ add input arguments MOV pc, lr @ return from subroutine @ end of program 1. LDR LDR R0, =0X3FF5000 ;伪指令,把0X3FF5000这个地址送给R0 LDR R0, 0XFF ; 把立即数0xff送给R0 LDR R0, =&FF ; &相当于0X BIC R0, R0, #%1011 ;.#表示立即数,%表示二进制 LDR R1, =0x3ff5000 ;伪指令 R1=0X3FF5000 LDR R1, 0x3ff5000 ;存储器访问指令 R1= [0x3ff5000] 2. adr与ldr比较 adr r0, InitSystem ; ldr r1, =InitSystem ; 伪指令adr r0,InitSystem 编译时汇编成:sub r0,PC,#offset to InitSystem

ARM汇编伪指令介绍

ARM汇编伪指令介绍 在ARM汇编语言程序中,有一些特殊指令助记符,这些助记符与指令系统的助记符不同,没有相对应的操作码,通常称这些特殊助记符为伪指令,它们所完成的操作称为微操作。伪指令在源程序中的作用是为完成汇编程序作各种准备工作的,这些伪指令仅在汇编过程中起作用,一旦汇编结束,伪指令的使命就完成。 在ARM 的汇编程序中,有如下几种伪指令:符号定义伪指令、数据定义伪指令、汇编控制伪指令、宏指令及其它伪指令。 一、符号定义(Symbol Definition)伪指令 符号定义伪指令用于定义ARM汇编程序中的变量、对变量赋值以及定义寄存器的别名等操作。 常见的符号定义伪指令有如下几种: —用于定义全局变量的GBLA、GBLL和GBLS。 —用于定义局部变量的LCLA、LCLL和LCLS。 —用于对变量赋值的SETA、SETL、SETS。 —为通用寄存器列表定义名称的RLIST。 1.GBLA、GBLL和GBLS 语法格式: GBLA(GBLL或GBLS)全局变量名 GBLA、GBLL和GBLS伪指令用于定义一个ARM程序中的全局变量,并将其初始化。 其中: GBLA伪指令用于定义一个全局的数字变量,并初始化为0; GBLL伪指令用于定义一个全局的逻辑变量,并初始化为F(假); GBLS伪指令用于定义一个全聚德字符串变量,并初始化为空; 由于以上三条伪指令用于定义全局变量,因此在整个程序范围内变量名必须唯一。 使用示例: GBLA Test1:定义一个全局的数字变量,变量名为Test1 Test1 SETA 0xaa:将该变量赋值为0xaa GBLL Test2:定义一个全局的逻辑变量,变量名为Test2 Test2 SETL {TRUE};将该变量赋值为真 GBLS Test3:定义一个全局的字符串变量,变量名为Test3

arm汇编快速入门

ARM汇编语言 ARM汇编语言源程序语句,一般由指令,伪操作,宏指令和伪指令作成. ARM汇编语言的设计基础是汇编伪指令,汇编伪操作和宏指令. 伪操作,是ARM汇编语言程序里的一些特殊的指令助记符,其作用主要是为完成汇编程序做各种准备工作,在源程序运行汇编程序处理,而不是在计算机运行期间有机器执行.也就是说,这些伪操作只是汇编过程中起作用,一旦汇编结束,伪操作的使命也就随之消失. 宏指令,是一段独立的程序代码,可以插在程序中,它通过伪操作来定义,宏在被使用之前必须提前定义好,宏之间可以互相调用,也可自己递归调用.通过直接书写宏名来使用宏.并本具宏指令的格式输入输出参数.宏定义本身不产生代码,只是在调用它时把宏体插入到原程序中.宏与C语言中的子函数形参和实参的调用相似,调用宏时通过实际的指令来代替宏体实现相关的一段代码,但宏的调用与子程序的调用有本质的区别,既宏并不会节省程序的空间,其优点是简化程序代码,提高程序的可读性以及宏内容可以同步修改. 伪操作,宏指令一般与编译程序有关,因此ARM汇编语言的伪操作,宏指令在不同的编译环境下有不同的编写形式和规则. 伪指令也是ARM汇编语言程序里的特殊助记符,也不在处理器运行期间由机器执行,他们在汇编时将被合适的机器指令代替成ARM或Thumb指令,从而实现真正的指令操作. 目前常用的ARM编译环境有2种.

1. ADS/SDT IDE:ARM公司开发,使用了CodeWarrior公司的编译器. 2. 集成了GNU开发工具的IDE开发环境;它由GNU的汇编器as,交叉汇编器gcc和连接器id组成. ADS编译环境下的ARM伪操作和宏指令,可参考北航出版社的<

ARM伪指令

AREA伪指令 此伪指令用于给一段汇编代码或数据段起一个名字.一个完整的汇编程序至少要有一个以上的代码段,其语法格式为 AREA 段名属性1,属性2,.... 例: AREA init CODE,READONLY 定义了段名为init的属性为只读的代码. 其用意主要是当代码比较长时,可以根据功能来划分代码段,增加程序的可读性.所以段名的命名要符合该程序段的功能,换句话说也就是让人一看段名就知道该程序段是干什么用的. 2. EQU伪指令 EQU(equal 相等的意思,EUQ两边具有等价关系,通俗的说就是给一个表达式,为什么要给表达式名字,一是表达式太长了不好记忆,二是该表达式用得比较多,方便修改.想当与C语言里的符号常量.语法格式: 名字 EQU 表达式 ;表达式可以是常量 例: Number EQU 50 实际上我们在ARM里用得比较多的是: GPFCON EUQ 0x56000050 因为寄存器名和其对应的地址都是系统设计好了的.所以在这里几是想当与将寄存器名和它对应的地址之间的关系建立起来.这样就可以直接通过寄存器名来访问该寄存器了. 3 EXPORT伪指令 在程序里我们常常要定义很多标号,但那些标号只能在本文件中使用,通常一个工程包含很多个文件,要想在别的文件中使用该文件定义的标号就必须使用EXPORT伪指令.含义就是定义一个全局标号,语法格式: EXPORT 标号 例: EXPORT LOOP1

4 IMPORT伪指令 语法格式为: IMPORT 标号 起含义通知编译器此标号在别的文件定义,但在此文件中要使用.一个比较常用的用法是在汇编语言调用C函数时: AREA Init,CODE,READONLY IMPORT Main ;通知编译器当前文件要引用标号Main,但Main在其他源文件中定义 镲 END 5 GET伪指令 相当C语言的INCLUDE指令,语法格式为: GET 文件名 例:GET a1.s ;通知编译器源文件a1.s被包含当前源文件. 作用用于将一个源文件包含到当前的源文件中,并将被包含的源文件在当前位置进行汇编处理,但注意GET伪指令只能用于包含源文件,包含目标文件需要使用INCBIN. 伪指令 6 INCBIN INCBIN伪指令用于将一个目标文件或数据文件包含到当前的源文件中,被包含的文件不作任何变动的存放在当前文件中,编译器从其后开始继续处理 语法格式: INCBIN 文件名 INCBIN a1.dat ;通知编译器当前源文件包含文件a1.dat

ARM汇编语言和C_C_语言混合编程的方法_史斌

嵌入式技术 电 子 测 量 技 术 ELECT RO NIC M EA SU REM EN T T ECHN O LO G Y 第29卷第6期 2006年12月  ARM汇编语言和C/C++语言混合编程的方法 史斌 (天津大学电子信息工程学院天津300072) 摘 要:文中首先对在嵌入式系统设计中广泛应用的A RM系列微处理器做了简要介绍;接着详细阐述了基于A RM 核的嵌入式微处理器的汇编语言和C/C++语言混合编程的方法:包括代码简洁而功能有限的在线汇编技术和功能强大、基于模块化设计的A T PCS规则;最后给出了详细的示例代码和分析。 关键词:嵌入式系统;A RM;汇编语言;在线汇编;A T PCS规则 Programming of ARM with both assembly and C/C++language Shi Bin (S chool of Electronic&Information Engin eering Tianjin University,Tianjin300072) A bstract:T his article briefly introduced A RM serial micropro ce sso r,w hich is ex tensiv ely used in embedded sy stem desig n;and then g ave the tw o metho ds of A RM-cor e embedded processor prog ramming with both assembly and C/C++ Language including in-line assembly w hich is co mpact but have so me limits and A T PCS rules w hich are pow erful and mo dularized.A t last,the re is some source code w ith analy sis for demo nstra tion. Keywords:embedded sy stem;A RM;assembly;in-line assembly;A T PCS 0 引 言 A RM是一种高性能、低功耗的32位RISC嵌入式处理器系列。目前在各种嵌入式系统中A RM获得了广泛的应用。 A RM编程可以使用汇编语言和C/C++语言,使用汇编语言编程目标代码效率较高,但较为繁琐,设计大型系统时不易维护;而C/C++语言比较简洁明了,但代码效率即使经过优化,也比汇编语言低,特别是在一些实时性强和需要精细处理的场合,C/C++语言难以胜任。因此一个折中的办法是:使用C/C++语言写整体框架,而使用汇编语言实现局部模块,这就涉及到汇编语言和C/C ++语言混合编程的问题。为此本文介绍了在ADS中常用的2种汇编语言和C/C++语言混合编程方法:在线汇编(in-line assem bly)和AT PCS(A RM-T humb Produce C all S tandard)规则。 1 在线汇编(in-line as sembly) 在线汇编的具体含义就是:在C/C++代码中插入一段汇编代码,以实现某种C/C++无法达到的效果,例如: { INTM SK=0xfffff fff;//屏蔽所有的向量中断, C/C++代码 __asm//插入一段汇编代码 { M RS r0,CPS R;//将状态积存器的内容传递到r0 ORR R0,R0,0x000000C0;//通过或运算将r0的第6,7两位置1,其它位不变 M SR CPSR_c,r0;//将r0的低8位送到CPS R的低8位,以屏蔽FIQ中断 } IN TPND=0xfffff fff;//清除全部中断标志位, C/C++代码 } 因为CPS R是一个物理寄存器,没有存储器的I/O映射,而A RM的C/C++语言使用的是ANSI标准,不像KeilC51那样有诸如sbit和sfr的扩展,所以访问C PS R的唯一方法就是用汇编语言;通过在C/C++代码中插入一段简短的汇编代码,来实现对CPSR的访问。再比如一些波形发生的场合,需要每隔一段精确的时间向端口送数据,那么C/C++代码经编译后产生的指令数是无法预知的,所以无法实现精确定时,因此就要使用在线汇编。 在线汇编通过__asm关键字实现,一般格式为: ……//C/C++代码 __asm { 指令1;指令2;指令3;…… 89

(完整版)汇编语言中常用的伪指令档

汇编语言中常用的伪指令 分类:软件相关2013-01-23 20:13 515人阅读评论(0) 收藏举报areaequ伪指令常用汇编语言 汇编语言中,指令语句在源程序汇编时会产生可供计算机执行的指令代码,即目标代码。汇编程序除指令语句外,还需要提供一些指令,用于辅助源程序的汇编。比如指定程序或数据存放的起始地址,为数据分配一段连续的内存单元等。这些指令在汇编时并不生成目标代码,不影响程序执行,因此称之为伪指令。本文简单总结了常用的伪指令,如下。 1、EQU(Equate) 一般格式为:标号:EQU 操作数 指令功能为将操作数赋予标号,两边的值完全相等。使用EQU伪指令给一个标号赋值后,此标号在整个源文件中值固定。 AREA: EQU 1000H ;将标号AREA赋值为1000H 2、ORG(Origin) 一般格式为:ORG xxxxH(绝对地址或标号) XxxxH决定此语句后第一条指令(或数据)的地址。该段源程序或数据被连续存放在此后的地址内,直到下一条ORG指令为止。 ORG 8000H ;此后目标代码存储在存储器中以0x8000h开始的地址空间中。 ADD R1,#1 MOV R2, #2 3、DB(Define Byte) 一般格式为:标号:DB 字节常数或字符或表达式 标号字段可有可无,字节常数或字符是指一个字节数据。此伪指令的功能是把字节常数或字节串存放至内存连续的地址空间中。 ORG 8000H DATA1:DB 43H,09H,08H DATA2:DB 07H 伪指令DB指定了43H,09H,08H 顺序存放在8000H开始的存储单元中,DATA2中的07H紧挨着DATA1的地址空间存放,即07H存放在8003H单元中。 注:DW(Define Word)指令定义与DB类似,区别在于DW定义一个字,DB定义一个字节。

ARM汇编实验报告

《嵌入式系统原理与应用B》课程实验报告 ARM汇编语言编程与调试 要求完成的主要实验 1、给出的数据中寻找最大、最小数问题 2、两种求和运算的编程与调试 3、第四章作业第9题 4、排序冒泡程序的调试与总结 5、第四章作业第11题 说明:标注完成的实验,未完成的给予说明 专业名称:通信工程 班级:1510班 学生姓名:石龙飞 学号(8位):03151307 指导教师:刘钊远

给出的数据中寻找最大、最小数问题 一、实验目的 1、学习汇编软件的安装、使用,熟悉汇编环境。 2、学会使用汇编软件,如何新建一个工程,如何书写源代码,如何进行链接、编译,以及如何调试。 3、尝试一些简单的指令,学会用汇编指令写一些简单的程序。 二、实验内容 编写一个汇编程序,要求在给定的一组数中找到最大数和最小数。 三、实验主要步骤 1、首先建立一个工程 2、再新建.s的源文件,添加到工程中 3、编写源代码,这里主要是实现在一组数中寻找最大数和最小数,最后将找到的两个数放到相应的寄存器中。

4、进行链接编译,看看有没有语法的错误,如果有错误编译器会提示错误的类型以及在哪里出错。 5、进行debug调试,查找代码中的逻辑错误,若无逻辑错误,可在debug界面查看运行结果,其最需要的关注的几个地方是菜单栏的一组运行按钮、源码执行的步骤以及断点、左边的寄存器状态、下方的存储器状态,将这些综合起来,就可以很明确的回到程序如何运行,运行结果如何。

四、实验代码

五、实验总结与分析 1、实验结果分析 其中用红色方框框起来的是最后程序运行的结果,也就是在R3中保存了最小数在R2中保存了最大数,完成了实验要求。 2、在用汇编语言编程之前首先要看看有没有汇编软件ADS、没有的话需要安装,WindowsXP安装起来比较简单,只需要点击setup,一直点击写一部就可以,但是如果是Windows 7或者更高版本的话就需要在setup的属性里点击兼容WindowsXP,运行时以管理员身份运行才能正确进行安装。

ARM GNU 汇编伪指令简介,编译器和开发工具,用GNU工具开发基于ARM的嵌入式系统

ARM GNU 汇编伪指令简介 1 ARM GNU 汇编伪指令简介 (1)abort .abort 停止汇编 (2)align .align absexpr1,absexpr2 以某种对齐方式,在未使用的存储区域填充值. 第一个值表示对齐方式,4, 8,16或 32. 第二个表达式值表示填充的值 (3)if...else...endif .if .else .endif: 支持条件预编译 (4)include .include "file": 包含指定的头文件, 可以把一个汇编常量定义放在头文件中 (5)comm .comm symbol, length: 在bss段申请一段命名空间,该段空间的名称叫symbol, 长度为length. Ld连接器在连接会为它留出空间 (6)data .data subsection: 说明接下来的定义归属于subsection数据段 (7)equ .equ symbol, expression: 把某一个符号(symbol)定义成某一个值(expression).该指令并不分配空间 (8)global .global symbol: 定义一个全局符号, 通常是为ld使用 (9)ascii .ascii "string": 定义一个字符串并为之分配空间 (10)byte .byte expressions: 定义一个字节, 并为之分配空间 (11)short

.short expressions: 定义一个短整型, 并为之分配空间 (12)int .int expressions: 定义一个整型,并为之分配空间 (13)long .long expressions: 定义一个长整型, 并为之分配空间 (14)word .word expressions: 定义一个字,并为之分配空间, 4 bytes (15)macro/endm .macro: 定义一段宏代码, .macro表示代码的开始, .endm表示代码的结束, .exitm 跳出宏, 示例如下: .macro SHIFTLEFT a, b .if \b < 0 mov \a, \a, ASR #-\b .exitm .endif mov \a, \a, LSL #\b .endm (16)req name .req register name: 为寄存器定义一个别名 (17)code .code [16|32]: 指定指令代码产生的长度, 16表示Thumb指令, 32表示ARM指令(18)ltorg .ltorg: 表示当前往下的定义在归于当前段,并为之分配空间 2 ARM GNU专有符号 (1)@ 表示注释从当前位置到行尾的字符. (2)# 注释掉一整行. (3); 新行分隔符. 3 操作码 (1)NOP: nop 空操作, 相当于MOV r0, r0

ARM汇编语言程序设计总结

1.存储器访问指令 LDR STR LDR Load 32-bit word to Memory. Syntax LDR{cond} Rd, [Rn] LDR{cond} Rd, [Rn, offset] LDR{cond} Rd, [Rn, offset]! LDR{cond} Rd, label LDR{cond} Rd, [Rn], offset Description LDR{cond} Rd, [Rn] (zero offset) Rn is used as address value. LDR{cond} Rd, [Rn, offset] (Pre-indexed offset) Rn and offset are added and used as address value. LDR{cond} Rd, [Rn, offset]{!} (Pre-indexed offset with update) Rn and offset are added and used as address value. The new address value is written to Rn. LDR{cond} Rd, label (Program-relative) The assembler calculates the PC offset and generates LDR{cond} Rd, [R15, offset]. LDR{cond} Rd, [Rn], offset (Post-indexed offset) Rn is used as address value. After memory transfer, the offset is added to Rn. Example LDR R8,[R10] //loads r8 from the address in r10. LDRNE R2,[R5,#960]! //(conditionally) loads r2 from a word 960 bytes above the address in r5, and increments r5 by 960. LDR R0,localdata //loads a word located at label localdata STR Store register 32-bit words to Memory. The address must be 32-bit word-aligned. Syntax STR{cond} Rd, [Rn] STR{cond} Rd, [Rn, offset] STR{cond} Rd, [Rn, offset]! STR{cond} Rd, label

相关文档
最新文档