ARM汇编程序基本知识

ARM汇编程序基本知识

1.汇编程序的基本组成

ARM汇编语言程序中,程序是以程序段为单位组织代码的。段是相对独立的指令或者代码序列,拥有特定的名称。段的种类有代码段、数据段和通用段,代 码段的内容为执行代码,数据段存放代码运行时需要用到的数据,通用段不包含用户代码和数据,所有通用段共用一个空间。段使用AREA伪操作来定义,并且说 明相关属性,如

代码段定义

AREA Init, CODE, READONLY

数据段定义

AREA Stack1,DATA,READWRITE,NOINIT,ALIGN=3

……

一个汇编程序至少应该有一个代码段,可以有零或者多个数据段。在格式上,一个汇编程序需要至少有一个ENTRY(关于ENTRY具体内容看伪操作符ENTRY),还需要在汇编源文件结束处,写上END表示该源文件的结束。

如一个基本的汇编源程序

AREA Init, CODE, READONLY ;定义一个代码段

ENTRY ;标记程序入口点

Start    LDR R0,0x3FF5000 ;标号Start可以要,也可以不要

LDR R1,0Xff

STR R1,[R0]

LDR R0,=0x3FF5000

LDR R1,0x01

STR R1,[R0]

……

END ;END伪操作表示本源文件结束

当汇编程序较长时,可以分割为多个代码段和多个数据段,多个段在程序编译链接时,最终形成一个可执行的映像文件。一个可执行映像文件通常由以下几部分组成

一个或者多个代码段,代码段属性为只读(只读数据也放在代码段?RO)

零个或者多个初始化数据的数据段,可读写(存放初始化了的变量数据,RW)

零个或者多个不包含初始化数据的数据段,可读写(所有未初始化的变量,也就是ZI)

链接器根据系统默认或者用户设定的规则,将各段安排在存储器中的相应位置,因此源程序中段之间的相对位置与可执行映像文件中的段的相对位置一般不会相同。

2.汇编语句应该注意的地方

汇编语句格式

[LABEL] OPERATION, [OPERAND], [;COMMENT]

LABEL必须在一行的开头写。

OPERATION包括指令、伪操作、宏指令或伪指令。每一条操作助记符必须全部大写或者全部小写。在写操作助记符前,必须有空格。

OPERAND 表示操作的对象,可以使常量、变量、标号、寄存器或者表达式,不同的对象之间必须用逗号分开。

例子:

AREA EX2,CODE,READONLY ;操作助记符前面必须有空格

GBLA DATA ;操作助记符前面必须有空格

DATA    SETA,0x20 ;变量名DATA前面不能留空格

ADD R0,R1,R2

ADD R0,R1,r2

add R0,R1,r2

Add R0,R1,r2 ;寄存器小写正确,指令助记符大小写混合错误

3.常用符号

汇编语言中,经常使用各种符号表示变量、常量和地址。

变量的定义:使用伪操作GBLA、GBLL、GBLS,分别是定义全局的数值变量、逻辑变量和字符变量;LCLA、LCLL、LCLS定义局部的数值变量、逻辑变量和字符变量。相应的变量使用SETA、SETL、SETS来进行赋值。注意字符串长度不应超过512个字节。

例子:

GBLA DATA

DATA    SETA 0x20

LCLS str1

str1 SETS “PEN”

LCLL lc

lc SETL {TRUE}

常量是在运行过程中不能改变的量。ARM支持数值常量、逻辑常量和字符串常量。汇编中使用EQU来定义一个数值常量,如

Test EQU 10; 定义标号Test的值为20.

Addr EQU 0x55,CODE32;

关于EQU的具体使用,看伪操作EQU。

数值常量一般为32为的整数,可以使十进制、十六进制,也可以是n进制(n=2~9)如8_247是一个八进制数。

4.常见的伪操作符

符号定义伪操作

GBLA、GBLL、GBLS

LCLA、LCLL、LCLS

SETA、SETL、SETS

RLIST

其中RLIST用来定义通用寄存器列表名称,使用该伪操作定义的名称可以在ARM指令LDM/STM中使用。在LDM/STM中,访问列表中的寄存器次序为寄存器编号由低到高的顺序。如

RegList RLIST {r0-r5,r8,r10}; 将寄存器列表名称定义为RegList

在程序中使用

STMFD SP!, RegList ;存储列表到堆栈

LDMIA R5, RegList ; 加载列表

数据定义伪操作

DCB 分配一片连续的字节存储单元并初始化

DCW(DCWU) 分配一片连续的半字存储单元并初始化

DCD(DCDU) 分配一片连续的字存储单元并初始化

DCDO、DCI、DCQ(DCQU)

DCFS(DCFSU) 为单精度浮点数分配一片连续的字存储单元并初始化

DCFD(DCFDU) 为双精度浮点数分配一片连续的字存储单元并初始化

SPACE 分配一片连续的存储单元

FIELD、MAP、LTORG

如:

Str DCB “this is a test” ;分配一片连续的字节存储单元并初始化

