欢迎来到 黑吧安全网 聚焦网络安全前沿资讯,精华内容,交流技术心得!

ARM 汇编基础速成2:ARM汇编中的数据类型

来源:本站整理 作者:佚名 时间:2017-07-07 TAG: 我要投稿

这是ARM汇编速成系列的第二部分,将学习到ARM汇编基础,数据类型及寄存器。
ARM汇编数据类型基础
与高级语言类似,ARM也支持操作不同的数据类型。

被加载或者存储的数据类型可以是无符号(有符号)的字(words,四字节),半字(halfwords,两字节),或者字节(bytes)。这些数据类型在汇编语言中的扩展后缀为-h或者-sh对应着半字,-b或者-sb对应着字节,但是对于字并没有对应的扩展。无符号类型与有符号类型的差别是:
符号数据类型可以包含正负数所以数值范围上更低些
无符号数据类型可以放得下很大的正数但是放不了负数
这有一些要求使用对应数据类型做存取操作的汇编指令示例:
ldr = 加载字,宽度四字节
ldrh = 加载无符号的半字,宽度两字节
ldrsh = 加载有符号的半字,宽度两字节
ldrb = 加载无符号的字节
ldrsb = 加载有符号的字节
str = 存储字,宽度四字节
strh = 存储无符号的半字,宽度两字节
strsh = 存储有符号的半字,宽度两字节
strb = 存储无符号的字节
strsb = 存储有符号的字节
字节序
在内存中有两种字节排布顺序,大端序(BE)或者小端序(LE)。两者的主要不同是对象中的每个字节在内存中的存储顺序存在差异。一般X86中是小端序,最低的字节存储在最低的地址上。在大端机中最高的字节存储在最低的地址上。

在版本3之前,ARM使用的是小端序,但在这之后就都是使用大端序了,但也允许切换回小端序。在我们样例代码所在的ARMv6中,指令代码是以[小端序排列对齐]。但是数据访问时采取大端序还是小端序使用程序状态寄存器(CPSR)的第9比特位来决定的。

ARM寄存器
寄存器的数量由ARM版本决定。根据[ARM参考手册],在ARMv6-M与ARMv7-M的处理器中有30个32bit位宽度的通用寄存器。前16个寄存器是用户层可访问控制的,其他的寄存器在高权限进程中可以访问(但ARMv6-M与ARMv7-M除外)。我们仅介绍可以在任何权限模式下访问的16个寄存器。这16个寄存器分为两组:通用寄存器与有特殊含义的寄存器。
|#|别名|用途|
|--|--|--|
|R0|-|通用寄存器|
|R1|-|通用寄存器|
|R2|-|通用寄存器|
|R3|-|通用寄存器|
|R4|-|通用寄存器|
|R5|-|通用寄存器|
|R6|-|通用寄存器|
|R7|-|一般放系统调用号|
|R8|-|通用寄存器|
|R9|-|通用寄存器|
|R10|-|通用寄存器|
|R11|FP|栈帧指针|
|R12|IP|内部程序调用|
|R13|SP|栈指针|
|R14|LR|链接寄存器(一般存放函数返回地址)|
|R15|PC|程序计数寄存器|
|CPSR|-|当前程序状态寄存器|
下面这张表是ARM架构与寄存器与Intel架构寄存器的关系:
|ARM|描述|X86|
|--|--|--|
|R0|通用寄存器|EAX|
|R1-R5|通用寄存器|EBX,ECX,EDX,ESI,EDI|
|R6-R10|通用寄存器|-|
|R11(FP)|栈帧指针|EBP|
|R12|内部程序调用|-|
|R13(SP)|栈指针|ESP|
|R14(LR)|链接寄存器|-|
|R14(LR)||EIP|
|CPSR|程序状态寄存器|EFLAGS|
R0-R12:用来在通用操作中存储临时的值,指针等。R0被用来存储函数调用的返回值。R7经常被用作存储系统调用号,R11存放着帮助我们找到栈帧边界的指针(之后会讲)。以及,在ARM的函数调用约定中,前四个参数按顺序存放在R0-R3中。
R13:SP(栈指针)。栈指针寄存器用来指向当前的栈顶。栈是一片来存储函数调用中相关数据的内存,在函数返回时会被修改为对应的栈指针。栈指针用来帮助在栈上申请数据空间。比如说你要申请一个字的大小,就会将栈指针减4,再将数据放入之前所指向的位置。
R14:LR(链接寄存器)。当一个函数调用发生,链接寄存器就被用来记录函数调用发生所在位置的下一条指令的地址。这么做允许我们快速的从子函数返回到父函数。
R15:PC(程序计数器)。程序计数器是一个在程序指令执行时自增的计数器。它的大小在ARM模式下总是4字节对齐,在Thumb模式下总是两字节对齐。当执行一个分支指令时,PC存储目的地址。在程序执行中,ARM模式下的PC存储着当前指令加8(两条ARM指令后)的位置,Thumb(v1)模式下的PC存储着当前指令加4(两条Thumb指令后)的位置。这也是X86与ARM在PC上的主要不同之处。
我们可以通过调试来观察PC的行为。我们的程序中将PC的值存到R0中同时包含了两条其他指令,来看看会发生什么。
.section .text
.global _start
_start:
 mov r0, pc
 mov r1, #2
 add r2, r1, r1
 bkpt
在GDB中,我们开始调试这段汇编代码:
gef> br _start
Breakpoint 1 at 0x8054
gef> run
在开始执行触发断点后,首先会在GDB中看到:
$r0 0x00000000   $r1 0x00000000   $r2 0x00000000   $r3 0x00000000
$r4 0x00000000   $r5 0x00000000   $r6 0x00000000   $r7 0x00000000
$r8 0x00000000   $r9 0x00000000   $r10 0x00000000  $r11 0x00000000
$r12 0x00000000  $sp 0xbefff7e0   $lr 0x00000000   $pc 0x00008054
$cpsr 0x00000010
0x8054  mov r0, pc    
0x8058  mov r0, #2
0x805c  add r1, r0, r0
0x8060  bkpt 0x0000
0x8064 andeq r1, r0, r1, asr #10
0x8068 cmnvs r5, r0, lsl #2

[1] [2]  下一页

【声明】:黑吧安全网(http://www.myhack58.com)登载此文出于传递更多信息之目的,并不代表本站赞同其观点和对其真实性负责,仅适于网络安全技术爱好者学习研究使用,学习中请遵循国家相关法律法规。如有问题请联系我们,联系邮箱admin@myhack58.com,我们会在最短的时间内进行处理。
  • 最新更新
    • 相关阅读
      • 本类热门
        • 最近下载