linux c函数返回值是在栈中还是寄存器

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了linux c函数返回值是在栈中还是寄存器相关的知识,希望对你有一定的参考价值。

函数的返回值是在寄存器中,但仅限于返回的是值。
如果返回的地址,并且这个地址是个局部变量的地址,那么就是在栈上,所以我们不建议返回这样的地址结果。
如果返回的是一个malloc或者new的变量的地址,就是在堆上。如果要返回地址,建议这样做,还要注意使用完成后进行内存释放
参考技术A 存在堆中。就比如说你在一个函数中,把一个局部变量a在函数最后return a;此时a就被系统自动释放了,但是return a(即返回值)并没有跟a一起消失。 参考技术B 什么是栈,什么是寄存器?
上了操作系统,基本上就没有寄存器这个概念了,除非是内核模块本回答被提问者采纳

022.强化训练三

 

 

函数的返回值都在EAX中.
64位返回值.

当我们写Windows32位C语言程序的时候.
使用参数和局部变量,能用int,就别用short和char类型.
涉及到一个程序内存对齐.

参数和局部变量没有本质的区别,都是在函数被调用的时候,在栈中分配的.
甚至完全可以把参数当做局部变量使用.

参数是在函数调用前分配的内存.call之前.
局部变量是函数调用时分配的内存.call中.

但是call之后,它们就全从栈中被排除之外了.



int x= 10;
int y =x+10;
int z =x*y;
int x =x+y*z


#include<stdio.h>
#include<stdlib.h>
void test1() {
int l_v1 = 1;
int l_v2 = 2;
int l_v3 = 3;
int l_v4 = 4;
int l_v5 = 5;
}


void test2() {
int l_arr[] = { 1,2,3,4,5 };
int l_v1 = 1;
int l_v2 = 2;
int l_temp;

l_temp = l_arr[1];
l_temp = l_arr[l_v1];
l_temp = l_arr[l_v1 + l_v2];
l_temp = l_arr[l_v1 * 2 + l_v2];
l_temp = l_arr[l_arr[1] + l_arr[2]];
l_temp = l_arr[7];
}


void main() {
__asm {
xor eax, eax;
}

test1();
test2();
}

 


 

在被调用的函数中,修改调用者数据的局部变量.

栈是怎么回事.
参数在栈里是如何体现的.
局部变量在栈里是如何体现的.
局部变量数组

全局变量以及全局变量数组
函数运行的时候.
可以使用寄存器
也可以使用栈
当然混合的使用.


在这个Windows 10 VS2015 debug x86模式生成的C/C++代码.
没有局部变量和数组的时候,缓存区默认大小为192个字节.

当有一个int局部变量的时候,缓存区大小为204个字节
当有一个char局部变量的时候,缓存区大小为204个字节
当有一个short局部变量的时候,缓存区大小为204个字节

当有一个int数组,5个成员,缓存区大小为224个字节.
当有一个char数组,5个成员,缓存区大小为212个字节.
当有一个short数组,5个成员,缓存区大小为216个字节.

如果你使用的变量不够4个字节,也按照4个字节给你在栈中分配.
所以这样子,就不存在一个什么char就比int节约空间.

我们编写的程序是32位.
发挥它的最大允许效率,浪费了一些内存空间.

一步迈50厘米. 有意识的去控制我的走路节奏.

存放一个数字,最大可能就是255
那我们就可以使用一个unsigned char 存放.


int是不是32位,4个字节.

 


EAX 0x00000000

不管返回值是char 对应着byte 8 al
还是short int 对应着word 16 ax
还是int 对应着dword 32 eax

当我们写一个32位程序,但是返回值是64位的时候.
返回值的高32位EDX中存放着,低32位在EAX存放着

数组


eax=-1
eax=0xFFFFFFFF
1111
edx=0xFFFFFFFFFFFFFFFF

把一个32位有符号数,并且是存放在EAX中,拓展到EDX中,两个合并成64位的一个有符号数.

 

#include<stdio.h>
#include<stdlib.h>
int f_test() {

return 1;//在这个Windows 10 VS2015 debug x86模式生成的C/C++代码.没有局部变量和数组的时候,缓存区默认大小为192个字节.

 

}//不管返回值是char 对应着byte8 al还是short int对应着word16 ax还是int 对应着dword 32 eax
void main() {
__asm {
xor eax, eax }
f_test();
}

#include<stdio.h>
#include<stdlib.h>
int test() {
long long int v1 = 0x11223344;
return v1;
}
void main() {
_asm {
xor eax,eax
}
test();
}
//当有一个int局部变量的时候,缓存区大小为208个字节
当有一个char局部变量的时候,缓存区大小为208个字节
当有一个short局部变量的时候,缓存区大小为208个字节
dpq 是拓展高位 整数 拓展都是0 负数拓展都是 1例如 eax是fffff fffff拓展到高位edx ffff ffff

 

#include<stdio.h>
#include<stdlib.h>
void f_test(int *p_v1)
{
*p_v1 = 200;
printf("%d", p_v1);

}
void main() {
int x = 100;
printf("%d\\n",&x);
f_test(&x);

system("pause");

}

以上是关于linux c函数返回值是在栈中还是寄存器的主要内容,如果未能解决你的问题,请参考以下文章

EBP寄存器存着啥东西,跟函数返回有啥联系啊

第15课 缔造程序兼容的合约(下)

C语言中函数调用过程(如何管理栈空间)

c语言中函数返回值可以是数组、字符串和结构体吗?

022.强化训练三

C语言函数调用完整过程