鱼C论坛

 找回密码
 立即注册
查看: 3883|回复: 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 | 显示全部楼层
都已经学了汇编语言了,那就给你一个代码,自己看
自己去分析堆栈上面的参数是如何传递的
int main(void) {
00DC1810  push        ebp  
00DC1811  mov         ebp,esp  
00DC1813  sub         esp,0D8h  
00DC1819  push        ebx  
00DC181A  push        esi  
00DC181B  push        edi  
00DC181C  lea         edi,[ebp-0D8h]  
00DC1822  mov         ecx,36h  
00DC1827  mov         eax,0CCCCCCCCh  
00DC182C  rep stos    dword ptr es:[edi]  
00DC182E  mov         ecx,offset _8A2E5209_main@c (0DCC003h)  
00DC1833  call        @__CheckForDebuggerJustMyCode@4 (0DC1217h)  
    int a = 12;
00DC1838  mov         dword ptr [a],0Ch  
    int b = 13;
00DC183F  mov         dword ptr [b],0Dh  
    test(a, b);
00DC1846  mov         eax,dword ptr [b]  
00DC1849  push        eax  
00DC184A  mov         ecx,dword ptr [a]  
00DC184D  push        ecx  
00DC184E  call        _test (0DC1389h)  
00DC1853  add         esp,8  
    return 0;
00DC1856  xor         eax,eax  
}

void test(int a, int b) {
00DC1F70  push        ebp  
00DC1F71  mov         ebp,esp  
00DC1F73  sub         esp,0C0h  
00DC1F79  push        ebx  
00DC1F7A  push        esi  
00DC1F7B  push        edi  
00DC1F7C  lea         edi,[ebp-0C0h]  
00DC1F82  mov         ecx,30h  
00DC1F87  mov         eax,0CCCCCCCCh  
00DC1F8C  rep stos    dword ptr es:[edi]  
00DC1F8E  mov         ecx,offset _8A2E5209_main@c (0DCC003h)  
00DC1F93  call        @__CheckForDebuggerJustMyCode@4 (0DC1217h)  
    a = a + 1;
00DC1F98  mov         eax,dword ptr [a]  
00DC1F9B  add         eax,1  
00DC1F9E  mov         dword ptr [a],eax  
    b = b + 1;
00DC1FA1  mov         eax,dword ptr [b]  
00DC1FA4  add         eax,1  
00DC1FA7  mov         dword ptr [b],eax  
    printf("%d %d\n", a, b);
00DC1FAA  mov         eax,dword ptr [b]  
00DC1FAD  push        eax  
00DC1FAE  mov         ecx,dword ptr [a]  
00DC1FB1  push        ecx  
00DC1FB2  push        offset string "hello\n" (0DC7B30h)  
00DC1FB7  call        _printf (0DC1046h)  
00DC1FBC  add         esp,0Ch  
}



这个是去掉符号名的版本
int main(void) {
00DC1810  push        ebp  
00DC1811  mov         ebp,esp  
00DC1813  sub         esp,0D8h  
00DC1819  push        ebx  
00DC181A  push        esi  
00DC181B  push        edi  
00DC181C  lea         edi,[ebp+FFFFFF28h]  
00DC1822  mov         ecx,36h  
00DC1827  mov         eax,0CCCCCCCCh  
00DC182C  rep stos    dword ptr es:[edi]  
00DC182E  mov         ecx,0DCC003h  
00DC1833  call        00DC1217  
    int a = 12;
00DC1838  mov         dword ptr [ebp-8],0Ch  
    int b = 13;
00DC183F  mov         dword ptr [ebp-14h],0Dh  
    test(a, b);
00DC1846  mov         eax,dword ptr [ebp-14h]  
00DC1849  push        eax  
00DC184A  mov         ecx,dword ptr [ebp-8]  
00DC184D  push        ecx  
00DC184E  call        00DC1389  
00DC1853  add         esp,8  
    return 0;
00DC1856  xor         eax,eax  
}

void test(int a, int b) {
00DC1F70  push        ebp  
00DC1F71  mov         ebp,esp  
00DC1F73  sub         esp,0C0h  
00DC1F79  push        ebx  
00DC1F7A  push        esi  
00DC1F7B  push        edi  
00DC1F7C  lea         edi,[ebp+FFFFFF40h]  
00DC1F82  mov         ecx,30h  
00DC1F87  mov         eax,0CCCCCCCCh  
00DC1F8C  rep stos    dword ptr es:[edi]  
00DC1F8E  mov         ecx,0DCC003h  
00DC1F93  call        00DC1217  
    a = a + 1;
00DC1F98  mov         eax,dword ptr [ebp+8]  
00DC1F9B  add         eax,1  
00DC1F9E  mov         dword ptr [ebp+8],eax  
    b = b + 1;
00DC1FA1  mov         eax,dword ptr [ebp+0Ch]  
00DC1FA4  add         eax,1  
00DC1FA7  mov         dword ptr [ebp+0Ch],eax  
    printf("%d %d\n", a, b);
00DC1FAA  mov         eax,dword ptr [ebp+0Ch]  
00DC1FAD  push        eax  
00DC1FAE  mov         ecx,dword ptr [ebp+8]  
00DC1FB1  push        ecx  
00DC1FB2  push        0DC7B30h  
00DC1FB7  call        00DC1046  
00DC1FBC  add         esp,0Ch  
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

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

void test(int *a) {
    *a += 1;
}

int main(void) {
    int a = 12;
    test(&a);
    printf("%d\n", a);
    return 0;
}
想知道小甲鱼最近在做啥?请访问 -> 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-11-23 18:29

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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