函式堆疊平衡

2022-02-02 07:35:59 字數 4435 閱讀 8859

int func(int a,int b,int c, int

d)01243d10

popedi

01243d11

popesi

01243d12

popebx

01243d13

movesp,ebp

01243d15

popebp

01243d16

retint

main()

01241b83

popedi

01241b84

popesi

01241b85

popebx

01241b86

addesp,0cch

01241b8c

cmpebp,esp

01241b8e

call

__rtc_checkesp (01241140h)

01241b93

movesp,ebp

01241b95

popebp

01241b96

ret

看上面劃線部分,很明顯是 _cdecl 呼叫方式,呼叫方平衡堆疊。

下面來看看 _stdcall 呼叫方式,這是被呼叫方平衡堆疊。

int_stdcallfunc(int a,int b,int c, int

d)010c3d10

popedi

010c3d11

popesi

010c3d12

popebx

010c3d13

movesp,ebp

010c3d15

popebp

010c3d16

ret10h

intmain()

010c1b80

popedi

010c1b81

popesi

010c1b82

popebx

010c1b83

addesp,0cch

010c1b89

cmpebp,esp

010c1b8b

call

__rtc_checkesp (010c1140h)

010c1b90

movesp,ebp

010c1b92

popebp

010c1b93

ret

下面看看win下x64(linux與此不同):

在x64下函式呼叫的前4個引數總是放在暫存器中傳遞,剩餘的引數則壓入堆疊中。

而x86上則是全部壓入堆疊中(除了fastcall方式)。這4個用於存放引數的暫存器分別是

:存放整數引數的rcx,rdx,r8,r9。

存放浮點數引數的xmm0,xmm1,xmm2,xmm3。

double func3(double a,double b,double c, double d)

000000013fd83290

addrsp,20h

000000013fd83294

poprdi

000000013fd83295

retint func2(int a,int b,int c, int d,int e,int

f)000000013fd832ec

addrsp,10h

000000013fd832f0

poprdi

000000013fd832f1

retint func(int a,int b,int c, int

d)000000013fd83344

addrsp,10h

000000013fd83348

poprdi

000000013fd83349

retint

main()

000000013fd833e0

addrsp,40h

000000013fd833e4

poprdi

000000013fd833e5

ret

下面摘自:

;

int __cdecl main()

main proc near

var_28= dword ptr -28h ;40

var_20= dword ptr -20h ;

32var_18= dword ptr -18h ;

24 x

var_14= dword ptr -14h ;

20 y

var_10= qword ptr -10h ;

16 z

push

rdisub rsp, 40h ;

64mov

rdi, rsp

movecx, 10h

moveax, 0cccccccch

repstosd

mov r9d, 4;d

mov r8d, 3;c

mov edx, 2;b

mov ecx, 1;a

call j_?func@@yahhhhh@z ;

func(int,int,int,int)

mov [rsp+48h+var_18], eax ;

xmov [rsp+48h+var_20], 6

mov [rsp+48h+var_28], 5

mov r9d, 4;d

mov r8d, 3;c

mov edx, 2;b

mov ecx, 1;a

call j_?func2@@yahhhhhhh@z ;

func2(int,int,int,int,int,int)

mov [rsp+48h+var_14], eax ;

ymovsd xmm3, cs:

__real@4010000000000000

movsd xmm2, cs:

__real@4008000000000000

movsd xmm1, cs:

__real@4000000000000000

movsd xmm0, cs:

__real@3ff0000000000000

call j_?func2@@yannnnn@z ;

func2(double,double,double,double)

movsd [rsp+48h+var_10], xmm0 ;

zxor

eax, eax

addrsp, 40h

poprdi

retn

main endp

func2:

int __cdecl func2(int a, int b, int c, int d, int e, int f)

?func2@@yahhhhhhh@z proc near

var_18= dword ptr -18h

arg_0= dword ptr

8arg_8= dword ptr 10h

arg_10= dword ptr 18h

arg_18= dword ptr 20h

e= dword ptr 28h

f= dword ptr 30h

mov[rsp+arg_18], r9d

mov[rsp+arg_10], r8d

mov[rsp+arg_8], edx

mov[rsp+arg_0], ecx

push

rdisub

rsp, 10h

movrdi, rsp

mov ecx, 4

moveax, 0cccccccch

repstosd

movecx, [rsp+18h+arg_0]

moveax, [rsp+18h+arg_8]

movecx, [rsp+18h+arg_0]

addecx, eax

moveax, ecx

addeax, [rsp+18h+arg_10]

addeax, [rsp+18h+arg_18]

addeax, [rsp+18h+e]

addeax, [rsp+18h+f]

mov[rsp+18h+var_18], eax

moveax, [rsp+18h+var_18]

addrsp, 10h

poprdi

retn

?func2@@yahhhhhhh@z endp

記憶體中的堆疊 堆疊平衡

1 記憶體中的堆疊使用是先從 高位的位址 到 低位的位址 使用 儲存的。2 堆疊使用的時候,最後需要進行堆疊平衡,也就是去平衡esp中暫存器儲存的值 3 esp暫存器中儲存的值對應的就是當前堆疊使用的位置 4 如果當前的壓入的堆疊資料 不是通過push指令 後面不需要的話,一般就是在sub esp,...

彙編堆疊平衡的幾種方式

任何程式在執行過程中都需要使用堆疊,作業系統為每乙個程式 程序及執行緒 設定乙個堆疊。在使用高階語言程式設計時,源程式中使用的函式呼叫 區域性變數都要用到堆疊,由編譯器來負責生成有關的機器指令。我的理解,堆疊就是維護當前執行緒中執行狀態的乙個資料結構,這種狀態包括 需要傳遞的變數,函式的返回位址,區...

堆空間 棧空間和堆疊平衡

堆 heap 與棧 stack 是程式儲存空間上的一組概念。應用程式啟動時 程式啟動時,windows的pe裝載器會將pe檔案 可執行檔案,unix linux 上是elf 的不同部分的內容裝入不同的記憶體區域。程式的資料段包括.data段 全域性變數 和.rdata段 靜態變數和常量 而pe裝載器...