x86、arm、mips架构栈空间分布情况分析

一、准备工作

1、相关概念

一个函数如果不再调用其他的函数,那么这个函数是叶子函数,一个函数如果调用其他的函数,那么这个函数是非叶子函数。一般来说,函数都是非叶子函数。

2、示例代码

使用不同平台的gcc进行源码编译以下代码,均不开启Stack-canary保护、栈执行保护(-fno-stack-protector -no-pie)。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

int funcB(char *A, char *B,char *C, char *D,char *E, char *F)
{
	char a[4]={'1'};
	char b[4]={'2'};
	A[0] = 'a';
	B[0] = 'b';
	C[0] = 'c';
	D[0] = 'd';
	E[0] = 'e';
	F[0] = 'f';
	return 0;
}

int funcA()
{
	char A[4] = {'A', 'A', 'A', 'A'};
	char B[4] = {'B', 'B', 'B', 'B'};
	char C[4] = {'C', 'C', 'C', 'C'};
	char D[4] = {'D', 'D', 'D', 'D'};
	char E[4] = {'E', 'E', 'E', 'E'};
	char F[4] = {'F', 'F', 'F', 'F'};

	funcB(A,B,C,D,E,F);
	return 0;
}



int main(int argc, char* argv[])
{
	funcA();
	return 0;
}

二、x86架构

1、汇编代码

