返回值是如何传递的
函数是怎么把返回值存到某个地方的,在函数外面是怎么得到这个返回值的,对应汇编代码
函数的返回值是:
- 8位,用al返回
- 16位,用ax返回
- 32位,用eax返回
返回值超过32位时,存在哪里?
int64 Function(){
__int64 x = 0x1234567890;
return x;
}
对应汇编
mov dword ptr [ebp-8],eax
mov dword ptr [ebp-4],edx
用eax、edx两个寄存器,且eax存低位34567890h,edx存高位12h。
参数传递的本质
两种传递方式:用堆栈和用寄存器。
1字节、2字节、4字节等整数类型的参数一律按4字节(本机尺寸)传递,但在使用的时候仍会按定义的字节来使用,如:
void fun(char a){
int b = a;
//对应汇编:
//movsx eax,byte ptr [ebp+8]
//mov dword ptr [ebp-4],eax
//会进行扩展
}
int main(){
fun(1);
}
按本机尺寸传递参数效率最高。
再来以编译器的角度看待一个老问题:改变形参的值不影响实参:
void fun(int x){
x = x + 1;
}
int main(){
int x = 2;
fun(x);
printf("%d",x);
}
很显然上面代码输出的值是2。
首先在main里,2的值是存在了[ebp-4]上,传参的时候也仅是将[ebp-4]上的值复制了一份再传递给fun函数,所以你对复制的这个值怎么操作也影响不到[ebp-4]上的大小。
局部变量的内存分配
对于char、short、int型等小于本机尺寸的局部变量,内存会分配本机尺寸字节数(32位–4字节)。
而但对于char、short、int型数组变量,内存则会分配对应大小字节空间,如:
假设对于空函数,内存默认分配40h
若定义char a[4] = {0},则会分配44h(根据本机尺寸,char a[3] = {0},同样分配44h)
若定义short a[4] = {0},则会分配48h
参数与局部变量其实没有本质区别,都是在堆栈中分配的空间。如果严谨点说区别,那就是,参数是函数调用时分配的,而局部变量是函数执行时分配的。
转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1666739907@qq.com