【发布时间】:2017-09-19 17:50:24
【问题描述】:
这个经典函数是我写的:(在32位模式下)
void ex(size_t a, size_t b)
{
size_t c;
c = a;
a = b;
b = c;
}
我在main里面这样称呼它:
size_t a = 4;
size_t b = 5;
ex(a,b);
我对输入函数时生成的汇编代码的期望是这样的:
1-将 b 和 a 的值压入堆栈:(已完成)
mov eax,dword ptr [b]
push eax
mov ecx,dword ptr [a]
push ecx
2-使用堆栈中a和b的值:
push ebp
mov ebp, esp
sub esp, 4
c = a;
mov eax, dword ptr [ebp+8]
mov dword ptr [ebp-4], eax
其他变量依此类推。
但是,这是我在调试时发现的:
push ebp
mov ebp,esp
sub esp,0CCh // normal since it's in debug with ZI option
push ebx
push esi
push edi
lea edi,[ebp-0CCh]
mov ecx,33h
mov eax,0CCCCCCCCh
rep stos dword ptr es:[edi]
size_t c;
c = a;
mov eax,dword ptr [a]
mov dword ptr [c],eax
为什么直接使用变量a而不是调用栈中存储的值呢?没看懂……
【问题讨论】:
-
无法调用存储在堆栈中的整数。仅调用函数。您需要使用其他动词。
-
你的函数是荒谬的,所以你真的可以期待任何荒谬的事情发生。您正在操作一些局部变量,然后在没有返回值且没有任何副作用的情况下返回。我敢打赌,在非调试版本中,您的函数将被编译为空。
-
我很惊讶由于函数没有执行任何操作而生成了任何代码。
-
编译器只是使用
a作为ebp+8的别名和c作为ebp-4的别名。如果生成的汇编代码确实可以编译,那么这些别名是在某处定义的。如果不是,那么a和c仅供参考。 -
@Mike Nakis 实际上,这是我参加的课程中的一个示例,该示例显示了按值传递参数和按地址传递参数之间的区别。
标签: c visual-studio assembly