您的位置 首页 电子

ARM芯片详解翻译

译者注:这篇文章主要介绍了Risc结构的PDA芯片组成和汇编程序,翻译不周,肯定有错误,请多包涵,另外我忘记了出处,这里向作者表示歉意。R…

译者注:这篇文章首要介绍了Risc结构的PDA芯片组成和汇编程序,翻译不周,必定有过错,请多包容,别的我忘记了出处,这儿向作者表示歉意。

RISC处理器被广泛应用在小型设备上,例如PDA,移动电话,智能热水器等。有许多关于RISC处理器的汇编程序,但最常见的仍是ARM
下面我要谈的是ARM7,由于我研讨的是这个。
让咱们先了解一下ARM的架构。ARM处理器包括37个寄存器:31个通用的32位寄存器,以及6个状况寄存器。寄存器的设置取决于处理器状况。ARM状况碑文32位指令,Thumb状况碑文16位指令集。
在ARM状况,有18个寄存器可用:可供直接存储的R0―R15,CPSR(当时程序状况寄存器),SPSR(被存储程序状况)。其间3个可直接存储器被称为服务寄存器。

(R13)SP??仓库指针
(R14)LR??衔接寄存器,用来存储调用进程的函数地址(译注:可简略理解为进程回来地址)。而且,LR并非存储在仓库中-它存在于寄存器中。
(R15)PC??当时指令指针。用一般的mov指令就能够改动它的值,然后碑文它所指向的指令。

在Thumb状况,有13个寄存器可用:R0-R8,R13-R15,CPSR,SPSR

状况的改动,不会影响寄存器内容的改动。
假如想进入Thumb状况,能够先将操作寄存器的状况位设为1(bit1),然后碑文BX指令。假如想进入ARM(译注:原文误为APM)状况,能够先将操作寄存器的状况位设为0(bit0),然后碑文BX指令。
2种状况的指令集是不同的,可是许多指令都是相似的。Thumb指令集长度为2bytes,ARM-4bytes。关于2种状况指令的详细材料能够参阅:http://www.atmel.com/dyn/resources/p…ts/doc0673.pdf
风趣的是许多指令能够一起操作多个寄存器。例如:
ADDR3,SP,#4相当于: R3:=SP+4
或许,用来存储寄存器入栈的指令:
PUSH{R2-R4,R7,LR} 这和x86汇编晒干的pushad指令不同,在ARM汇编晒干,这种将寄存器存入仓库的办法是可行的。
内存中,数据存储办法能够是低位存储(例如Intel寄存器)或许高位存储(例如Motorola寄存器)。所以,写代码时分,有必要指明数据寄存办法。
下面是一些ARM编译器的材料:
http://heanet.dl.sourceforge.net/sou…de-arm-win.exe-GNUcompilerwithallconsequences-allthroughcommandline+debuggingthroughgdb.

http://www.goldroad.co.uk/grARM.html-unpretentiousARMassembler.

http://www.arm.com/support/downloads/index.html-officialtoolsforARM’sdevelpment.Hereyoucanonlybuythem.

http://www.iar.com/-alternativetoIDAforARM.30-daystrialversionisoffered.
下面解说一下由C++的ARM编译器生成的ARM汇编程序。
一般地,剖析不同程序的时分,常常碰到的并不是朴实的汇编语言,而是由C++编译器生成的代码。当然,x86汇编程序员一般不会如此。
函数调用:
这儿不存在函数参数调用约好(例如cdecl,stdcall等)!一切的函数调用约好相似于Borland的fastcall。参数由寄存器传入,假如数目不行,由仓库传入。
例如:
ROM:0001F4E2MOVR0,SP

ROM:0001F4E4MOVR2,*6

ROM:0001F4E6ADDR1,R4,*0

ROM:0001F4E8BLmemcmp
参数的传递次序对应于寄存器编号,R0为第一个,R1为第二个,R2为第三个(译注:比较有意思)。相当于:
intmemcmp(

constvoid*buf1,

constvoid*buf2,

size_tcount

);
buf1=R0

buf2=R1

count=R2

函数回来值被寄存在R0中:
ROM:0001F4E2MOVR0,SP

ROM:0001F4E4MOVR2,*6

ROM:0001F4E6ADDR1,R4,*0

ROM:0001F4E8BLmemcmp

ROM:0001F4ECCMPR0,*0

ROM:0001F4EEBNEloc_1F4F4
下面是一个运用仓库传递参数的比方:
ROM:000BCDECMOVR2,*0

ROM:000BCDEESTRR2,[SP]

ROM:000BCDF0MOVR2,*128

ROM:000BCDF2MOVR3,*128

ROM:000BCDF4MOVR1,*14

ROM:000BCDF6MOVR0,*0

ROM:000BCDF8BLFillBoxColor
上面,R0-R3存储坐标,第5个参数(颜色)被寄存在仓库中。

只要经过剖析才能够确认操作数的数目。咱们能够剖析函数和它的调用部分。有时分,参数信息能够经过对寄存器和仓库的操作观察出来。例如,在Thumb状况下,程序对R0-R7和服务寄存器的操作。所以,假如看到相似于下面的代码:
ROM:00059ADAgetTextBounds

