Подробное объяснение push и pop сборки ARM.

Ссылка: https://blog.csdn.net/u012874587/article/details/78843940?utm_source=app&app_version=4.8.0
. После прочтения справочной статьи вам может быть легче понять некоторые основные вещи, прочитав их в предыдущей статье. ., исключено из этой статьи.
Цель написания этой статьи состоит в том, что большинство блогов просто публикуют ассемблерный код без подробных комментариев, что вызвало у меня массу сомнений, когда я сам его прочитал, поэтому я написал эту статью, чтобы прояснить некоторые моменты, в которых у меня есть сомнения. Добавить комментарии
1. Во-первых, вы должны понять структуру фрейма стека, как показано ниже.
Вставьте сюда описание изображения
Указатель стека R11 обычно имеет значение fp в ассемблере, а sp указывает на адрес возврата
. 2. Код языка 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 }

Соответствующий код дизассемблирования:

 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

Рисунок 1
фигура 2

Guess you like

Origin blog.csdn.net/weixin_45950842/article/details/118145070