本来是想将实验过程写清楚的,但是想想,这个代码的调试过程还是留给读者吧。毕竟我前面写的二十几篇都是将完整的步骤写出来了,如果学会了前面gdb调试的内容那么自己调试应该不在话下。我只给出调试的思路和代码。
return.c
#include <stdio.h>
struct ST
int x;
int y;
int z;
struct ST f(int x, int y, int z)
struct ST st = {0};
printf("f() : &st = %p\n", &st);
st.x = x;
st.y = y;
st.z = z;
return st;
void g()
struct ST st = {0};
printf("g() : &st = %p\n", &st);
st = f(1, 2, 3);
printf("g() : st.x = %d\n", st.x);
printf("g() : st.y = %d\n", st.y);
printf("g() : st.z = %d\n", st.z);
void h()
struct ST st = f(4, 5, 6);
printf("h() : &st = %p\n", &st);
printf("h() : st.x = %d\n", st.x);
printf("h() : st.y = %d\n", st.y);
printf("h() : st.z = %d\n", st.z);
int main()
h();
g();
return 0;
调试思路:使用gdb进行调试。在不同的函数栈帧中查看当前函数栈帧中,结构体变量的地址是否入栈或者是否有一个临时变量的地址入栈。然后通过使用gdb打断点的形式,证明最终函数返回时是将返回值拷贝到相应的地址。当然,最后最干脆的方法还是查看该程序的反汇编代码,通过阅读反汇编代码来更加清晰的认识整个函数的运行机制。
好了,这次就不写调试步骤了,有心的人可以自己调试哦~
- 函数返回值为结构体的时候,如何将返回值传递给调用者
- 函数返回值作为初始化与赋值时的不同。注意效率问题
上一篇文章学习了几种函数调用约定的区别,点击链接查看上一篇文章:【软件开发底层知识修炼】二十四 ABI之函数调用约定本篇文章继续学习函数调用约定中,关于函数返回值的问题。当函数返回值为结构体时,函数返回值是如何来传给调用者的。文章目录1 函数返回值为结构体类型1.1 函数返回值用于初始化变量1.2 函数返回值给变量赋值2 代码案例分析3 总结1 函数返回值为结构体类型前一篇文章...
春招结束,发现面试的后面几面,会闻到c++的abi问题,大致问题就是,gcc编译的库,clang能用吗,或者在升级so文件的时候要注意什么,当时不知道,现在来总结一下。
这个abi问题,网上资料不是很多,有一些零零散散的,最后自己总结了一下以后,在这里做个笔记。
一般的软件为了模块分割,思路都是这样的:
模块写在so/dll文件中,使用exe加载并执行功能,更新只用更新dll、so就可以了。...
C++ ABI探究和兼容性问题
ABI(Application Binary Interface)
应用程序二进制接口,描述了应用程序和操作系统之间,一个应用和它的库之间,或者应用的组成部分之间的低接口。
编程语言实现的 ABI 是一种可以使单独编译的模块协同工作的低级细节的规范。如果没有一个稳定的 ABI,就必须使用同一编译器的同一版本编译程序的所有部分。
C ABI
Oracle Solari...
上一篇文章学习了Linux环境下的函数栈帧的形成与摧毁。点击链接查看相关文章:软件开发底层知识修炼】二十三 ABI-应用程序二进制接口三之深入理解函数栈帧的形成与摧毁
本篇文章继续学习ABI接口相关的内容。函数调用约定
文章目录1 函数参数如何入栈,返回值在哪里2 函数调用约定的编程实验2.1 使用gdb调试代码证明eax存的值是函数返回值2 .2 查看程序的反汇编文件来说明调用约定的不...
刚参加工作,总是听到PM分配任务的时候提到打桩的概念。查看项目代码的时候又碰到打桩函数中的HOOK技术。对于这两种技术我以前都没有接触过,在网上查了下资料,备份如下,希望对自己和他人都能有所帮助。
在软件测试的时候经常需要动态的替换被测函数调用的其它函数,而这个替换就叫做打桩。比如现在要测试函数A,但是函数A调用了还没有实现的函数B,那么我们给函数B创造打桩函数STUB_B,STUB_B可