鱼C论坛

 找回密码
 立即注册
查看: 3466|回复: 5

call 参数push问题。

[复制链接]
发表于 2020-4-27 12:08:11 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
想问各位大佬,
当call一个函数传参数的时候,先将参数push入栈,当函数调用的完成之后,只需要将栈平衡就可以,不需要将参数数pop出栈。但是在c中实参在函数调用完成之后实参的值就会被还原,这是不是就意味着实参push栈中,还是会把实参在pop出来吧?还是说在去内存中把之前的实参变量值在读一遍?
小弟刚刚看汇编求大佬解答!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2020-4-27 12:09:02 | 显示全部楼层
自顶一下哈
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-27 12:35:26 | 显示全部楼层
都已经学了汇编语言了,那就给你一个代码,自己看
自己去分析堆栈上面的参数是如何传递的

  1. int main(void) {
  2. 00DC1810  push        ebp  
  3. 00DC1811  mov         ebp,esp  
  4. 00DC1813  sub         esp,0D8h  
  5. 00DC1819  push        ebx  
  6. 00DC181A  push        esi  
  7. 00DC181B  push        edi  
  8. 00DC181C  lea         edi,[ebp-0D8h]  
  9. 00DC1822  mov         ecx,36h  
  10. 00DC1827  mov         eax,0CCCCCCCCh  
  11. 00DC182C  rep stos    dword ptr es:[edi]  
  12. 00DC182E  mov         ecx,offset _8A2E5209_main@c (0DCC003h)  
  13. 00DC1833  call        @__CheckForDebuggerJustMyCode@4 (0DC1217h)  
  14.     int a = 12;
  15. 00DC1838  mov         dword ptr [a],0Ch  
  16.     int b = 13;
  17. 00DC183F  mov         dword ptr [b],0Dh  
  18.     test(a, b);
  19. 00DC1846  mov         eax,dword ptr [b]  
  20. 00DC1849  push        eax  
  21. 00DC184A  mov         ecx,dword ptr [a]  
  22. 00DC184D  push        ecx  
  23. 00DC184E  call        _test (0DC1389h)  
  24. 00DC1853  add         esp,8  
  25.     return 0;
  26. 00DC1856  xor         eax,eax  
  27. }

  28. void test(int a, int b) {
  29. 00DC1F70  push        ebp  
  30. 00DC1F71  mov         ebp,esp  
  31. 00DC1F73  sub         esp,0C0h  
  32. 00DC1F79  push        ebx  
  33. 00DC1F7A  push        esi  
  34. 00DC1F7B  push        edi  
  35. 00DC1F7C  lea         edi,[ebp-0C0h]  
  36. 00DC1F82  mov         ecx,30h  
  37. 00DC1F87  mov         eax,0CCCCCCCCh  
  38. 00DC1F8C  rep stos    dword ptr es:[edi]  
  39. 00DC1F8E  mov         ecx,offset _8A2E5209_main@c (0DCC003h)  
  40. 00DC1F93  call        @__CheckForDebuggerJustMyCode@4 (0DC1217h)  
  41.     a = a + 1;
  42. 00DC1F98  mov         eax,dword ptr [a]  
  43. 00DC1F9B  add         eax,1  
  44. 00DC1F9E  mov         dword ptr [a],eax  
  45.     b = b + 1;
  46. 00DC1FA1  mov         eax,dword ptr [b]  
  47. 00DC1FA4  add         eax,1  
  48. 00DC1FA7  mov         dword ptr [b],eax  
  49.     printf("%d %d\n", a, b);
  50. 00DC1FAA  mov         eax,dword ptr [b]  
  51. 00DC1FAD  push        eax  
  52. 00DC1FAE  mov         ecx,dword ptr [a]  
  53. 00DC1FB1  push        ecx  
  54. 00DC1FB2  push        offset string "hello\n" (0DC7B30h)  
  55. 00DC1FB7  call        _printf (0DC1046h)  
  56. 00DC1FBC  add         esp,0Ch  
  57. }