ROM:00059ADAPUSH{R4-R7,LR},
能够以为它的参数被寄存在R0,R1,R2,R3和SP。假如见到:
ROM:0005924EADDR0,SP,*0x14

ROM:00059250ADDR1,SP,*0x6C

ROM:00059252ADDR2,SP,*0x68

ROM:00059254ADDR3,SP,*0x64

ROM:00059256BLgetTextBounds
咱们看到只要R0-R3被运用,便是说只要4个参数被传递过来。

搬运(Transitions)
一般,搬运分为条件搬运和无条件搬运。搬运方针能够寄存在寄存器或许其他处。寄存器搬运一般用于Thumb/ARM状况转化。无条件短搬运指令为B(branch)指令。长跳转指令-BX(交流搬运)。函数调用选用BL(衔接搬运),且调用时将回来地址存入LR寄存器。当然,改动PC寄存器内容也能够改动搬运地址:
ADDPC,*0x64
可是C编译器一般不这样处理,它们在搬运的时分,只是以写入指令改动PC寄存器。

分支(Branches)
也称为转化,一般用法如下:
ROM:0027806ECMPR2,*0x4D;M

ROM:00278070BCSloc_27807A

ROM:00278072ADRR3,word_27807C

ROM:00278074ADDR3,R3,R2

ROM:00278076LDRHR3,[R3,R2]

ROM:00278078ADDPC,R3

ROM:0027807A

ROM:0027807Aloc_27807A

ROM:0027807ABloc_278766

ROM:0027807Cword_27807CDCW0xAA,0xBE,0xC6,0x180,0x186;0

ROM:0027807CDCW0x190,0x1A0,0x1A8,0x1DE,0x1E4;5

ROM:0027807CDCW0x1B0,0x212,0x276,0x1FE,0x294;10
首要,查看跳转符号,该符号有必要小于0x40,假如大于,则跳到默许处理方位,即:loc_27807A。
然后碑文坐落word_27807C的搬运控制表。这个表晒干寄存的是偏移,并非地址。随后,依据跳转符号,取表中的偏移,扩展之,加操作放入PC寄存器。比方,假如跳转符号为0,将会跳转到地址:
0x278078(currentvaluePC)+0xAA(offsetfromthetable)+0x4(!!!)=0x278126
之所以加4,是由于ARM处理器的特征:操作PC寄存器时,其值应该比预先确认的数值大4(在文档“toensureitiswordaligned”中有阐明)。

内存存取

在Thumb状况,处理器能够存取+/-256字节的空间。因而,无法直接存取内存,而需求运用寄存器来引导。也便是无法直接定位到0x974170,而需求选用寄存器。例如:
ROM:00277FF6LDRR0,=unk_974170

ROM:00277FF8LDRR0,[R0]
咱们获得了0x974170处的数据,可是工作还没有完毕!该有用地址(0x974170)处于有用的正负256字节中:
ROM:00278044off_278044DCDunk_974170
这样,便是说,LDR指令的机器码中存储了该指令当时的地址。(译注:便是说0x974170尽管看起来比较大,实际上仍是那+-256字节内,只不过经过LDR指令来定位)
这儿存在一个很艺术的优化办法:假如一个地址和该函数中别的一个被用到的地址有相关,那么这个地址能够经过算术运算指令或许直接存取来获取。举例来说,假如一个函数需求用到0x100000处的变量,而且需求用到0x100150处的别的一个变量,那么,编译器能够将这2个变量树立相关,或许选用以下代码:
LDRR0,=0x100000

ADDR0,*0xFF

ADDR0,*0x51

LDRR0,[R0]
在x86晒干,这种办法应用于结构中获取子结构接口。可是此处,却是一个常用的优化,这有什么优点呢?能够减小内存存储,而且算术运算比数据加载快得多。能够以为整个ARM汇编程序充满了不同的寄存器间算术运算。事实上,有多达16个寄存器用来进行此操作-削减内存和仓库定位频度。因而,只要在非常大的函数中才需求用仓库存储变量。对仓库的操作和x86处理仓库的办法相同。

IDA中的代码剖析

已然ARM文件没有一致格局,那么在加载ARM二进制映像的时分,有必要先加载该文件。在加载的时分,需求确认处理器类型。假如处理器规则代码有必要依照处理器模块处理次序,那么你能够加载映像文件而且指定需求的处理办法,ARM处理办法(低位处理)或许ARMB(高位处理)。而且,有必要树立ROM或许RAM段。总归没有固定的处理办法,详细的处理有赖于映像和每个ARM处理器的架构。例如,在ARM7中,内存一般有如下格局:
0x0-0x8000ofRAMprocessor

0x8000-0x1000000ROM

0x1000000-0x…..-SRAM(这儿看出本身数目)
现在就能够剖析代码了,在许多设备中(一般都是移动电话),代码的进口设定为0x8000。ARM形式下的代码从0x8000开端碑文,所以,开端碑文的指令和该处的相同。处理器的IDA模块能够简略地剖析此类switching查办,然后Thumb代码在ARM中碑文。假如窜逃修正跳转,能够按ALT-G,然后修正文件中的符号,假如为ARM文件,设为0,Thumb文件,设为1。

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/qiche/dianzi/264019.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部