Register
from r0 to r15r0 is used as a return value of functionsr11 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 directlyldr r1, [pc] ;(pc point to ‘.long 0x00001337’)b go_next.long 0x00001337
r1 register will have 0x1337
ARM中的三级流水线,当前指令在执行,下一条在译码,再下一条正在读取
参数传递
ARM中的函数参数是通过r0~r3进行传递的,参数超过4个时,超出的部分会通过栈来传递。
movmov r1, r2 ;r1=r2mov r1, #0x80 ;r1 = 0x80
pushpush 0x10 ;push 0x10 onto stackpush {r1} ;push r1 register onto stackpush {r11, lr} ;push from right to left (push lr, push r11)push {r1-r5} ;push r1,r2,r3,r4 and r5 onto stack
poppop {r11, pc} ;pop r11, pop pc
ldr
ldr{type}{cond} Rd, labelldr r1, [r2] ;r1 = *r2ldr r1, [r2, #0x10] ;r1 = *(r2+0x10)
type指明操作数的位数:
| type | 含义 |
|---|---|
| B | 无符号字节 8位 |
| SB | 有符号字节 8位 |
| H | 无符号半字 16位 |
| SH | 有符号半字 16位 |
字是32位,不需要指定type。加载数据时会根据有/无符号,将数据符号/零扩展为32位。
strstr r1, [r2] ;*r2 = r1str r1, [r2, #0x1] ;*(r2+1)=r1
b/blb 0x8080 ;jump to 0x8080bl 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。
addadd r1, r2 ;r1 = r1 + r2add r1, #0x10 ;r1 = r1 + 0x10add r1, r2, r3 ;r1 = r2 + r3add r1, r2, #0x10 ;r1 = r2 + 0x10
subsub r1, r2 ;r1 = r1 - r2
cmpcmp r1, r2 ;r1 - r2
系统调用
1.svcsvc #0x900004 ;calling sys_write
2.swimov r7, #4 ; write syscallswi 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 **))
eoreor r0, r0 ;异或