arm指令练习篇章一
口号:为了熟悉arm指令而奋斗!
for
C code
|
|
arm code
main函数
|
|
push {fp, lr}
{}
: 其中包含多个值;fp
(frame pointer): 帧指针,每个栈帧由fp和sp界定,fp相当于x86中的ebp,sp相当于x86中的esp;lr
(link register): 链接寄存器,在程序中调用其他函数时,存放子程序的返回地址(即调用指令的下一条指令);
本指令相当于stmfd sp!,{fp,lr}
(!表示更新寄存器的值),将调用者的fp和lr寄存的值压入堆栈(顺序:编号小的寄存器的值存入低地址,编号大的寄存器的值存入高地址),
保护调用者程序的环境,子程序执行完毕后恢复环境.
add fp, sp, #4
将被调用者的fp(栈底)指向存放调用者fp的地址.
sub sp, sp, #8
抬高栈顶指针,开辟栈空间(8字节).
str r0, [fp, #-8]
将r0的值(参数1)存储到fp-8所在的地址.
str r1, [fp, #-12]
将r1的值(参数2)存储到fp-12所在的地址.
现在子程序的栈结构如下:
高地址 -> 低地址
返回地址(fp) 参数1 参数2(sp)
bl 8314
调用8314处的test_for函数.bl指令同时会将返回地址存储在r14(lr)中.
mov r2, r0
r0存储的是test_for的返回值,赋给r2.
ldr r3, [pc, #24] ; 83ac
加载pc+24地址处的一个字的数据(.word 0x00000030)放入r3.r3=0x30.
add r3, pc, r3
r3+=pc,即取”sum:%d”字符串的地址.(PC的值为当前执行指令地址+8字节)
mov r0, r3
r0为第一个参数(format字符串).
mov r1, r2
r2为第二个参数(test_for返回值).(当参数少于4个时保存在通用寄存器中,多余4个的保存在栈中)
bl 8258 printf@plt
调用printf函数.
sub sp, fp, #4
与开辟栈空间相对应.
pop {fp, pc}
将栈顶数据分别弹出至fp,pc,恢复调用者程序的环境(顺序:低地址的值放入编号小的寄存器,高地址的值放入编号大的寄存器).
test_for
|
|
switch
c code
|
|
arm code
|
|