void mySwap( int a , int b )
{
int tmp ;
tmp = a ;
a = b ;
b = tmp ;
}
int main(int argc, char* argv[])
{
int a = 1 ;
int b = 2 ;
mySwap( a , b ) ;
return 0;
}
void mySwap( int * a , int * b )
{
int tmp ;
tmp = *a ;
*a = *b ;
*b = tmp ;
}
int main(int argc, char* argv[])
{
int a = 1 ;
int b = 2 ;
mySwap( &a , &b ) ;
return 0;
}
void mySwap( int & a , int & b )
{
int tmp ;
tmp = a ;
a = b ;
b = tmp ;
}
int main(int argc, char* argv[])
{
int a = 1 ;
int b = 2 ;
mySwap( a , b ) ;
return 0;
}
分析上面3段代码,我们来分析其编译后是上面情况,所以使用IDA反汇编来进行分析。
1.指针
.text:00401020 mySwap proc near ; CODE XREF: j_mySwapj
.text:00401020
.text:00401020 var_44 = byte ptr -44h
.text:00401020 var_4 = dword ptr -4
.text:00401020 arg_0 = dword ptr 8
.text:00401020 arg_4 = dword ptr 0Ch
.text:00401020
.text:00401020 push ebp
.text:00401021 mov ebp, esp
.text:00401023 sub esp, 44h
.text:00401026 push ebx
.text:00401027 push esi
.text:00401028 push edi
.text:00401029 lea edi, [ebp+var_44]
.text:0040102C mov ecx, 11h
.text:00401031 mov eax, 0CCCCCCCCh
.text:00401036 rep stosd
.text:00401038 mov eax, [ebp+arg_0]
.text:0040103B mov ecx, [eax]
.text:0040103D mov [ebp+var_4], ecx
.text:00401040 mov edx, [ebp+arg_0]
.text:00401043 mov eax, [ebp+arg_4]
.text:00401046 mov ecx, [eax]
.text:00401048 mov [edx], ecx
.text:0040104A mov edx, [ebp+arg_4]
.text:0040104D mov eax, [ebp+var_4]
.text:00401050 mov [edx], eax
.text:00401052 pop edi
.text:00401053 pop esi
.text:00401054 pop ebx
.text:00401055 mov esp, ebp
.text:00401057 pop ebp
.text:00401058 retn
.text:00401058 mySwap endp
.text:00401070 main proc near ; CODE XREF: _mainj
.text:00401070
.text:00401070 var_48 = byte ptr -48h
.text:00401070 var_8 = dword ptr -8
.text:00401070 var_4 = dword ptr -4
.text:00401070
.text:00401070 push ebp
.text:00401071 mov ebp, esp
.text:00401073 sub esp, 48h
.text:00401076 push ebx
.text:00401077 push esi
.text:00401078 push edi
.text:00401079 lea edi, [ebp+var_48]
.text:0040107C mov ecx, 12h
.text:00401081 mov eax, 0CCCCCCCCh
.text:00401086 rep stosd
.text:00401088 mov [ebp+var_4], 1
.text:0040108F mov [ebp+var_8], 2
.text:00401096 lea eax, [ebp+var_8]
.text:00401099 push eax
.text:0040109A lea ecx, [ebp+var_4]
.text:0040109D push ecx
.text:0040109E call j_mySwap
.text:004010A3 add esp, 8
.text:004010A6 xor eax, eax
.text:004010A8 pop edi
.text:004010A9 pop esi
.text:004010AA pop ebx
.text:004010AB add esp, 48h
.text:004010AE cmp ebp, esp
.text:004010B0 call __chkesp
.text:004010B5 mov esp, ebp
.text:004010B7 pop ebp
.text:004010B8 retn
.text:004010B8 main endp
(2)引用
.text:00401020 sub_401020 proc near ; CODE XREF: sub_401005j
.text:00401020
.text:00401020 var_44 = byte ptr -44h
.text:00401020 var_4 = dword ptr -4
.text:00401020 arg_0 = dword ptr 8
.text:00401020 arg_4 = dword ptr 0Ch
.text:00401020
.text:00401020 push ebp
.text:00401021 mov ebp, esp
.text:00401023 sub esp, 44h
.text:00401026 push ebx
.text:00401027 push esi
.text:00401028 push edi
.text:00401029 lea edi, [ebp+var_44]
.text:0040102C mov ecx, 11h
.text:00401031 mov eax, 0CCCCCCCCh
.text:00401036 rep stosd
.text:00401038 mov eax, [ebp+arg_0]
.text:0040103B mov ecx, [eax]
.text:0040103D mov [ebp+var_4], ecx
.text:00401040 mov edx, [ebp+arg_0]
.text:00401043 mov eax, [ebp+arg_4]
.text:00401046 mov ecx, [eax]
.text:00401048 mov [edx], ecx
.text:0040104A mov edx, [ebp+arg_4]
.text:0040104D mov eax, [ebp+var_4]
.text:00401050 mov [edx], eax
.text:00401052 pop edi
.text:00401053 pop esi
.text:00401054 pop ebx
.text:00401055 mov esp, ebp
.text:00401057 pop ebp
.text:00401058 retn
.text:00401058 sub_401020 endp
.text:00401070 _main_0 proc near ; CODE XREF: _mainj
.text:00401070
.text:00401070 var_48 = byte ptr -48h
.text:00401070 var_8 = dword ptr -8
.text:00401070 var_4 = dword ptr -4
.text:00401070
.text:00401070 push ebp
.text:00401071 mov ebp, esp
.text:00401073 sub esp, 48h
.text:00401076 push ebx
.text:00401077 push esi
.text:00401078 push edi
.text:00401079 lea edi, [ebp+var_48]
.text:0040107C mov ecx, 12h
.text:00401081 mov eax, 0CCCCCCCCh
.text:00401086 rep stosd
.text:00401088 mov [ebp+var_4], 1
.text:0040108F mov [ebp+var_8], 2
.text:00401096 lea eax, [ebp+var_8]
.text:00401099 push eax
.text:0040109A lea ecx, [ebp+var_4]
.text:0040109D push ecx
.text:0040109E call sub_401005
.text:004010A3 add esp, 8
.text:004010A6 xor eax, eax
.text:004010A8 pop edi
.text:004010A9 pop esi
.text:004010AA pop ebx
.text:004010AB add esp, 48h
.text:004010AE cmp ebp, esp
.text:004010B0 call __chkesp
.text:004010B5 mov esp, ebp
.text:004010B7 pop ebp
.text:004010B8 retn
.text:004010B8 _main_0 endp
(3)值传递调用
.text:00401020 mySwap proc near ; CODE XREF: j_mySwapj
.text:00401020
.text:00401020 var_44 = byte ptr -44h
.text:00401020 var_4 = dword ptr -4
.text:00401020 arg_0 = dword ptr 8
.text:00401020 arg_4 = dword ptr 0Ch
.text:00401020
.text:00401020 push ebp
.text:00401021 mov ebp, esp
.text:00401023 sub esp, 44h
.text:00401026 push ebx
.text:00401027 push esi
.text:00401028 push edi
.text:00401029 lea edi, [ebp+var_44]
.text:0040102C mov ecx, 11h
.text:00401031 mov eax, 0CCCCCCCCh
.text:00401036 rep stosd
.text:00401038 mov eax, [ebp+arg_0]
.text:0040103B mov [ebp+var_4], eax
.text:0040103E mov ecx, [ebp+arg_4]
.text:00401041 mov [ebp+arg_0], ecx
.text:00401044 mov edx, [ebp+var_4]
.text:00401047 mov [ebp+arg_4], edx
.text:0040104A pop edi
.text:0040104B pop esi
.text:0040104C pop ebx
.text:0040104D mov esp, ebp
.text:0040104F pop ebp
.text:00401050 retn
.text:00401050 mySwap endp
.text:00401060 main proc near ; CODE XREF: _mainj
.text:00401060
.text:00401060 var_48 = byte ptr -48h
.text:00401060 var_8 = dword ptr -8
.text:00401060 var_4 = dword ptr -4
.text:00401060
.text:00401060 push ebp
.text:00401061 mov ebp, esp
.text:00401063 sub esp, 48h
.text:00401066 push ebx
.text:00401067 push esi
.text:00401068 push edi
.text:00401069 lea edi, [ebp+var_48]
.text:0040106C mov ecx, 12h
.text:00401071 mov eax, 0CCCCCCCCh
.text:00401076 rep stosd
.text:00401078 mov [ebp+var_4], 1
.text:0040107F mov [ebp+var_8], 2
.text:00401086 mov eax, [ebp+var_8]
.text:00401089 push eax
.text:0040108A mov ecx, [ebp+var_4]
.text:0040108D push ecx
.text:0040108E call j_mySwap
.text:00401093 add esp, 8
.text:00401096 xor eax, eax
.text:00401098 pop edi
.text:00401099 pop esi
.text:0040109A pop ebx
.text:0040109B add esp, 48h
.text:0040109E cmp ebp, esp
.text:004010A0 call __chkesp
.text:004010A5 mov esp, ebp
.text:004010A7 pop ebp
.text:004010A8 retn
.text:004010A8 main endp
得到结论:
指针与引用的参数传递都是传的地址,属于地址传递,一般的值传递传的是值,在值传递的情况下,主函数与子函数的栈的地址不一样,所以即使在子函数中进行了值交换,但是还是没有改变主函数栈中的值。