.text:08049176 ; =============== S U B R O U T I N E =======================================
.text:08049176
.text:08049176 ; Attributes: bp-based frame
.text:08049176
.text:08049176 ; int __cdecl funcB(char *A, char *B, char *C, char *D, char *E, char *F)
.text:08049176                 public funcB
.text:08049176 funcB           proc near               ; CODE XREF: funcA+56↓p
.text:08049176
.text:08049176 b               = byte ptr -8
.text:08049176 a               = byte ptr -4
.text:08049176 A               = dword ptr  8
.text:08049176 B               = dword ptr  0Ch
.text:08049176 C               = dword ptr  10h
.text:08049176 D               = dword ptr  14h
.text:08049176 E               = dword ptr  18h
.text:08049176 F               = dword ptr  1Ch
.text:08049176
.text:08049176 ; __unwind {
.text:08049176                 endbr32
.text:0804917A                 push    ebp
.text:0804917B                 mov     ebp, esp
.text:0804917D                 sub     esp, 10h
.text:08049180                 call    __x86_get_pc_thunk_ax
.text:08049185                 add     eax, (offset _GLOBAL_OFFSET_TABLE_ - $)
.text:0804918A                 mov     dword ptr [ebp+a], 31h ; '1'
.text:08049191                 mov     dword ptr [ebp+b], 32h ; '2'
.text:08049198                 mov     eax, [ebp+A]
.text:0804919B                 mov     byte ptr ds:(_GLOBAL_OFFSET_TABLE_ - 804C000h)[eax], 61h ; 'a'
.text:0804919E                 mov     eax, [ebp+B]
.text:080491A1                 mov     byte ptr ds:(_GLOBAL_OFFSET_TABLE_ - 804C000h)[eax], 62h ; 'b'
.text:080491A4                 mov     eax, [ebp+C]
.text:080491A7                 mov     byte ptr ds:(_GLOBAL_OFFSET_TABLE_ - 804C000h)[eax], 63h ; 'c'
.text:080491AA                 mov     eax, [ebp+D]
.text:080491AD                 mov     byte ptr ds:(_GLOBAL_OFFSET_TABLE_ - 804C000h)[eax], 64h ; 'd'
.text:080491B0                 mov     eax, [ebp+E]
.text:080491B3                 mov     byte ptr ds:(_GLOBAL_OFFSET_TABLE_ - 804C000h)[eax], 65h ; 'e'
.text:080491B6                 mov     eax, [ebp+F]
.text:080491B9                 mov     byte ptr ds:(_GLOBAL_OFFSET_TABLE_ - 804C000h)[eax], 66h ; 'f'
.text:080491BC                 mov     eax, 0
.text:080491C1                 leave
.text:080491C2                 retn
.text:080491C2 ; } // starts at 8049176
.text:080491C2 funcB           endp
.text:080491C2
.text:080491C3
.text:080491C3 ; =============== S U B R O U T I N E =======================================
.text:080491C3
.text:080491C3 ; Attributes: bp-based frame
.text:080491C3
.text:080491C3 ; int funcA()
.text:080491C3                 public funcA
.text:080491C3 funcA           proc near               ; CODE XREF: main+11↓p
.text:080491C3
.text:080491C3 F               = byte ptr -18h
.text:080491C3 E               = byte ptr -14h
.text:080491C3 D               = byte ptr -10h
.text:080491C3 C               = byte ptr -0Ch
.text:080491C3 B               = byte ptr -8
.text:080491C3 A               = byte ptr -4
.text:080491C3
.text:080491C3 ; __unwind {
.text:080491C3                 endbr32
.text:080491C7                 push    ebp
.text:080491C8                 mov     ebp, esp
.text:080491CA                 sub     esp, 20h
.text:080491CD                 call    __x86_get_pc_thunk_ax
.text:080491D2                 add     eax, (offset _GLOBAL_OFFSET_TABLE_ - $)
.text:080491D7                 mov     dword ptr [ebp+A], 41414141h
.text:080491DE                 mov     dword ptr [ebp+B], 42424242h
.text:080491E5                 mov     dword ptr [ebp+C], 43434343h
.text:080491EC                 mov     dword ptr [ebp+D], 44444444h
.text:080491F3                 mov     dword ptr [ebp+E], 45454545h
.text:080491FA                 mov     dword ptr [ebp+F], 46464646h
.text:08049201                 lea     eax, [ebp+F]
.text:08049204                 push    eax             ; F
.text:08049205                 lea     eax, [ebp+E]
.text:08049208                 push    eax             ; E
.text:08049209                 lea     eax, [ebp+D]
.text:0804920C                 push    eax             ; D
.text:0804920D                 lea     eax, [ebp+C]
.text:08049210                 push    eax             ; C
.text:08049211                 lea     eax, [ebp+B]
.text:08049214                 push    eax             ; B
.text:08049215                 lea     eax, [ebp+A]
.text:08049218                 push    eax             ; A
.text:08049219                 call    funcB
.text:0804921E                 add     esp, 18h
.text:08049221                 mov     eax, 0
.text:08049226                 leave
.text:08049227                 retn
.text:08049227 ; } // starts at 80491C3
.text:08049227 funcA           endp
.text:08049227
.text:08049228
.text:08049228 ; =============== S U B R O U T I N E =======================================
.text:08049228
.text:08049228 ; Attributes: bp-based frame
.text:08049228
.text:08049228 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:08049228                 public main
.text:08049228 main            proc near               ; DATA XREF: _start+2A↑o
.text:08049228
.text:08049228 argc            = dword ptr  8
.text:08049228 argv            = dword ptr  0Ch
.text:08049228 envp            = dword ptr  10h
.text:08049228
.text:08049228 ; __unwind {
.text:08049228                 endbr32
.text:0804922C                 push    ebp
.text:0804922D                 mov     ebp, esp
.text:0804922F                 call    __x86_get_pc_thunk_ax
.text:08049234                 add     eax, (offset _GLOBAL_OFFSET_TABLE_ - $)
.text:08049239                 call    funcA
.text:0804923E                 mov     eax, 0
.text:08049243                 pop     ebp
.text:08049244                 retn
.text:08049244 ; } // starts at 8049228
.text:08049244 main            endp
.text:08049244
.text:08049245
.text:08049245 ; =============== S U B R O U T I N E =======================================

2、栈分布

函数名形参局部参数申请栈空间大小
main3个dword值=12字节0个0字节
funcA0个6个dword值=20字节32字节
funcB6个dword值=24字节2个dword值=8字节16字节

