ARM资料汇编2003
- 格式:doc
- 大小:884.00 KB
- 文档页数:9
ARM平台下的反汇编目的作为代码插桩过程的前提,首先需要对于所提供的二进制代码进行必要的分析,了解ELF文件的结构以及ARM平台的指令编码,将二进制01码翻译成为用户可读的汇编代码。
通过对于汇编代码的分析,用户可以得到程序应用中各个函数起始地址以及程序各个模块的流程调用等重要信息,为代码插桩提供详细的数据。
经过插桩的代码最后通过再一次汇编的过程输出到目标文件。
因此,正确、快速地进行平台下的反汇编工作显得十分关键。
ARM平台介绍[1-2]ARM(Advanced RISC Machines)是微处理器行业的一家知名企业,设计了大量高性能、廉价、耗能低的RISC(精简指令集计算机)处理器、相关技术及软件。
技术具有性能高、成本低和能耗低等特点。
经历过早期自己设计和制造芯片的不景气之后,公司自己开始不制造芯片,只将芯片的设计方案授权(licensing)给其他公司,由它们来生产,形成了较为独特的盈利模式。
RISC结构优先选取使用频率最高的简单指令,避免复杂指令;将指令长度固定,指令格式和寻地方式种类减少;以控制逻辑为主,不用或少用微码控制等。
ARM处理器在秉承RISC体系优点的基础上,进行了针对嵌入式系统的功能扩展,使得指令更加灵活,处理器性能在嵌入式平台上更加突出。
ARM微处理器的核心结构如下图所示:Figure 1.ARM处理器核心结构示意图[2]数据指令通过数据总线进入到处理器核心,然后在指令被执行之前经由指令解码器翻译。
和所有精简指令集处理器一样,ARM采用了load-store架构,load指令将数据从内存拷贝到寄存器,store指令将数据从寄存器转储到内存,所有的数据处理在寄存器中完成。
ARM处理器是32位的处理器,所有的指令默认将寄存器视为32位的值,因此Sign extend会在数据写入寄存器之前将所有8位或者12位的数值转换为32位的数值。
ARM指令通常有两个源寄存器: Rn, Rm 以及一个目标寄存器,操作数都是从寄存器通过内部总线读取得到。
第一张:ARM相关学习资料。
第二章:学ARM和学单片机一样简单视频教程。
第三张:电子科大嵌入式学习视频和 LINUX上C 语言开发视频教程。
第四张和第五张光盘:国嵌视频教程。
非常详细的教学视频。
第六张、第七张:成都中嵌视频教程。
很好的视频教程,非常适合于初学者。
第八张:ARM基础视频。
第九张光盘:名校视频及相关学习资料。
第十张:中嵌ARM高级班视频
第11张 WINCE 5.0
第12张 WINCE 6.0
第13张 WINCE6.0B
第14张 VS2005
第15张:RedHat9+PCB设计相关资料
第16张:24小时学会Linux
第17张:PB6光盘(WINCE6.0的开发环境)
加上公司配的一张DVD盘,一共18张。
ARM 中常⽤的汇编指令1 处理器内部数据传输指令MSR & MRS⽤于在状态寄存器和通⽤寄存器之间传送数据MRS: 状态寄存器到通⽤寄存器的传送指令。
({R0-R12} <== CPSR,SPSR)MSR: 通⽤寄存器到状态寄存器的传送指令。
MRS:(CPSR,SPSR==>{R0-R12})MOVMOV 指令⽤于将数据从⼀个寄存器拷贝到另外⼀个寄存器,或者将⼀个⽴即数传递到寄存器⾥⾯,使⽤⽰例如下:2 存储器访问指令ARM 不能直接访问存储器,⽐如 RAM 中的数据,⼀般先将要配置的值写⼊到 Rx(x=0~12)寄存器中,然后借助存储器访问指令将 Rx 中的数据写⼊到寄存器中。
指令描述LDR Rd, [Rn , #offset]从存储器 Rn+offset 的位置读取数据存放到 Rd 中STR Rd, [Rn, #offset]将 Rd 中的数据写⼊到存储器中的 Rn+offset 位置LDR 指令LDR 主要⽤于从存储加载数据到寄存器 Rx 中, LDR 也可以将⼀个⽴即数加载到寄存器 Rx中, LDR 加载⽴即数的时候要使⽤“=”,⽽不是“#”。
在嵌⼊式开发中, LDR 最常⽤的就是读取 CPU 的寄存器值。
上述代码就是读取寄存器中的值,读取到的寄存器值保存在 R1 寄存器中,上⾯代码中 offset 是 0,也就是没有⽤到 offset。
STR 指令LDR 是从存储器读取数据, STR 就是将数据写⼊到存储器中LDR 和 STR 都是按照字进⾏读取和写⼊的,也就是操作的 32 位数据,如果要按照字节、半字进⾏操作的话可以在指令“LDR”后⾯加上B 或 H,⽐如按字节操作的指令就是 LDRB 和STRB,按半字操作的指令就是 LDRH 和 STRH。
MRS R0, CPSR @ 将特殊寄存器 CPSR ⾥⾯的数据传递给 R0,即R0=CPSR1MSR CPSR , R0 @ 将 R0 中的数据复制到 CPSR 中,即 CPSR =R01MOV R0, R1 @ 将寄存器 R1 中的数据传递给 R0,即 R0=R1MOV R0, #0X12 @ 将⽴即数 0X12 传递给 R0 寄存器,即 R0=0X1212LDR R0, =0X0209C004 @ 将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004LDR R1, [R0] @ 读取地址 0X0209C004 中的数据到 R1 寄存器中12LDR R0, =0X0209C004 @ 将寄存器地址 0X0209C004 加载到 R0 中,即 R0=0X0209C004LDR R1, =0X20000002 @ R1 保存要写⼊到寄存器的值,即R1=0X20000002STR R1, [R0] @ 将 R1 中的值写⼊到 R0 中所保存的地址中1233 压栈和出栈指令我们通常会在 A 函数中调⽤ B 函数,当 B 函数执⾏完以后再回到 A 函数继续执⾏。
arm 汇编指令ARM汇编指令是一种用于编写ARM处理器程序的语言。
ARM处理器广泛应用于嵌入式系统和移动设备等领域。
ARM汇编指令与x86汇编指令有所不同,它基于RISC(精简指令集计算机)架构。
下面是一些基本的ARM汇编指令:1. 数据传输指令:用于在寄存器之间传输数据。
例如:- mov:将数据从一个寄存器传输到另一个寄存器。
- ldr:将数据从内存传输到寄存器。
2. 算术指令:用于执行加法、减法、乘法和除法等操作。
例如:- add:加法操作。
- sub:减法操作。
- mull:乘法操作。
- div:除法操作。
3. 逻辑指令:用于执行逻辑操作,如与、或、非等。
例如:- and:与操作。
- or:或操作。
- xor:异或操作。
4. 移位指令:用于对数据进行左移、右移或无符号右移。
例如:- lsr:无符号右移。
- asr:带符号右移。
- ror:循环右移。
5. 比较指令:用于比较两个寄存器的值。
例如:- cmp:比较两个寄存器的值,若相等则返回0,否则返回1。
6. 跳转指令:用于改变程序的执行流程。
例如:- b:条件跳转。
- bl:无条件跳转。
- bx:带状态跳转。
7. 循环指令:用于实现循环操作。
例如:- loop:内部循环。
- ldp:外部循环。
8. 调用指令:用于实现函数调用。
例如:- blx:带状态调用。
- bx:不带状态调用。
9. 系统调用指令:用于实现与操作系统交互的功能。
例如:- swi:执行系统调用。
10. 存储器访问指令:用于访问内存数据。
例如:- str:将数据存储到内存。
- ldr:从内存中加载数据。
以上仅为ARM汇编指令的一部分,实际上,ARM汇编指令还有很多其他功能。
为了更好地理解和使用ARM汇编指令,可以参考相关的教程和手册,并进行实际操作。
arm的汇编标准
ARM的汇编语言规范如下:
1. 汇编语句格式:在ARM汇编中,所有标号必须在一行的顶格书写,其后面不要添加“:”,而所有指令均不能顶格书写。
2. 标识符大小写:ARM汇编器对标识符大小写敏感,书写标号及指令时字
母大小写要一致,一个ARM指令、伪指令、寄存器名可以全部为大写字母,也可以全部为小写字母,但不要大小写混合使用。
3. 注释:注释使用“;”,注释内容由“;”开始到此行结束,注释可以在一行的顶格书写。
4. 格式:格式为[标号] <指令条件S> <操作数>[;注释]。
5. 空行和换行:源程序中允许有空行,适当地插入空行可以提高源代码的可读性。
如果单行太长,可以使用字符“”将其分行,“”后不能有任何字符,包括空格和制表符等。
6. 变量和常量:对于变量的设置,常量的定义,其标识符必须在一行的顶格书写。
以上就是ARM汇编的一些规范,供您参考。
如果需要更多信息,建议查阅相关书籍或咨询专业人士。
ARM公司业务模型
ARM体系结构的演化和发展
每一个体系结构上都含有众多的处理器型号,这是在同一体系结构下根据硬件配置和存储器系统的不同而作的进一步细分。
需要注意的是通常我们用来区分ARM 处理器家族的ARM7、ARM9 或ARM10,可能跨越不同的体系结构。
ARM处理器的命名
ARM处理器工作模式
ARM处理器寄存器组
ARM指令举例
SUB r0,r1,#5 ; r0=r1-5
ADD r2,r3,r3, LSL #2 ; r2=r3*5
ANDS r4,r4,#0x20 ; r4=r4 AND 0x20; set flags
ADDEQ r5,r5,r6 ; if EQ, r5=r5+r6
LDR r0,[r1],#4 ; r0 = contents of address pointed to by r1; r1=r1+4
STRNEB r2,[r3,r4] ; if NE contents of byte pointed to by (r3+r4) = r2[7-0]
LDRSH r5,[r6,#8]! ; sign extended r5 = contents of halfword pointed to by (r6+8) and
update r6
STMFD sp!,{..regs..} ; stack registers in list,update sp 三级流水线
流水线互锁(LDM)
32位立即数
在ARM指令中,有三个操作数,目的操作数,第一源操作数,第二源操作数,其中最有意思的就是第二源操作数了。
第二源操作数共有12位,分成两个部分,一个部分占8位,能表示0-255,另外一个部分占4位,表示第一个部分8位数零扩展成32位的右循环移位,0001右循环移位2位,0010右循环移位4位,以此类推,来扩大用12位表示更大的数,但不能表示全部,这就是所谓的8位位图原理。
ARM处理器的汇编语言中,对指令语法格式中的<shifter_operand>的常数表达式有这样的规定:“该常数必须对应8位位图,即常数是由一个8位的常数循环移位偶数位得到的。
”
当第2 个操作数的形式为:#immed_8r常数表达式时,“该常数必须对应8位位图,即常数是由一个8位的常数循环移位偶数位得到的。
”其意思是这样:#immed_8r在芯片处理时表示一个32位数,但是它是由一个8位数(比如:01011010,即0x5A)通过循环移位偶数位得到(1000 0000 0000 0000 0000 0000 0001 0110,就是0x5A通过循环右移2位(偶数位)的到的)。
为什么要有这样的规定?要从指令编码格式来解释。
仔细看表格中的shifter_operand所占的位数:12位。
要用一个12位的编码来表示任意的32位数是绝对不可能的(12位数有2^12种可能,而32位数有2^32种)。
但是又要用12位的编码来表示32位数,怎么办?只有在表示数的数量上做限制,通过编码来实现用12位的编码来表示32位数。
在12位的shifter_operand中:8位存数据,4位存移位的次数。
8位存数据:解释了“该常数必须对应8位位图”。
4位存移位的次数:解释了为什么只能移偶数位。
4位只有16种可能值,而32位数可以循环移位32次(32种可能),那就只好限制:只能移偶数位(两位两位地移,好像一个16位数在移位,16种移位可能)。
这样就解决了能表示的情况是实际情况一半的矛盾。
所以对#immed_8r常数表达式的限制是解决指令编码的第二个操作数位数不足以表示32位操作数的无奈之举,这个可以说是聪明的做法。
因为如果直接用12位数来表示32位操作数,只能表示0 到(2^12-1),大于(2^12-1)的数就没办法表示了。
而且细细想来“8位存数据,4位存移位的次数”,应该是最好的组合了。