树莓派上关于ARM指令的验证
来源:互联网 发布:淘宝异地客服找工作 编辑:程序博客网 时间:2024/05/18 01:55
made by Rk
本文由浙江大学《嵌入式系统》课程提供强力支持。
感谢翁恺老师 @翁恺BA5AG
/*************************************************************/
通过C代码和反汇编工具研究以下几点:
生成了Thumb指令还是ARM指令,如何通过编译参数改变;
对于ARM指令,能否产生条件执行的指令;
设计C的代码场景,观察是否产生了寄存器移位寻址;
设计C的代码场景,观察一个复杂的32位数是如何装载到寄存器的;
写一个C的多重函数调用的程序,观察和分析:
调用时的返回地址在哪里?
传入的参数在哪里?
本地变量的堆栈分配是如何做的?
寄存器是caller保存还是callee保存?是全体保存还是部分保存?
MLA是带累加的乘法,尝试要如何写C的表达式能编译得到MLA指令。
为了实验代码的完整可用,新建一个文件夹arm。
生成了Thumb指令还是ARM指令,如何通过编译参数改变
1、编写下列指令:
#include <stdio.h>int main(){ int t = 0; t++; return 0;}
gcc -c arm_1.cobjdump -d arm_1.o
可以看到结果如下:
pi@raspberrypi ~/code/arm $ objdump -d arm_1.oarm_1.o: file format elf32-littlearmDisassembly of section .text:00000000 <main>: 0:e52db004 push{fp}; (str fp, [sp, #-4]!) 4:e28db000 addfp, sp, #0 8:e24dd00c subsp, sp, #12 c:e3a03000 movr3, #0 10:e50b3008 strr3, [fp, #-8] 14:e51b3008 ldrr3, [fp, #-8] 18:e2833001 addr3, r3, #1 1c:e50b3008 strr3, [fp, #-8] 20:e3a03000 movr3, #0 24:e1a00003 movr0, r3 28:e28bd000 addsp, fp, #0 2c:e8bd0800 pop{fp} 30:e12fff1e bxlr
指令程度为32位,gcc默认使用arm指令集。
3、使用Thumb编译
gcc -c -mthumb -msoft-float arm_1.c查看编译生成结果:
pi@raspberrypi ~/code/arm $ objdump -d arm_1.oarm_1.o: file format elf32-littlearmDisassembly of section .text:00000000 <main>: 0:b580 push{r7, lr} 2:b082 subsp, #8 4:af00 addr7, sp, #0 6:2300 movsr3, #0 8:607b strr3, [r7, #4] a:687b ldrr3, [r7, #4] c:3301 addsr3, #1 e:607b strr3, [r7, #4] 10:2300 movsr3, #0 12:1c18 addsr0, r3, #0 14:46bd movsp, r7 16:b002 addsp, #8 18:bd80 pop{r7, pc} 1a:46c0 nop; (mov r8, r8)
指令长度是16位(最左一列以2Byte递增)
对于ARM指令,能否产生条件执行的指令;
1、编写arm_branch.c源文件:
#include <stdio.h>int f(int a, int b) {int t;if (a > b)t = a - b--;if (a == b - 10)t = a + b++;return t;}int main() {f(10, 20);return 0;}
pi@raspberrypi ~/code/arm $ objdump -d arm_branch.oarm_branch.o: file format elf32-littlearmDisassembly of section .text:00000000 <f>: 0:e52db004 push{fp}; (str fp, [sp, #-4]!) 4:e28db000 addfp, sp, #0 8:e24dd014 subsp, sp, #20 c:e50b0010 strr0, [fp, #-16] 10:e50b1014 strr1, [fp, #-20] 14:e51b2010 ldrr2, [fp, #-16] 18:e51b3014 ldrr3, [fp, #-20] 1c:e1520003 cmpr2, r3 20:da000006 ble40 <f+0x40> 24:e51b2010 ldrr2, [fp, #-16] 28:e51b3014 ldrr3, [fp, #-20] 2c:e0633002 rsbr3, r3, r2 30:e50b3008 strr3, [fp, #-8] 34:e51b3014 ldrr3, [fp, #-20] 38:e2433001 subr3, r3, #1 3c:e50b3014 strr3, [fp, #-20] 40:e51b3014 ldrr3, [fp, #-20] 44:e243200a subr2, r3, #10 48:e51b3010 ldrr3, [fp, #-16] 4c:e1520003 cmpr2, r3 50:1a000006 bne70 <f+0x70> 54:e51b2014 ldrr2, [fp, #-20] 58:e51b3010 ldrr3, [fp, #-16] 5c:e0823003 addr3, r2, r3 60:e50b3008 strr3, [fp, #-8] 64:e51b3014 ldrr3, [fp, #-20] 68:e2833001 addr3, r3, #1 6c:e50b3014 strr3, [fp, #-20] 70:e51b3008 ldrr3, [fp, #-8] 74:e1a00003 movr0, r3 78:e28bd000 addsp, fp, #0 7c:e8bd0800 pop{fp} 80:e12fff1e bxlr00000084 <main>: 84:e92d4800 push{fp, lr} 88:e28db004 addfp, sp, #4 8c:e3a0000a movr0, #10 90:e3a01014 movr1, #20 94:ebfffffe bl0 <f> 98:e3a03000 movr3, #0 9c:e1a00003 movr0, r3 a0:e8bd8800 pop{fp, pc}
可以看到bne等条件分支指令的出现,可见ARM是支持的条件执行指令的。
设计C的代码场景,观察是否产生了寄存器移位寻址;
1、编译生成测试代码:
#include <stdio.h>int main() { int t[10]; int i = 0; int j = 0; for(j=0; j<4; j++) { t[8] = t[i*2]; } printf("%d", t[8]); return 0;}
2、查看编译结果:
pi@raspberrypi ~/code/arm $ objdump -d arm_shift.oarm_shift.o: file format elf32-littlearmDisassembly of section .text:00000000 <main>: 0:e92d4800 push{fp, lr} 4:e28db004 addfp, sp, #4 8:e24dd030 subsp, sp, #48; 0x30 c:e3a03000 movr3, #0 10:e50b300c strr3, [fp, #-12] 14:e3a03000 movr3, #0 18:e50b3008 strr3, [fp, #-8] 1c:e3a03000 movr3, #0 20:e50b3008 strr3, [fp, #-8] 24:ea00000b b58 <main+0x58> 28:e51b300c ldrr3, [fp, #-12] 2c:e1a02083 lslr2, r3, #1 30:e3e0302f mvnr3, #47; 0x2f 34:e1a02102 lslr2, r2, #2 38:e24b1004 subr1, fp, #4 3c:e0812002 addr2, r1, r2 40:e0823003 addr3, r2, r3 44:e5933000 ldrr3, [r3] 48:e50b3014 strr3, [fp, #-20] 4c:e51b3008 ldrr3, [fp, #-8] 50:e2833001 addr3, r3, #1 54:e50b3008 strr3, [fp, #-8] 58:e51b3008 ldrr3, [fp, #-8] 5c:e3530003 cmpr3, #3 60:dafffff0 ble28 <main+0x28> 64:e59f201c ldrr2, [pc, #28]; 88 <main+0x88> 68:e51b3014 ldrr3, [fp, #-20] 6c:e1a00002 movr0, r2 70:e1a01003 movr1, r3 74:ebfffffe bl0 <printf> 78:e3a03000 movr3, #0 7c:e1a00003 movr0, r3 80:e24bd004 subsp, fp, #4 84:e8bd8800 pop{fp, pc} 88:00000000 .word0x00000000
lslr2, r3, #1
设计C的代码场景,观察一个复杂的32位数是如何装载到寄存器的;
1、编写测试代码
#include <stdio.h>int main() { unsigned int a = 0x12345678; a++; return 0;}
2、编译查看结果:
pi@raspberrypi ~/code/arm $ objdump -d arm_big_num.oarm_big_num.o: file format elf32-littlearmDisassembly of section .text:00000000 <main>: 0:e52db004 push{fp}; (str fp, [sp, #-4]!) 4:e28db000 addfp, sp, #0 8:e24dd00c subsp, sp, #12 c:e59f3020 ldrr3, [pc, #32]; 34 <main+0x34> 10:e50b3008 strr3, [fp, #-8] 14:e51b3008 ldrr3, [fp, #-8] 18:e2833001 addr3, r3, #1 1c:e50b3008 strr3, [fp, #-8] 20:e3a03000 movr3, #0 24:e1a00003 movr0, r3 28:e28bd000 addsp, fp, #0 2c:e8bd0800 pop{fp} 30:e12fff1e bxlr 34:12345678 .word0x12345678
可以看到ARM指令将大数字存在命令段,通过ldr指令去加载,而非MIPS等指令集使用lui和ori来实现32位大数字的实现。
写一个C的多重函数调用的程序,观察和分析:
调用时的返回地址在哪里?
传入的参数在哪里?
本地变量的堆栈分配是如何做的?
寄存器是caller保存还是callee保存?是全体保存还是部分保存?
1、编写测试代码
#include <stdio.h>int f2(int a, int b, int c, int x, int y, int z, int p, int q, int r) { int temp = 0; temp = a*x + b*y + c*z + p*q +r; return temp;}int f3(int a,int b,int c,int d,int e,int f,int g,int h,int i,int j,int k) { int t1=a+b; int t2=c+d; int t3=e+f; int t4=g+h; int t5=i+j; f2(1,2,3,4,5,6,7,8,9); int t6=t1*t2; int t7=t3*t4; int t8=t6-t7; int t9=t8*t5*k; return t9;} int f1(int a, int b, int c) { int temp = 0; temp = f2(a, b, c, 4, 5, 6, 7, 8, 9); return temp;}int main() { int a,b,c; a = 0; b = 1; c = 2; printf("%d", f1(a,b,c)); f3(11,10,9,8,7,6,5,4,3,2,1); return 0;}
2、编译查看结果
pi@raspberrypi ~/code/arm $ gcc -c arm_multi_call.cpi@raspberrypi ~/code/arm $ objdump -d arm_multi_call.oarm_multi_call.o: file format elf32-littlearmDisassembly of section .text:00000000 <f2>: 0:e52db004 push{fp}; (str fp, [sp, #-4]!) 4:e28db000 addfp, sp, #0 8:e24dd01c subsp, sp, #28 c:e50b0010 strr0, [fp, #-16] 10:e50b1014 strr1, [fp, #-20] 14:e50b2018 strr2, [fp, #-24] 18:e50b301c strr3, [fp, #-28] 1c:e3a03000 movr3, #0 20:e50b3008 strr3, [fp, #-8] 24:e51b3010 ldrr3, [fp, #-16] 28:e51b201c ldrr2, [fp, #-28] 2c:e0020392 mulr2, r2, r3 30:e51b3014 ldrr3, [fp, #-20] 34:e59b1004 ldrr1, [fp, #4] 38:e0030391 mulr3, r1, r3 3c:e0822003 addr2, r2, r3 40:e59b300c ldrr3, [fp, #12] 44:e59b1010 ldrr1, [fp, #16] 48:e0010391 mulr1, r1, r3 4c:e51b3018 ldrr3, [fp, #-24] 50:e59b0008 ldrr0, [fp, #8] 54:e0030390 mulr3, r0, r3 58:e0813003 addr3, r1, r3 5c:e0822003 addr2, r2, r3 60:e59b3014 ldrr3, [fp, #20] 64:e0823003 addr3, r2, r3 68:e50b3008 strr3, [fp, #-8] 6c:e51b3008 ldrr3, [fp, #-8] 70:e1a00003 movr0, r3 74:e28bd000 addsp, fp, #0 78:e8bd0800 pop{fp} 7c:e12fff1e bxlr00000080 <f3>: 80:e92d4800 push{fp, lr} 84:e28db004 addfp, sp, #4 88:e24dd050 subsp, sp, #80; 0x50 8c:e50b0030 strr0, [fp, #-48]; 0x30 90:e50b1034 strr1, [fp, #-52]; 0x34 94:e50b2038 strr2, [fp, #-56]; 0x38 98:e50b303c strr3, [fp, #-60]; 0x3c 9c:e51b2030 ldrr2, [fp, #-48]; 0x30 a0:e51b3034 ldrr3, [fp, #-52]; 0x34 a4:e0823003 addr3, r2, r3 a8:e50b3008 strr3, [fp, #-8] ac:e51b2038 ldrr2, [fp, #-56]; 0x38 b0:e51b303c ldrr3, [fp, #-60]; 0x3c b4:e0823003 addr3, r2, r3 b8:e50b300c strr3, [fp, #-12] bc:e59b2004 ldrr2, [fp, #4] c0:e59b3008 ldrr3, [fp, #8] c4:e0823003 addr3, r2, r3 c8:e50b3010 strr3, [fp, #-16] cc:e59b200c ldrr2, [fp, #12] d0:e59b3010 ldrr3, [fp, #16] d4:e0823003 addr3, r2, r3 d8:e50b3014 strr3, [fp, #-20] dc:e59b2014 ldrr2, [fp, #20] e0:e59b3018 ldrr3, [fp, #24] e4:e0823003 addr3, r2, r3 e8:e50b3018 strr3, [fp, #-24] ec:e3a03005 movr3, #5 f0:e58d3000 strr3, [sp] f4:e3a03006 movr3, #6 f8:e58d3004 strr3, [sp, #4] fc:e3a03007 movr3, #7 100:e58d3008 strr3, [sp, #8] 104:e3a03008 movr3, #8 108:e58d300c strr3, [sp, #12] 10c:e3a03009 movr3, #9 110:e58d3010 strr3, [sp, #16] 114:e3a00001 movr0, #1 118:e3a01002 movr1, #2 11c:e3a02003 movr2, #3 120:e3a03004 movr3, #4 124:ebfffffe bl0 <f2> 128:e51b3008 ldrr3, [fp, #-8] 12c:e51b200c ldrr2, [fp, #-12] 130:e0030392 mulr3, r2, r3 134:e50b301c strr3, [fp, #-28] 138:e51b3010 ldrr3, [fp, #-16] 13c:e51b2014 ldrr2, [fp, #-20] 140:e0030392 mulr3, r2, r3 144:e50b3020 strr3, [fp, #-32] 148:e51b201c ldrr2, [fp, #-28] 14c:e51b3020 ldrr3, [fp, #-32] 150:e0633002 rsbr3, r3, r2 154:e50b3024 strr3, [fp, #-36]; 0x24 158:e51b3024 ldrr3, [fp, #-36]; 0x24 15c:e51b2018 ldrr2, [fp, #-24] 160:e0030392 mulr3, r2, r3 164:e59b201c ldrr2, [fp, #28] 168:e0030392 mulr3, r2, r3 16c:e50b3028 strr3, [fp, #-40]; 0x28 170:e51b3028 ldrr3, [fp, #-40]; 0x28 174:e1a00003 movr0, r3 178:e24bd004 subsp, fp, #4 17c:e8bd8800 pop{fp, pc}00000180 <f1>: 180:e92d4800 push{fp, lr} 184:e28db004 addfp, sp, #4 188:e24dd030 subsp, sp, #48; 0x30 18c:e50b0010 strr0, [fp, #-16] 190:e50b1014 strr1, [fp, #-20] 194:e50b2018 strr2, [fp, #-24] 198:e3a03000 movr3, #0 19c:e50b3008 strr3, [fp, #-8] 1a0:e3a03005 movr3, #5 1a4:e58d3000 strr3, [sp] 1a8:e3a03006 movr3, #6 1ac:e58d3004 strr3, [sp, #4] 1b0:e3a03007 movr3, #7 1b4:e58d3008 strr3, [sp, #8] 1b8:e3a03008 movr3, #8 1bc:e58d300c strr3, [sp, #12] 1c0:e3a03009 movr3, #9 1c4:e58d3010 strr3, [sp, #16] 1c8:e51b0010 ldrr0, [fp, #-16] 1cc:e51b1014 ldrr1, [fp, #-20] 1d0:e51b2018 ldrr2, [fp, #-24] 1d4:e3a03004 movr3, #4 1d8:ebfffffe bl0 <f2> 1dc:e50b0008 strr0, [fp, #-8] 1e0:e51b3008 ldrr3, [fp, #-8] 1e4:e1a00003 movr0, r3 1e8:e24bd004 subsp, fp, #4 1ec:e8bd8800 pop{fp, pc}000001f0 <main>: 1f0:e92d4810 push{r4, fp, lr} 1f4:e28db008 addfp, sp, #8 1f8:e24dd034 subsp, sp, #52; 0x34 1fc:e3a03000 movr3, #0 200:e50b3010 strr3, [fp, #-16] 204:e3a03001 movr3, #1 208:e50b3014 strr3, [fp, #-20] 20c:e3a03002 movr3, #2 210:e50b3018 strr3, [fp, #-24] 214:e59f4078 ldrr4, [pc, #120]; 294 <main+0xa4> 218:e51b0010 ldrr0, [fp, #-16] 21c:e51b1014 ldrr1, [fp, #-20] 220:e51b2018 ldrr2, [fp, #-24] 224:ebfffffe bl180 <f1> 228:e1a03000 movr3, r0 22c:e1a00004 movr0, r4 230:e1a01003 movr1, r3 234:ebfffffe bl0 <printf> 238:e3a03007 movr3, #7 23c:e58d3000 strr3, [sp] 240:e3a03006 movr3, #6 244:e58d3004 strr3, [sp, #4] 248:e3a03005 movr3, #5 24c:e58d3008 strr3, [sp, #8] 250:e3a03004 movr3, #4 254:e58d300c strr3, [sp, #12] 258:e3a03003 movr3, #3 25c:e58d3010 strr3, [sp, #16] 260:e3a03002 movr3, #2 264:e58d3014 strr3, [sp, #20] 268:e3a03001 movr3, #1 26c:e58d3018 strr3, [sp, #24] 270:e3a0000b movr0, #11 274:e3a0100a movr1, #10 278:e3a02009 movr2, #9 27c:e3a03008 movr3, #8 280:ebfffffe bl80 <f3> 284:e3a03000 movr3, #0 288:e1a00003 movr0, r3 28c:e24bd008 subsp, fp, #8 290:e8bd8810 pop{r4, fp, pc} 294:00000000 .word0x00000000
可以发现:
函数调用后的返回地址存放在LR寄存器中。
传入的参数存放在R0 R1 R2 R3四个寄存器中,多余的参数放在堆栈中。
本地变量存放在堆栈高地址,传进来的参数存放在堆栈低地址。
R0到R3由caller保存,R4以上由callee保存。
MLA是带累加的乘法,尝试要如何写C的表达式能编译得到MLA指令。
1、编写函数如下:
#include <stdio.h>int f1(int a, int b, int c) { return a*b + c;}int main() { f1(1,2,3); return 0;}
2、编译查看结果:
可以看到MLA命令得到了使用。
- 树莓派上关于ARM指令的验证
- 嵌入式学习笔记--关于ARM中SWP指令的执行顺序问题【待验证】
- 关于ARM的B,BL跳转指令
- 关于ARM伪指令
- 关于ARM里面的CMP指令的个人理解
- 关于汇编ARM指令DCD
- 关于汇编ARM指令DCD
- 关于汇编ARM指令DCD
- ARM汇编中关于“.word”伪指令的概念
- 关于ARM 汇编 指令 操作范围的一点理解
- ARM汇编中关于“.word”伪指令的概念
- ARM的跳转指令
- ARM的跳转指令
- ARM的BX指令
- ARM 的DCD指令
- ARM 的DCD指令
- ARM的BX指令
- ARM 的指令集
- GPS是如何定位你在哪的?
- 手机web注意事项收集
- zookeeper研究笔记(一)—— single模式搭建
- 关于linux设备驱动模型,今天做一个简单的理解总结,可能有错误,后面可能会更正
- ubuntu10.10下测试gcc,gfortran编译器的helloworld工程
- 树莓派上关于ARM指令的验证
- windows 用内核对象进行线程同步
- 宽字节与单字节的转换 Unicode字符集下CString与char *转换
- 聊天常用缩略语
- (个人笔记)java Swing 笔记
- C#身份证验证
- 为什么要用非关系数据库?
- Socket(TCP)通信简单示例
- 顺序表c语言实现