Explicación detallada del push y pop del ensamblaje ARM

Referencia: https://blog.csdn.net/u012874587/article/details/78843940?utm_source=app&app_version=4.8.0
Después de leer el artículo de referencia primero, puede ser más fácil comprender algunas cosas básicas después de leerlas en el artículo anterior. ., omitido en este artículo.
El propósito de escribir este artículo es que la mayoría de los blogs simplemente publican el código ensamblador sin comentarios detallados, lo que me causó muchas dudas cuando lo leí yo mismo, así que escribí este artículo para aclarar algunas de las cosas sobre las que tengo dudas. Agregar comentarios
1. Primero, debe comprender la estructura del marco de la pila, como se muestra a continuación.
Insertar descripción de la imagen aquí
El puntero de la pila R11 generalmente es fp en ensamblador y sp apunta a la dirección de retorno
. 2. Código en lenguaje 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 }

El código de desmontaje correspondiente es

 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

Figura 1
Figura 2

Supongo que te gusta

Origin blog.csdn.net/weixin_45950842/article/details/118145070
Recomendado
Clasificación