call 参数push问题。
想问各位大佬,当call一个函数传参数的时候,先将参数push入栈,当函数调用的完成之后,只需要将栈平衡就可以,不需要将参数数pop出栈。但是在c中实参在函数调用完成之后实参的值就会被还原,这是不是就意味着实参push栈中,还是会把实参在pop出来吧?还是说在去内存中把之前的实参变量值在读一遍?
小弟刚刚看汇编求大佬解答!! 自顶一下哈 都已经学了汇编语言了,那就给你一个代码,自己看
自己去分析堆栈上面的参数是如何传递的
int main(void) {
00DC1810push ebp
00DC1811mov ebp,esp
00DC1813sub esp,0D8h
00DC1819push ebx
00DC181Apush esi
00DC181Bpush edi
00DC181Clea edi,
00DC1822mov ecx,36h
00DC1827mov eax,0CCCCCCCCh
00DC182Crep stos dword ptr es:
00DC182Emov ecx,offset _8A2E5209_main@c (0DCC003h)
00DC1833call @__CheckForDebuggerJustMyCode@4 (0DC1217h)
int a = 12;
00DC1838mov dword ptr ,0Ch
int b = 13;
00DC183Fmov dword ptr ,0Dh
test(a, b);
00DC1846mov eax,dword ptr
00DC1849push eax
00DC184Amov ecx,dword ptr
00DC184Dpush ecx
00DC184Ecall _test (0DC1389h)
00DC1853add esp,8
return 0;
00DC1856xor eax,eax
}
void test(int a, int b) {
00DC1F70push ebp
00DC1F71mov ebp,esp
00DC1F73sub esp,0C0h
00DC1F79push ebx
00DC1F7Apush esi
00DC1F7Bpush edi
00DC1F7Clea edi,
00DC1F82mov ecx,30h
00DC1F87mov eax,0CCCCCCCCh
00DC1F8Crep stos dword ptr es:
00DC1F8Emov ecx,offset _8A2E5209_main@c (0DCC003h)
00DC1F93call @__CheckForDebuggerJustMyCode@4 (0DC1217h)
a = a + 1;
00DC1F98mov eax,dword ptr
00DC1F9Badd eax,1
00DC1F9Emov dword ptr ,eax
b = b + 1;
00DC1FA1mov eax,dword ptr
00DC1FA4add eax,1
00DC1FA7mov dword ptr ,eax
printf("%d %d\n", a, b);
00DC1FAAmov eax,dword ptr
00DC1FADpush eax
00DC1FAEmov ecx,dword ptr
00DC1FB1push ecx
00DC1FB2push offset string "hello\n" (0DC7B30h)
00DC1FB7call _printf (0DC1046h)
00DC1FBCadd esp,0Ch
}
这个是去掉符号名的版本
int main(void) {
00DC1810push ebp
00DC1811mov ebp,esp
00DC1813sub esp,0D8h
00DC1819push ebx
00DC181Apush esi
00DC181Bpush edi
00DC181Clea edi,
00DC1822mov ecx,36h
00DC1827mov eax,0CCCCCCCCh
00DC182Crep stos dword ptr es:
00DC182Emov ecx,0DCC003h
00DC1833call 00DC1217
int a = 12;
00DC1838mov dword ptr ,0Ch
int b = 13;
00DC183Fmov dword ptr ,0Dh
test(a, b);
00DC1846mov eax,dword ptr
00DC1849push eax
00DC184Amov ecx,dword ptr
00DC184Dpush ecx
00DC184Ecall 00DC1389
00DC1853add esp,8
return 0;
00DC1856xor eax,eax
}
void test(int a, int b) {
00DC1F70push ebp
00DC1F71mov ebp,esp
00DC1F73sub esp,0C0h
00DC1F79push ebx
00DC1F7Apush esi
00DC1F7Bpush edi
00DC1F7Clea edi,
00DC1F82mov ecx,30h
00DC1F87mov eax,0CCCCCCCCh
00DC1F8Crep stos dword ptr es:
00DC1F8Emov ecx,0DCC003h
00DC1F93call 00DC1217
a = a + 1;
00DC1F98mov eax,dword ptr
00DC1F9Badd eax,1
00DC1F9Emov dword ptr ,eax
b = b + 1;
00DC1FA1mov eax,dword ptr
00DC1FA4add eax,1
00DC1FA7mov dword ptr ,eax
printf("%d %d\n", a, b);
00DC1FAAmov eax,dword ptr
00DC1FADpush eax
00DC1FAEmov ecx,dword ptr
00DC1FB1push ecx
00DC1FB2push 0DC7B30h
00DC1FB7call 00DC1046
00DC1FBCadd esp,0Ch
} 看懂上面的代码后,再看指针的,去分析堆栈上面的参数
学会学习,多画图,多思考
#include <stdio.h>
void test(int *a) {
*a += 1;
}
int main(void) {
int a = 12;
test(&a);
printf("%d\n", a);
return 0;
}
本帖最后由 newlyh1992 于 2020-4-27 14:37 编辑
人造人 发表于 2020-4-27 12:39
看懂上面的代码后,再看指针的,去分析堆栈上面的参数
学会学习,多画图,多思考
如何把参数传递给下一个函数,我知道。
假如
int a(int a){
return a + 1;
}
int main(void){
int a = 1;
a(a);
printf("%d\n", a);
}
问题在,main函数调用a(); 这个是变量a应该会被压栈,当main函数调用完a();时,变量a应该是再从栈中把之前的值进行还原,但是再汇编的代码中,我没有看到pop的指令,只看到一个add esp,4的平衡栈的指令。 那变量a的值是如何还原的呢? 不需要还原好吗!谁告诉你原值push了,它就被删了?它还好好的在那里好吗!你push个ax看看,ax还在不在?何况实参是在内存中的。不动它根本就不会改。
页:
[1]