BruceFan's Blog

Stay hungry, stay foolish

0%

ARM基础

Register
from r0 to r15
r0 is used as a return value of functions
r11 is used like EBP (called FP)
r12 intra-procedure-call scratch register (called IP)
r13 is used like ESP (called SP)
r14 is Link-Register (called LR)
r15 is used like EIP (called PC)
all register are completely general, you can set a value to r15 directly
ldr r1, [pc] ;(pc point to ‘.long 0x00001337’)
b go_next
.long 0x00001337

r1 register will have 0x1337
ARM中的三级流水线,当前指令在执行,下一条在译码,再下一条正在读取
参数传递
ARM中的函数参数是通过r0~r3进行传递的,参数超过4个时,超出的部分会通过栈来传递。
mov
mov r1, r2 ;r1=r2
mov r1, #0x80 ;r1 = 0x80
push
push 0x10 ;push 0x10 onto stack
push {r1} ;push r1 register onto stack
push {r11, lr} ;push from right to left (push lr, push r11)
push {r1-r5} ;push r1,r2,r3,r4 and r5 onto stack
pop
pop {r11, pc} ;pop r11, pop pc
ldr
ldr{type}{cond} Rd, label
ldr r1, [r2] ;r1 = *r2
ldr r1, [r2, #0x10] ;r1 = *(r2+0x10)
type指明操作数的位数:

type 含义
B 无符号字节 8位
SB 有符号字节 8位
H 无符号半字 16位
SH 有符号半字 16位

字是32位,不需要指定type。加载数据时会根据有/无符号,将数据符号/零扩展为32位。
str
str r1, [r2] ;*r2 = r1
str r1, [r2, #0x1] ;*(r2+1)=r1
b/bl
b 0x8080 ;jump to 0x8080
bl 0x8080 ;jump to 0x8080 and save next instruction address of current into lr register
bx/blx
bx{cond} Rm
带状态切换的跳转指令,操作数为寄存器。满足条件cond,处理器判断Rm的最低位如果为1,则跳转时自动将CPSR寄存器的标志T置位,并将目标地址的代码解释为Thumb代码;如果Rm的最低位为0,则跳转时自动将CPSR寄存器的标志T复位,并将目标地址的代码解释为ARM。
add
add r1, r2 ;r1 = r1 + r2
add r1, #0x10 ;r1 = r1 + 0x10
add r1, r2, r3 ;r1 = r2 + r3
add r1, r2, #0x10 ;r1 = r2 + 0x10
sub
sub r1, r2 ;r1 = r1 - r2
cmp
cmp r1, r2 ;r1 - r2
系统调用
1.svc
svc #0x900004 ;calling sys_write
2.swi
mov r7, #4 ; write syscall
swi 0 ; execute syscall
这两个是一样的

lsls
Logical shift left
lsls r2, r2, #1 ;r2 = r2 << 1

system call /usr/include/arm-linux-gnueabihf/asm/unistd.h
(__lib_start_main)(int (*main)(int , char **, char **))
eor
eor r0, r0 ;异或