Data DCW 1,2,3 ;分配一片连续的半字存储单元并初始化

Data DCD 4,5,6 ; 分配一片连续的字存储单元并初始化

Fdata DCFS 2e5,-5e-7 ;分配一片连续的字存储单元并初始化为指定的单精度数

Dspce SPACE 100 ;分配连续100字节的存储单元并初始化为0

控制伪操作

IF ELSE ENDIF

WHILE WEND

MACRO MEND;MEXIT

信息报告伪操作

ASSERT

INFO

OPT

其他常用伪操作

AREA ALIGN CODE16/CODE32 ENTRY END EQU EXPORT(GLOBLE) IMPORT EXTERN GET(INCLUDE) INCBIN RN ROUT

AREA

格式:AREA 段名 属性1,属性2,……

常用属性有:

CODE :用于定义代码段,默认为READONLY

DATA: 定义数据段,默认为READWRITE

READONLY: 指定本段为只读

READWRITE: 指定本段为读写

ALIGN: 使用方式为ALIGN表达式。在默认时,ELF(可执行链接文件)的代码段和数据段是按字对齐的。表达式的取值范围为0~31,相应的对齐方式为2次幂。

COMMON: 定义一个通用的段,不包含任何用户的代码和数据。各源文件中同名的COMMON段共享同一段存储单元。

ALIGN

格式:ALIGN [表达式[,偏移量]]

ALIGN伪操作可通过添加填充字节的方式,使当前位置满足一定的对齐方式。

例:

……

DATA1  DCB “STRIN” ; 定义后不能保证地址对齐

ALIGN 4 ;确保当前地址是4字节对齐

……

例:

AREA Cache, CODE, ALIGN=3 ; 指定本代码段的指令时23=8字节对齐的

……

MOV PC, LR ;程序跳转后是4字节对齐,返回后需要继续8字节对齐

ALIGN 8 ;当前位置再次满足8字节对齐

……

注意上面,在AREA中使用和单独使用ALIGN的区别,格式和计算方式不一样。

ENTRY

用于指定汇编程序的入口点。一个程序可以由一个或者多个源文件组成,一个源文件由一个或者多个程序段组成。一个程序至少有一个入口点,也可有多个入 口点,但是在一个源文件中,最多只能有一个ENTRY。当有多个ENTRY时,程序的真正入口点由链接器指定。编译程序在编译连接时根据程序入口点进行连 接。在只有一个入口点时,编译程序会把这个入口点的地址定义为系统复位后的程序起始点。

END

在源文件结束处写上,表示源程序的结尾。

EXPORT

格式:EXPORT 标号 [,WEAK]

声明一个全局标号,该标号在其他文件中可引用。WEAK表示碰上其他同名标号时,其他标号优先。

AREA INIT, CODE, READONLY

EXPORT Stest

……

END

IMPORT

格式:IMPORT 标号 [,WEAK]

表示该引用的标号在其他源文件中,但要在当前文件中引用。WEAK表示找不到该标号时,也不报错,一般讲该标号值置为0,如果是B或者BL使用到,则该指令置为NOP。

与EXTERN的不同的是,无论当前文件是否引用该标号,该标号都被加入当前源文件的符号表中。

AREA INIT, CODE, READONLY

IMPORT MAIN;

……

END

EXTERN

和IMPORT一样,不同之处在于,如果当前文件没有引用该标号,该标号不会加入当前源文件的符号表中。

GETINCLUDE

将一个源文件包含到当前的源文件中,并在当前位置进行编译。

AREA INIT, CODE, READONLY

GET a1.s

GET C:/a2.s

……

END

INCBIN

将一个目标文件或者数据文件包含到当前,文件内容被原封不动的放在当前位置,编译器不对文件内容进行编译。

AREA INIT, CODE, READONLY

GET a1.s ; 包含a1.s并且对a1.s进行编译

INCBIN C:/d.txt ; 包含d.txt,不对内容进行编译

GET a2.s ; 包含a2.s,并对内容进行编译

END

RN

给一个寄存器定义一个别名。

Temp RN, R0 ; 将R0定义一个别名 Temp

ARM汇编程序基本知识

时间: 2024-09-30 15:18:58

ARM汇编程序基本知识的相关文章

ARM汇编基础(1)--ADS1.2安装与第一个ARM汇编程序

前言 最近的工作是与逆向相关, 用到ARM汇编, 以前在大学时学过x86汇编和ARM开发, 自我感觉当时学的还挺好, 很久没用也生疏了. 正好趁着这个机会也复习一下ARM汇编. 关于ARM的介绍和理论知识,此处就不再赘述. 进入正题: 安装ADS1.2 安装过程很简单, 没什么技术含量. 但是, win7可能会碰到卡在100%的问题, 网上有很多解决的办法, 但好像都不管用. 我用XP的虚拟机装的ADS1.2, 在XP系统上安装很顺利. 第一个ARM汇编程序 新建一个工程, 然后再按照一下步骤设

