本次实验的起源是这样的:
看到C99标准里面支持变量用到时再定义,然后做了以下实验,定义函数,看反汇编结果。
void test_c99(void)
{
char i=0;
printf("i=%d", i);
char j=0;
printf("j=%d", j);
char k=0;
printf("k=%d", k);
char l=0;
printf("l=%d", l);
char m=0;
printf("m=%d", m);
char n=0;
printf("n=%d", n);
char o=0;
printf("o=%d", o);
char p=0;
printf("p=%d", p);
char q=0;
printf("q=%d", q);
char r=0;
printf("r=%d", r);
char s=0;
printf("s=%d", s);
char t=0;
printf("t=%d", t);
char str[3]="Jim";
printf("str=%s", str);
}
{
char i=0;
printf("i=%d", i);
char j=0;
printf("j=%d", j);
char k=0;
printf("k=%d", k);
char l=0;
printf("l=%d", l);
char m=0;
printf("m=%d", m);
char n=0;
printf("n=%d", n);
char o=0;
printf("o=%d", o);
char p=0;
printf("p=%d", p);
char q=0;
printf("q=%d", q);
char r=0;
printf("r=%d", r);
char s=0;
printf("s=%d", s);
char t=0;
printf("t=%d", t);
char str[3]="Jim";
printf("str=%s", str);
}
test_c99
0x70007724: e92d5fff ._-. PUSH {r0-r12,lr}
0x70007728: e3a04000 .@.. MOV r4,#0 //从R4寄存器开始使用,每定义一个变量使用一个寄存器
0x7000772c: e1a01004 .... MOV r1,r4 //将刚刚定义并初始化的变量(r4中)取出,放到r1中
0x70007730: e28f0fce .... ADR r0,{pc}+0x340 ; 0x70007a70 //取出"i=%d"字符串的地址到r0中
0x70007734: fa00027f .... BLX __2printf ; 0x70008138 //调用printf函数,函数调用的传参规则是:func(r0,r1,r2,r3)
0x70007724: e92d5fff ._-. PUSH {r0-r12,lr}
0x70007728: e3a04000 .@.. MOV r4,#0 //从R4寄存器开始使用,每定义一个变量使用一个寄存器
0x7000772c: e1a01004 .... MOV r1,r4 //将刚刚定义并初始化的变量(r4中)取出,放到r1中
0x70007730: e28f0fce .... ADR r0,{pc}+0x340 ; 0x70007a70 //取出"i=%d"字符串的地址到r0中
0x70007734: fa00027f .... BLX __2printf ; 0x70008138 //调用printf函数,函数调用的传参规则是:func(r0,r1,r2,r3)
//具体要看ABI规范或Procedure Call Standard for ARM
0x70007738: e3a05000 .P.. MOV r5,#0
0x7000773c: e1a01005 .... MOV r1,r5
0x70007740: e28f0e33 3... ADR r0,{pc}+0x338 ; 0x70007a78
0x70007744: fa00027b {... BLX __2printf ; 0x70008138
0x70007748: e3a06000 .`.. MOV r6,#0
0x7000774c: e1a01006 .... MOV r1,r6
0x70007750: e28f0fca .... ADR r0,{pc}+0x330 ; 0x70007a80
0x70007754: fa000277 w... BLX __2printf ; 0x70008138
0x70007758: e3a07000 .p.. MOV r7,#0
0x7000775c: e1a01007 .... MOV r1,r7
0x70007760: e28f0e32 2... ADR r0,{pc}+0x328 ; 0x70007a88
0x70007764: fa000273 s... BLX __2printf ; 0x70008138
0x70007768: e3a08000 .... MOV r8,#0
0x7000776c: e1a01008 .... MOV r1,r8
0x70007770: e28f0fc6 .... ADR r0,{pc}+0x320 ; 0x70007a90
0x70007774: fa00026f o... BLX __2printf ; 0x70008138
0x70007778: e3a09000 .... MOV r9,#0
0x7000777c: e1a01009 .... MOV r1,r9
0x70007780: e28f0e31 1... ADR r0,{pc}+0x318 ; 0x70007a98
0x70007784: fa00026b k... BLX __2printf ; 0x70008138
0x70007788: e3a0a000 .... MOV r10,#0
0x7000778c: e1a0100a .... MOV r1,r10
0x70007790: e28f0fc2 .... ADR r0,{pc}+0x310 ; 0x70007aa0
0x70007794: fa000267 g... BLX __2printf ; 0x70008138
0x70007798: e3a0b000 .... MOV r11,#0 //寄存器r11中存放定义的新变量
0x7000779c: e1a0100b .... MOV r1,r11
0x700077a0: e28f0c03 .... ADR r0,{pc}+0x308 ; 0x70007aa8
0x700077a4: fa000263 c... BLX __2printf ; 0x70008138
0x700077a8: e3a00000 .... MOV r0,#0 //寄存器已经不够用了,需要通过堆栈来存储新定义的变量。
0x70007738: e3a05000 .P.. MOV r5,#0
0x7000773c: e1a01005 .... MOV r1,r5
0x70007740: e28f0e33 3... ADR r0,{pc}+0x338 ; 0x70007a78
0x70007744: fa00027b {... BLX __2printf ; 0x70008138
0x70007748: e3a06000 .`.. MOV r6,#0
0x7000774c: e1a01006 .... MOV r1,r6
0x70007750: e28f0fca .... ADR r0,{pc}+0x330 ; 0x70007a80
0x70007754: fa000277 w... BLX __2printf ; 0x70008138
0x70007758: e3a07000 .p.. MOV r7,#0
0x7000775c: e1a01007 .... MOV r1,r7
0x70007760: e28f0e32 2... ADR r0,{pc}+0x328 ; 0x70007a88
0x70007764: fa000273 s... BLX __2printf ; 0x70008138
0x70007768: e3a08000 .... MOV r8,#0
0x7000776c: e1a01008 .... MOV r1,r8
0x70007770: e28f0fc6 .... ADR r0,{pc}+0x320 ; 0x70007a90
0x70007774: fa00026f o... BLX __2printf ; 0x70008138
0x70007778: e3a09000 .... MOV r9,#0
0x7000777c: e1a01009 .... MOV r1,r9
0x70007780: e28f0e31 1... ADR r0,{pc}+0x318 ; 0x70007a98
0x70007784: fa00026b k... BLX __2printf ; 0x70008138
0x70007788: e3a0a000 .... MOV r10,#0
0x7000778c: e1a0100a .... MOV r1,r10
0x70007790: e28f0fc2 .... ADR r0,{pc}+0x310 ; 0x70007aa0
0x70007794: fa000267 g... BLX __2printf ; 0x70008138
0x70007798: e3a0b000 .... MOV r11,#0 //寄存器r11中存放定义的新变量
0x7000779c: e1a0100b .... MOV r1,r11
0x700077a0: e28f0c03 .... ADR r0,{pc}+0x308 ; 0x70007aa8
0x700077a4: fa000263 c... BLX __2printf ; 0x70008138
0x700077a8: e3a00000 .... MOV r0,#0 //寄存器已经不够用了,需要通过堆栈来存储新定义的变量。
//r12之后有特殊用途,具体看架构手册或Procedure Call Standard for ARM
//gooogleman博客有篇