4 c++ 链接

本文探讨了从汇编.o目标文件到程序运行的过程,包括链接阶段的符号处理、地址分配和重定位。在函数调用中,详细阐述了形参内存分配、调用方与被调用方的角色以及返回值的传递。还分析了未初始化指针导致的错误,并解释了错误原因。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

汇编 .o目标文件

以编译单元为单位

汇编阶段没有处理的:

1.强弱符号

2.符号表 外部符号处理

3.指令段 虚假地址和虚假偏移

在这里插入图片描述

链接阶段处理的:

1.合并段和符号表 强弱符号

2.符号解析

3.分配地址和空间 程序和虚拟地址空间的映射

4.符号的重定位

处理UND区域符号

​ 通过声明找到定义的位置

符号解析

​ 在符号引用的地方找到符号定义的地方

在这里插入图片描述
在这里插入图片描述

进程

运行

1.建立虚拟地址空间和物理内存的映射(创建内核映射结构体),创建页目录页表

2.加载指令和数据

3.把入口地址放在下一行指令寄存器

下一部分

1.编译链接运行原理

2.函数堆栈调用

寄存器

​ eax ebx ecx edx 存储数据

​ ebp 栈底指针寄存器

​ esp 栈顶指针寄存器

汇编指令

mov dword ptr[a],0Ah 移值指令

​ a = 10;

lea dword ptr[p],[a]; 移地址指令

​ int* p = &q

push 0ah; 压栈指令 esp改变

pop eax; 出栈指针 esp改变

​ eax = pop();

add eax,0a 累加指令

​ eax += 0a;

sub eax,0a 累减指令

​ eax -= 0a;

[a] 该内存单元的地址

ptr[a] 该内存单元

#include<stdio.h>

int Sum(int a,int b)//被调用方函数
{
    return a + b;
}

void fun()
{
    Sum(10,20);
}

int main()//调用方函数
{
    int rt = 0;
    rt = Sum(10,20);
    return 0;
}

问题:函数和函数调用过程中

1.形参开不开辟内存?如果开辟,是调用方开辟,还是被调用方开辟?

​ 实参的传递过程中,形参开辟内存,是由调用方开辟的

2.函数调用完成,怎么回退到调用方?

3.函数调用完成,怎么接着调用方继续指令?

4.函数返回值怎么返回到调用方的?

#include<stdio.h>

int Sum(int left,int right)
{
    int tmp = 0;
    tmp = left + right
    return tmp;
}

int main()
{
    int a = 10;
    int b = 20;
    int rt;
    rt = Sum(a,b);
    printf("rt:%d\n",rt);
    return 0;
}

在这里插入图片描述

函数做了哪些事

1.栈帧跳转

​ 调用方跳转到被调用方

2.被调用方预留空间并作初始化(cccc cccc)

call做的事情:

1.压入下一行指令地址

2.jmp 跳转到被调用方

int main()
{
	int *p;
	*p = 20;//error
	return 0;
}

问题:上面的程序错误的原因

因为int *p没有初始化,没有初始化定义指针变量的时候,操作系统是给其预留空间的,预留的空间都是cccc cccc,所以当p里面存放的地址是0xcccc cccc,是内核地址,内核地址只能由操作系统操纵,所以解引用赋值操作错误

{
int *p;
*p = 20;//error
return 0;
}


**问题:上面的程序错误的原因**

因为int *p没有初始化,没有初始化定义指针变量的时候,操作系统是给其预留空间的,预留的空间都是cccc cccc,所以当p里面存放的地址是0xcccc cccc,是内核地址,内核地址只能由操作系统操纵,所以解引用赋值操作错误

![在这里插入图片描述](https://img-blog.csdnimg.cn/202103312127339.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3B3bF9wcA==,size_16,color_FFFFFF,t_70#pic_center)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值