13.ARM协处理器的知识

13.ARM协处理器的知识 在处理器中有协处理器来辅助处理器完成部分功能的,主要是协助作用. 协处理器: 协处理器用于执行特定的处理任务,如:数学协处理器可以控制数字处理,以减轻处理器的负担.ARM可支持多达16个协处理器,其中CP15是最重要的一个. ? 在ARM9.ARM11.cortexa8等核中,CP15的功能都是一样的. 在ARM11核的文档看到图1-1: The section gives an overall view of the system control coprocess

1.ARM的基础知识

ARM简述 ARM公司既不生产芯片也不销售芯片,它只出售芯片技术授权.ARM技术具有很高的性能和功效,因而容易被厂商接受.同时,合作伙伴的增多,可获得更多的第三方工具.制造和软件支持,这又会使整个系统成本降低,让产品进入市场的时间加快,从而具有更大的竞争优势. 一.ARM技术的应用领域及其特点 采用ARM技术IP核的微处理器遍及汽车.消费电子.成像.工业控制.海量存储.网络.安保和无线等各类产品市场. 1.什么是IP核? IP核是指拥有知识产权的控制功能单元.(IP核是一段具有特定电路功能的硬件

ARM各种版本号知识以及型号的发展(三星为例)

1.ARM型号的发展历史 2.单片机.工业上一般使用RTOS(实时操作系统),Linux.Android用在影音娱乐等对实时性要求没那么高的场合: 3.ARM内核版本号和Soc版本号是由ARM确定的,而Soc型号是由半导体公司确定的: 4.Cortex系列ARM产品线分割成了3个系列,这个是市场细分的需要和选择: 5.ARM已经发布了一些64位架构如A53等,主要面向高性能服务器类的应用: 6.ARM下一步重点发展方向是Cortex-M7,特点是低功耗,主要面向物联网终端. 参考来源: 朱有鹏老

ARM总线方面知识

AMBA简介 随着深亚微米工艺技术日益成熟,集成电路芯片的规模越来越大.数字IC从基于时序驱动的设计方法,发展到基于IP复用的设计方法,并在SOC设计中得到了广泛应用.在基于IP复用的SoC设计中,片上总线设计是最关键的问题.为此,业界出现了很多片上总线标准.其中,由ARM公司推出的AMBA片上总线受到了广大IP开发商和SoC系统集成者的青睐,已成为一种流行的工业标准片上结构.AMBA规范主要包括了AHB(Advanced High performance Bus)系统总线和APB(Advanc

linux下的arm汇编程序

1.gnu 的编译环境搭建 解压编译工具,加入环境变量PATH 2.编译相关命令的使用 编译命令 arm-linux-gcc  -g -c -o led.o main.o led.c main.c //了解静态编译和只编译不链接的用法 链接命令 arm-linux-ld -Tled.lds -o led.elf led.o main.o //使用脚本文件led.s进行链接 反汇编命令 arm-linux-objdump -D -S led.elf //若在编译时加上 -g 选项则可以在此处获得更

ARM汇编指令汇总

1.ARM汇编的格式:    在ARM汇编里,有些字符是用来标记行号的,这些字符要求顶格写:有些伪码是需要成对出现的,例如ENTRY和END,就需要对齐出现,也就是说他们要么都顶格,要么都空相等的空,否则编译器将报错.常量定义需要顶格书写,不然,编译器同样会报错.    2.字符串变量的值是一系列的字符,并且使用双引号作为分界符,如果要在字符串中使用双引号,则必须连续使用两个双引号.    3.在使用LDR时,当格式是LDR r0,=0x022248,则第二个参数表示地址,即0x022248,同

ARM Cortex-M底层技术(2)—启动代码详解

杂谈 工作了一天,脑袋比较乱.一直想把底层的知识写成一个系列,希望可以坚持下去.为什么要写底层的东西呢?首先,工作用到了这部分内容,最近和内部Flash打交道比较多,自然而然会接触到一些底层的东西:第二,近些年来Cortex-M阵营各厂商(ST.Nordic.ATMEL……)对新产品的迭代速度越来越快,以及微控制器应用普及程度的加深,越来越多的开发者把更多精力投注在应用层开发上,花在对底层技术上的时间越来越少,更深层次的原因是走嵌入式底层没有做互联网上层赚钱.希望自己可以把嵌入式ARM Cort

如何实现对ARM汇编指令的调试?

学习ARM汇编语言时,少不了对ARM汇编指令的调试.作为支持多语言的调试器,gdb自然是较好的选择.调试器工作时,一般通过修改代码段的内容构造trap软中断指令,实现程序的暂停和程序执行状态的监控.为了在x86平台上执行ARM指令,可以使用qemu模拟器执行ARM汇编指令,具体的调试方法,一起来看看吧. 一.准备ARM汇编程序 首先,我们构造一段简单的ARM汇编程序作为测试代码main.s. .globl _start _start: mov R0,#0 swi 0x00900001 以上汇编指