复制代码




这个是去掉符号名的版本
  1. int main(void) {
  2. 00DC1810  push        ebp  
  3. 00DC1811  mov         ebp,esp  
  4. 00DC1813  sub         esp,0D8h  
  5. 00DC1819  push        ebx  
  6. 00DC181A  push        esi  
  7. 00DC181B  push        edi  
  8. 00DC181C  lea         edi,[ebp+FFFFFF28h]  
  9. 00DC1822  mov         ecx,36h  
  10. 00DC1827  mov         eax,0CCCCCCCCh  
  11. 00DC182C  rep stos    dword ptr es:[edi]  
  12. 00DC182E  mov         ecx,0DCC003h  
  13. 00DC1833  call        00DC1217  
  14.     int a = 12;
  15. 00DC1838  mov         dword ptr [ebp-8],0Ch  
  16.     int b = 13;
  17. 00DC183F  mov         dword ptr [ebp-14h],0Dh  
  18.     test(a, b);
  19. 00DC1846  mov         eax,dword ptr [ebp-14h]  
  20. 00DC1849  push        eax  
  21. 00DC184A  mov         ecx,dword ptr [ebp-8]  
  22. 00DC184D  push        ecx  
  23. 00DC184E  call        00DC1389  
  24. 00DC1853  add         esp,8  
  25.     return 0;
  26. 00DC1856  xor         eax,eax  
  27. }

  28. void test(int a, int b) {
  29. 00DC1F70  push        ebp  
  30. 00DC1F71  mov         ebp,esp  
  31. 00DC1F73  sub         esp,0C0h  
  32. 00DC1F79  push        ebx  
  33. 00DC1F7A  push        esi  
  34. 00DC1F7B  push        edi  
  35. 00DC1F7C  lea         edi,[ebp+FFFFFF40h]  
  36. 00DC1F82  mov         ecx,30h  
  37. 00DC1F87  mov         eax,0CCCCCCCCh  
  38. 00DC1F8C  rep stos    dword ptr es:[edi]  
  39. 00DC1F8E  mov         ecx,0DCC003h  
  40. 00DC1F93  call        00DC1217  
  41.     a = a + 1;
  42. 00DC1F98  mov         eax,dword ptr [ebp+8]  
  43. 00DC1F9B  add         eax,1  
  44. 00DC1F9E  mov         dword ptr [ebp+8],eax  
  45.     b = b + 1;
  46. 00DC1FA1  mov         eax,dword ptr [ebp+0Ch]  
  47. 00DC1FA4  add         eax,1  
  48. 00DC1FA7  mov         dword ptr [ebp+0Ch],eax  
  49.     printf("%d %d\n", a, b);
  50. 00DC1FAA  mov         eax,dword ptr [ebp+0Ch]  
  51. 00DC1FAD  push        eax  
  52. 00DC1FAE  mov         ecx,dword ptr [ebp+8]  
  53. 00DC1FB1  push        ecx  
  54. 00DC1FB2  push        0DC7B30h  
  55. 00DC1FB7  call        00DC1046  
  56. 00DC1FBC  add         esp,0Ch  
  57. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-27 12:39:15 | 显示全部楼层
看懂上面的代码后,再看指针的,去分析堆栈上面的参数
学会学习,多画图,多思考

  1. #include <stdio.h>

  2. void test(int *a) {
  3.     *a += 1;
  4. }

  5. int main(void) {
  6.     int a = 12;
  7.     test(&a);
  8.     printf("%d\n", a);
  9.     return 0;
  10. }
复制代码
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-4-27 14:22:53 | 显示全部楼层
本帖最后由 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的值是如何还原的呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-4-29 19:04:34 | 显示全部楼层
不需要还原好吗!谁告诉你原值push了,它就被删了?它还好好的在那里好吗!你push个ax看看,ax还在不在?何况实参是在内存中的。不动它根本就不会改。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-14 03:15

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表