Référence : https://blog.csdn.net/u012874587/article/details/78843940?utm_source=app&app_version=4.8.0
Après avoir d'abord lu l'article de référence, il peut être plus facile de comprendre certaines choses de base après les avoir lues dans l'article précédent. . , omis de cet article.
Le but de cet article est que la plupart des blogs publient simplement le code assembleur sans commentaires détaillés, ce qui m'a fait avoir beaucoup de doutes lorsque je l'ai lu moi-même, j'ai donc écrit cet article pour clarifier certaines des choses sur lesquelles j'ai des doutes. Ajouter des commentaires
1. Tout d'abord, vous devez comprendre la structure du cadre de pile, comme indiqué ci-dessous.
Le pointeur de pile R11 est généralement fp dans l'assembly et sp pointe vers l'adresse de retour
. 2. Code du langage C
1 int foo(int a, int b, int c, int d)
2 {
3 int A,B,C,D;
4 A = a;
5 B = b;
6 C = c;
7 D = d;
8
9 return 0;
10 }
11 void main(void)
12 {
13 int a;
14 a = foo(1,2,3,4);
15 }
Le code de démontage correspondant est
1 00000000 <_start>:
2 .text
3 .global _start
4 _start:
5 ldr sp,=4096 ;声明栈空间大小为4096字节
6 0: e3a0da01 mov sp, #4096 ; 0x1000
7 bl main ;跳入main函数,进入c世界
8 4: eb000014 bl 5c <main>
9
10 00000008 <loop>:
11 loop:
12 b loop
13 8: eafffffe b 8 <loop>
14
15 0000000c <foo>: ;先从main函数看起,再根据跳转,读这部分代码
16 int foo(int a, int b, int c, int d)
17 {
18 c: e52db004 push {
fp} ; 保存栈指针压入栈中也就是上图中的R11。地址为sp-4(str fp, [sp, #-4]!)
19 10: e28db000 add fp, sp, #0 ;fp栈指针指向栈顶指针sp
20 14: e24dd024 sub sp, sp, #36 ; 留给栈空间大小为36个字节,具体栈空间分布情况见下图10x24
21 18: e50b0018 str r0, [fp, #-24]
22 1c: e50b101c str r1, [fp, #-28]
23 20: e50b2020 str r2, [fp, #-32]
24 24: e50b3024 str r3, [fp, #-36] ; 0x24
25 int A,B,C,D;
26 A = a;
27 28: e51b3018 ldr r3, [fp, #-24]
28 2c: e50b3014 str r3, [fp, #-20]
29 B = b;
30 30: e51b301c ldr r3, [fp, #-28]
31 34: e50b3010 str r3, [fp, #-16]
32 C = c;
33 38: e51b3020 ldr r3, [fp, #-32]
34 3c: e50b300c str r3, [fp, #-12]
35 D = d;
36 40: e51b3024 ldr r3, [fp, #-36] ; 0x24
37 44: e50b3008 str r3, [fp, #-8]
38
39 return 0;
40 48: e3a03000 mov r3, #0
41 }
42 4c: e1a00003 mov r0, r3 ;一般函数返回都是用R0进行传递
43 50: e28bd000 add sp, fp, #0 ;sp指针重新指向栈顶
44 54: e8bd0800 pop {
fp} ;fp出栈
45 58: e12fff1e bx lr
46
47 0000005c <main>:
48 void main(void)
49 {
50 5c: e92d4800 push {
fp, lr} ;压栈之后,fp指针指向sp-4的地址
51 60: e28db004 add fp, sp, #4 ;加4之后,fp指针指向栈顶Sp
52 64: e24dd008 sub sp, sp, #8 ;栈空间大小为8个字节,具体栈分布情况见下图2
53 int a;
54 a = foo(1,2,3,4);
55 68: e3a00001 mov r0, #1
56 6c: e3a01002 mov r1, #2
57 70: e3a02003 mov r2, #3
58 74: e3a03004 mov r3, #4
59 78: ebffffe3 bl c <foo>
60 7c: e1a03000 mov r3, r0
61 80: e50b3008 str r3, [fp, #-8]
62 }
63 84: e24bd004 sub sp, fp, #4
64 88: e8bd4800 pop {
fp, lr}
65 8c: e12fff1e bx lr