main->funcA->funcB时,即执行到0x000011F8(retn之前),此时栈分布如下所示:

3、传参方式

从右至左,依次压栈(F->E->D->C->B->A),call函数后,将返回地址压栈。

三、arm架构

1、汇编代码

.text:000083E4 ; =============== S U B R O U T I N E =======================================
.text:000083E4
.text:000083E4 ; Attributes: bp-based frame
.text:000083E4
.text:000083E4 ; int funcA()
.text:000083E4                 EXPORT funcA
.text:000083E4 funcA                                   ; CODE XREF: main+18↓p
.text:000083E4
.text:000083E4 var_2C          = -0x2C
.text:000083E4 var_28          = -0x28
.text:000083E4 F               = -0x24
.text:000083E4 E               = -0x20
.text:000083E4 D               = -0x1C
.text:000083E4 C               = -0x18
.text:000083E4 B               = -0x14
.text:000083E4 A               = -0x10
.text:000083E4
.text:000083E4                 MOV             R12, SP
.text:000083E8                 PUSH            {R11,R12,LR,PC}
.text:000083EC                 SUB             R11, R12, #4
.text:000083F0                 SUB             SP, SP, #0x20
.text:000083F4                 SUB             R2, R11, #-A
.text:000083F8                 MOV             R3, #0x4141
.text:00008400                 ORR             R3, R3, R3,LSL#16
.text:00008404                 STR             R3, [R2]
.text:00008408                 SUB             R2, R11, #-B
.text:0000840C                 MOV             R3, #0x4242
.text:00008414                 ORR             R3, R3, R3,LSL#16
.text:00008418                 STR             R3, [R2]
.text:0000841C                 SUB             R2, R11, #-C
.text:00008420                 MOV             R3, #0x4343
.text:00008428                 ORR             R3, R3, R3,LSL#16
.text:0000842C                 STR             R3, [R2]
.text:00008430                 SUB             R2, R11, #-D
.text:00008434                 MOV             R3, #0x4444
.text:0000843C                 ORR             R3, R3, R3,LSL#16
.text:00008440                 STR             R3, [R2]
.text:00008444                 SUB             R2, R11, #-E
.text:00008448                 MOV             R3, #0x4545
.text:00008450                 ORR             R3, R3, R3,LSL#16
.text:00008454                 STR             R3, [R2]
.text:00008458                 SUB             R2, R11, #-F
.text:0000845C                 MOV             R3, #0x4646
.text:00008464                 ORR             R3, R3, R3,LSL#16
.text:00008468                 STR             R3, [R2]
.text:0000846C                 SUB             R2, R11, #-A
.text:00008470                 SUB             R1, R11, #-B ; B
.text:00008474                 SUB             R12, R11, #-C
.text:00008478                 SUB             LR, R11, #-D
.text:0000847C                 SUB             R3, R11, #-E
.text:00008480                 STR             R3, [SP,#0x2C+var_2C] ; E
.text:00008484                 SUB             R3, R11, #-F
.text:00008488                 STR             R3, [SP,#0x2C+var_28] ; F
.text:0000848C                 MOV             R0, R2  ; A
.text:00008490                 MOV             R2, R12 ; C
.text:00008494                 MOV             R3, LR  ; D
.text:00008498                 BL              funcB
.text:0000849C                 MOV             R3, #0
.text:000084A0                 MOV             R0, R3
.text:000084A4                 SUB             SP, R11, #0xC
.text:000084A8                 LDMFD           SP, {R11,SP,PC}
.text:000084A8 ; End of function funcA
.text:000084A8
.text:000084AC
.text:000084AC ; =============== S U B R O U T I N E =======================================
.text:000084AC
.text:000084AC ; Attributes: bp-based frame
.text:000084AC
.text:000084AC ; int __cdecl funcB(unsigned __int8 *A, unsigned __int8 *B, unsigned __int8 *C, unsigned __int8 *D, unsigned __int8 *E, unsigned __int8 *F)
.text:000084AC                 EXPORT funcB
.text:000084AC funcB                                   ; CODE XREF: funcA+B4↑p
.text:000084AC
.text:000084AC D               = -0x24
.text:000084AC C               = -0x20
.text:000084AC B               = -0x1C
.text:000084AC A               = -0x18
.text:000084AC b               = -0x14
.text:000084AC a               = -0x10
.text:000084AC E               =  4
.text:000084AC F               =  8
.text:000084AC
.text:000084AC                 MOV             R12, SP
.text:000084B0                 PUSH            {R11,R12,LR,PC}
.text:000084B4                 SUB             R11, R12, #4
.text:000084B8                 SUB             SP, SP, #0x18
.text:000084BC                 STR             R0, [R11,#A]
.text:000084C0                 STR             R1, [R11,#B]
.text:000084C4                 STR             R2, [R11,#C]
.text:000084C8                 STR             R3, [R11,#D]
.text:000084CC                 LDR             R2, [R11,#A]
.text:000084D0                 MOV             R3, #0x61 ; 'a'
.text:000084D4                 STRB            R3, [R2]
.text:000084D8                 LDR             R2, [R11,#B]
.text:000084DC                 MOV             R3, #0x62 ; 'b'
.text:000084E0                 STRB            R3, [R2]
.text:000084E4                 LDR             R2, [R11,#C]
.text:000084E8                 MOV             R3, #0x63 ; 'c'
.text:000084EC                 STRB            R3, [R2]
.text:000084F0                 LDR             R2, [R11,#D]
.text:000084F4                 MOV             R3, #0x64 ; 'd'
.text:000084F8                 STRB            R3, [R2]
.text:000084FC                 LDR             R2, [R11,#E]
.text:00008500                 MOV             R3, #0x65 ; 'e'
.text:00008504                 STRB            R3, [R2]
.text:00008508                 LDR             R2, [R11,#F]
.text:0000850C                 MOV             R3, #0x66 ; 'f'
.text:00008510                 STRB            R3, [R2]
.text:00008514                 MOV             R3, #0x31 ; '1'
.text:00008518                 STRB            R3, [R11,#a]
.text:0000851C                 MOV             R3, #0x32 ; '2'
.text:00008520                 STRB            R3, [R11,#b]
.text:00008524                 MOV             R3, #0
.text:00008528                 MOV             R0, R3
.text:0000852C                 SUB             SP, R11, #0xC
.text:00008530                 LDMFD           SP, {R11,SP,PC}
.text:00008530 ; End of function funcB
.text:00008530
.text:00008534
.text:00008534 ; =============== S U B R O U T I N E =======================================
.text:00008534
.text:00008534 ; Attributes: bp-based frame
.text:00008534
.text:00008534 ; int __cdecl main(int argc, const char **argv, const char **envp)
.text:00008534                 EXPORT main
.text:00008534 main                                    ; DATA XREF: _start+20↑o
.text:00008534                                         ; .text:off_83DC↑o
.text:00008534
.text:00008534 argv            = -0x14
.text:00008534 argc            = -0x10
.text:00008534
.text:00008534                 MOV             R12, SP
.text:00008538                 PUSH            {R11,R12,LR,PC}
.text:0000853C                 SUB             R11, R12, #4
.text:00008540                 SUB             SP, SP, #8
.text:00008544                 STR             R0, [R11,#argc]
.text:00008548                 STR             R1, [R11,#argv]
.text:0000854C                 BL              funcA
.text:00008550                 MOV             R3, #0
.text:00008554                 MOV             R0, R3
.text:00008558                 SUB             SP, R11, #0xC
.text:0000855C                 LDMFD           SP, {R11,SP,PC}
.text:0000855C ; End of function main
.text:0000855C
.text:00008560
.text:00008560 ; =============== S U B R O U T I N E =======================================

2、栈分布

函数名形参局部参数申请栈空间大小
main2个dword值=8字节0个8字节
funcA0个6个dword值=20字节32字节
funcB6个dword值=24字节2个dword值=8字节16字节

main->funcA->funcB时,即执行到0x000084A0(函数末尾前),此时栈分布如下所示:

3、传参方式

前四个参数,R0->R1->R2->R3寄存器:A->B->C->D,剩余的参数从右至左,依次压栈(F->E),BL函数后,将返回地址存于LR寄存器。

四、mips架构

1、汇编代码

.text:00400710  # =============== S U B R O U T I N E =======================================
.text:00400710
.text:00400710  # Attributes: bp-based frame fpd=0x10
.text:00400710
.text:00400710  # int __cdecl funcB(char *A, char *B, char *C, char *D, char *E, char *F)
.text:00400710                 .globl funcB
.text:00400710 funcB:                                   # CODE XREF: funcA+C8↓p
.text:00400710                                          # DATA XREF: LOAD:004003A4↑o ...
.text:00400710
.text:00400710 a               = -8
.text:00400710 b               = -4
.text:00400710 var_s0          =  0
.text:00400710 A               =  8
.text:00400710 B               =  0xC
.text:00400710 C               =  0x10
.text:00400710 D               =  0x14
.text:00400710 E               =  0x18
.text:00400710 F               =  0x1C
.text:00400710
.text:00400710                 addiu   $sp, -0x18
.text:00400714                 sw      $fp, 0x10+var_s0($sp)
.text:00400718                 move    $fp, $sp
.text:0040071C                 sw      $a0, 0x10+A($fp)
.text:00400720                 sw      $a1, 0x10+B($fp)
.text:00400724                 sw      $a2, 0x10+C($fp)
.text:00400728                 sw      $a3, 0x10+D($fp)
.text:0040072C                 sw      $zero, 0x10+a($fp)
.text:00400730                 li      $v0, 0x31  # '1'
.text:00400734                 sb      $v0, 0x10+a($fp)
.text:00400738                 sw      $zero, 0x10+b($fp)
.text:0040073C                 li      $v0, 0x32  # '2'
.text:00400740                 sb      $v0, 0x10+b($fp)
.text:00400744                 lw      $v1, 0x10+A($fp)
.text:00400748                 li      $v0, 0x61  # 'a'
.text:0040074C                 sb      $v0, 0($v1)
.text:00400750                 lw      $v1, 0x10+B($fp)
.text:00400754                 li      $v0, 0x62  # 'b'
.text:00400758                 sb      $v0, 0($v1)
.text:0040075C                 lw      $v1, 0x10+C($fp)
.text:00400760                 li      $v0, 0x63  # 'c'
.text:00400764                 sb      $v0, 0($v1)
.text:00400768                 lw      $v1, 0x10+D($fp)
.text:0040076C                 li      $v0, 0x64  # 'd'
.text:00400770                 sb      $v0, 0($v1)
.text:00400774                 lw      $v1, 0x10+E($fp)
.text:00400778                 li      $v0, 0x65  # 'e'
.text:0040077C                 sb      $v0, 0($v1)
.text:00400780                 lw      $v1, 0x10+F($fp)
.text:00400784                 li      $v0, 0x66  # 'f'
.text:00400788                 sb      $v0, 0($v1)
.text:0040078C                 move    $v0, $zero
.text:00400790                 move    $sp, $fp
.text:00400794                 lw      $fp, 0x10+var_s0($sp)
.text:00400798                 addiu   $sp, 0x18
.text:0040079C                 jr      $ra
.text:004007A0                 nop
.text:004007A0  # End of function funcB
.text:004007A0
.text:004007A4
.text:004007A4  # =============== S U B R O U T I N E =======================================
.text:004007A4
.text:004007A4  # Attributes: bp-based frame fpd=0x38
.text:004007A4
.text:004007A4  # int funcA()
.text:004007A4                 .globl funcA
.text:004007A4 funcA:                                   # CODE XREF: main+30↓p
.text:004007A4                                          # DATA XREF: LOAD:00400384↑o ...
.text:004007A4
.text:004007A4 var_28          = -0x28
.text:004007A4 var_24          = -0x24
.text:004007A4 var_20          = -0x20
.text:004007A4 A               = -0x18
.text:004007A4 B               = -0x14
.text:004007A4 C               = -0x10
.text:004007A4 D               = -0xC
.text:004007A4 E               = -8
.text:004007A4 F               = -4
.text:004007A4 var_s0          =  0
.text:004007A4 var_s4          =  4
.text:004007A4
.text:004007A4                 li      $gp, (_GLOBAL_OFFSET_TABLE_+0x7FF0 - .)
.text:004007AC                 addu    $gp, $t9
.text:004007B0                 addiu   $sp, -0x40
.text:004007B4                 sw      $ra, 0x38+var_s4($sp)
.text:004007B8                 sw      $fp, 0x38+var_s0($sp)
.text:004007BC                 move    $fp, $sp
.text:004007C0                 sw      $gp, 0x38+var_20($sp)
.text:004007C4                 li      $v0, 0x400000
.text:004007C8                 nop
.text:004007CC                 lw      $v0, (C_0_2411 - 0x400000)($v0)
.text:004007D0                 nop
.text:004007D4                 sw      $v0, 0x38+A($fp)
.text:004007D8                 li      $v0, 0x400000
.text:004007DC                 nop
.text:004007E0                 lw      $v0, (C_1_2412 - 0x400000)($v0)
.text:004007E4                 nop
.text:004007E8                 sw      $v0, 0x38+B($fp)
.text:004007EC                 li      $v0, 0x400000
.text:004007F0                 nop
.text:004007F4                 lw      $v0, (C_2_2413 - 0x400000)($v0)
.text:004007F8                 nop
.text:004007FC                 sw      $v0, 0x38+C($fp)
.text:00400800                 li      $v0, 0x400000
.text:00400804                 nop
.text:00400808                 lw      $v0, (C_3_2414 - 0x400000)($v0)
.text:0040080C                 nop
.text:00400810                 sw      $v0, 0x38+D($fp)
.text:00400814                 li      $v0, 0x400000
.text:00400818                 nop
.text:0040081C                 lw      $v0, (C_4_2415 - 0x400000)($v0)
.text:00400820                 nop
.text:00400824                 sw      $v0, 0x38+E($fp)
.text:00400828                 li      $v0, 0x400000
.text:0040082C                 nop
.text:00400830                 lw      $v0, (C_5_2416 - 0x400000)($v0)
.text:00400834                 nop
.text:00400838                 sw      $v0, 0x38+F($fp)
.text:0040083C                 addiu   $v1, $fp, 0x38+B
.text:00400840                 addiu   $a2, $fp, 0x38+C  # C
.text:00400844                 addiu   $a3, $fp, 0x38+D  # D
.text:00400848                 addiu   $v0, $fp, 0x38+E
.text:0040084C                 sw      $v0, 0x38+var_28($sp)  # E
.text:00400850                 addiu   $v0, $fp, 0x38+F
.text:00400854                 sw      $v0, 0x38+var_24($sp)  # F
.text:00400858                 addiu   $v0, $fp, 0x38+A
.text:0040085C                 move    $a0, $v0         # A
.text:00400860                 move    $a1, $v1         # B
.text:00400864                 la      $t9, funcB
.text:00400868                 nop
.text:0040086C                 jalr    $t9 ; funcB
.text:00400870                 nop
.text:00400874                 lw      $gp, 0x38+var_20($fp)
.text:00400878                 move    $v0, $zero
.text:0040087C                 move    $sp, $fp
.text:00400880                 lw      $ra, 0x38+var_s4($sp)
.text:00400884                 lw      $fp, 0x38+var_s0($sp)
.text:00400888                 addiu   $sp, 0x40
.text:0040088C                 jr      $ra
.text:00400890                 nop
.text:00400890  # End of function funcA
.text:00400890
.text:00400894
.text:00400894  # =============== S U B R O U T I N E =======================================
.text:00400894
.text:00400894  # Attributes: bp-based frame fpd=0x18
.text:00400894
.text:00400894  # int __cdecl main(int argc, const char **argv, const char **envp)
.text:00400894                 .globl main
.text:00400894 main:                                    # DATA XREF: LOAD:004003B4↑o
.text:00400894                                          # __start+1C↑o ...
.text:00400894
.text:00400894 var_8           = -8
.text:00400894 var_s0          =  0
.text:00400894 var_s4          =  4
.text:00400894 argc            =  8
.text:00400894 argv            =  0xC
.text:00400894
.text:00400894                 li      $gp, (_GLOBAL_OFFSET_TABLE_+0x7FF0 - .)
.text:0040089C                 addu    $gp, $t9
.text:004008A0                 addiu   $sp, -0x20
.text:004008A4                 sw      $ra, 0x18+var_s4($sp)
.text:004008A8                 sw      $fp, 0x18+var_s0($sp)
.text:004008AC                 move    $fp, $sp
.text:004008B0                 sw      $gp, 0x18+var_8($sp)
.text:004008B4                 sw      $a0, 0x18+argc($fp)
.text:004008B8                 sw      $a1, 0x18+argv($fp)
.text:004008BC                 la      $t9, funcA
.text:004008C0                 nop
.text:004008C4                 jalr    $t9 ; funcA
.text:004008C8                 nop
.text:004008CC                 lw      $gp, 0x18+var_8($fp)
.text:004008D0                 move    $v0, $zero
.text:004008D4                 move    $sp, $fp
.text:004008D8                 lw      $ra, 0x18+var_s4($sp)
.text:004008DC                 lw      $fp, 0x18+var_s0($sp)
.text:004008E0                 addiu   $sp, 0x20
.text:004008E4                 jr      $ra
.text:004008E8                 nop
.text:004008E8  # End of function main
.text:004008E8
.text:004008E8  # ---------------------------------------------------------------------------
.text:004008EC                 .align 4
.text:004008F0
.text:004008F0  # =============== S U B R O U T I N E =======================================

2、栈分布

函数名形参局部参数申请栈空间大小
main2个dword值=8字节0个32字节
funcA0个6个dword值=20字节64字节
funcB6个dword值=24字节2个dword值=8字节24字节

main->funcA->funcB时,即执行到0x00400798(函数末尾前),此时栈分布如下所示:

3、传参方式

前四个参数,a0->a1->a2->a3寄存器:A->B->C->D,剩余的参数从右至左,依次压栈(F->E),jalr函数后,将返回地址存于ra寄存器。

五、总结

架构x86armmips
运行到funB末尾前消耗栈空间0x6C 字节0x70 字节0x80 字节
传参方式从左至右压栈,其次返回地址压栈前4个参数从左至右存入R0-R3寄存器,剩余参数从右至左压栈,其次返回地址存入LR寄存器前4个参数从左至右存入a0-a3寄存器,剩余参数从右至左压栈,其次返回地址存入ra寄存器
栈操作使用push、pop的方式使用push、pop的方式内存地址操作
函数返回方式调用call的时候返回地址存于栈
call funA
...
retn
返回地址在LR
PUSH {R11,R12,LR,PC}
...
LDMFD SP, {R11,SP,PC}
叶子函数(funA)和非叶子函数(funB)在存放返回地址的时候,存在差异。
叶子函数只把返回地址保存在$ra寄存其中,结束函数调用的时候,通过jr $ra指令返回即可。
非叶子函数把在函数调用初始把$ra寄存器中的返回地址保存在栈中,然后结束函数调用的时候将栈中保存的返回地址加载到$ra寄存器中,再通过jr $ra指令返回。

六、参考链接

https://www.cnblogs.com/L0g4n-blog/p/13968404.html

留下评论

您的电子邮箱地址不会被公开。 必填项已用*标注