请教c函数参数入栈的问题

hzy694358 2018-08-20 08:44:43
直接上代码

char * add_normal(int num, ...) {
int *p;
char * ret;
p = &num + 1; //p指向参数列表下一个位置
ret = *(char **)p;

return ret;
}

char * add_normal2(short num, ...) {
short *p;
char * ret;

p = &num + 8; //p指向参数列表下一个位置 为什么要+8才能定位要下一个地址呢 ?
ret = *(char **)p;

// ret = ret + strlen(ret) + 1;
return ret;
}

char * add_normal3(short num, ...) {
char * ret;
int *p;
p = (int *)&num+4;
ret = *(char **)p;

// ret = ret + strlen(ret) + 1;
return ret;
}

void show_test1(int num1, int num2)
{
printf("num1=%d in address [%p]\n",num1, &num1);
printf("num2=%d in address [%p]\n",num2, &num2);
printf("address2-address1=%d\n",(int)&num2-(int)&num1);
}

void show_test2(short num1, int num2)
{
printf("num1=%d in address [%p]\n",num1, &num1);
printf("num2=%d in address [%p]\n",num2, &num2);
printf("address2-address1=%d\n",(int)&num2-(int)&num1);
}

int main(int argc, char **argv) {
printf("%s\n", add_normal(5,"13dsfsdaf",2,3,4,5));
printf("%s\n", add_normal2(5,"13dsfsdaf","2fsdfs",3,4,5));
printf("%s\n", add_normal3(5,"13dsfsdaf","2fsdfs",3,4,5));
printf("%d\n", add_normal4(5,1,2,3,4,5));
show_test1(1,2);
show_test2(1,2);
return 0;
}

liunux 下

输出是
13dsfsdaf
13dsfsdaf
13dsfsdaf
num1=1 in address [0xbffe0fc0]
num2=2 in address [0xbffe0fc4]
address2-address1=4
num1=1 in address [0xbffe0fac]
num2=2 in address [0xbffe0fc4]
address2-address1=24



疑问:add_normal2 中 就算short被提升为int入栈 为什么要+8才能定位要下一个地址呢?
show_test2函数 相差的怎么是24?
...全文
398 6 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
赵4老师 2018-08-20
  • 打赏
  • 举报
回复
http://edu.csdn.net/course/detail/2344 C语言指针与汇编内存地址-一.代码要素
yiyefangzhou24 2018-08-20
  • 打赏
  • 举报
回复
如果你测试的可以这么写,如果是项目代码,这样写是很危险的,不同的编译器会编译出不同的结果,vs的话可以显式的定义函数调用约定,gcc不是很清楚了
yiyefangzhou24 2018-08-20
  • 打赏
  • 举报
回复
看编译器不同,编译的方法不同,如果你用的gcc编译链接的,默认函数调用约定是stdcall,参数是从右至左压入栈的
sghcpt 2018-08-20
  • 打赏
  • 举报
回复
个人观点:感觉是Windows下的编译器跟linux下的编译器在处理函数参数时,在栈中的处理方式不一样了,导致这样的结果。。
sghcpt 2018-08-20
  • 打赏
  • 举报
回复
楼主,下面的是我在windows vs2013 控制台的输出:
你的第一个问题,add_normal2 和 add_normal3 输出如下(崩溃了):

你的第二问题,这边输入的值如上:


可见是否你那边的linux编译器在代码中做了什么处理跟windows不一样,这样能不能认为是编译器不同导致的。
赵4老师 2018-08-20
  • 打赏
  • 举报
回复
  • 打赏
  • 举报
回复
这个行为完全取决于平台、编译器。
一、最左边的参数,到底是在栈顶还是栈底,取决于环境。
二、栈元素之间的字节对齐,C标准里也没有规定。
还是建议用变参的辅助函数 va_list做,就安全了。
https://blog.csdn.net/dengzhilong_cpp/article/details/54944676

70,021

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