int func(int a,int b,int c, intd)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, intd)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 -18harg_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裝載器...