当前位置: 首页 > news >正文

青岛cms建站系统顺德门户网站建设公司

青岛cms建站系统,顺德门户网站建设公司,长春做网站用的软件,梅州做网站设计公司Linux可执行程序的生成和运行详解 01.可执行程序的生成流程 我们已知用高级语言编写的程序无法直接被机器识别,需要被编译成机器指令才能被机器识别,在此涉及四个过程: 1.1 预处理 头文件包含,宏定义替换,注释删除…

Linux可执行程序的生成和运行详解

01.可执行程序的生成流程

我们已知用高级语言编写的程序无法直接被机器识别,需要被编译成机器指令才能被机器识别,在此涉及四个过程:

1.1 预处理

头文件包含,宏定义替换,注释删除操作。

gcc -E myexe.c -o myexe.i  # 仅执行预处理相关操作

在这里插入图片描述

在这里插入图片描述


1.2 编译

将预处理后的代码转换为汇编代码,并进行语义/语法分析符号汇总

gcc -S myexe.i -o myexe.s  # 执行编译生成汇编代码

在这里插入图片描述


1.3 汇编

将汇编代码转换为机器码,生成可重定位目标文件。

gcc -c myexe.s -o myexe.o  # 汇编为机器指令

在这里插入图片描述


1.4 链接

将多个目标文件(.o)和库文件(.a .so) 合并为可执行文件,解决符号引用。

1.4.1 动/静态库
  • 动态链接:节省内存,支持库更新;
  • 静态链接:部署简单,无外部依赖。

动态库也称为共享库,系统一般自带动态库,静态库需要手动安装。系统给我们提供了标准库.h(告诉怎么用),标准的动静态库.so/.a(告诉我们,方法实现我有,来找我)。可执行程序=我的代码+库的代码。

在这里插入图片描述

1.4.2 多文件编译

链接过程示意图:

在这里插入图片描述

在不用makefile条件下的多文件编译。如果出现了问题 使用gcc -v ,--help,-g排除问题。

// process.c
#include"process.h"
void ProcessOn(){//函数的定义//循环101次int cnt=0;char bar[NUM];char style[S_NUM]={'-','+','=','_','.'};const char *lable="|\\-/";memset(bar,'\0',sizeof(bar));while(cnt<=100){printf("[%-100s][%-3d%%][%c]\r",bar,cnt,lable[cnt%4]);fflush(stdout);bar[cnt++]=style[Npp];usleep(50000);  }printf("\n");
}
// process.h
#pragma once
#include<stdio.h>
#include<string.h>
#define NUM 101
#define S_NUM 5
extern void ProcessOn();//函数声明
// main.c
#include"process.h"
int main(){ProcessOn();//函数调用printf("hello world!\n");return 0;
}

在这里插入图片描述

通过gcc -v process.c可知文件在当前目录根/usr/这些路径下搜索process.c。如果编译器找不到在末尾加上I/目录指定即可。

在这里插入图片描述


02.操作系统执行程序步骤

Linux环境下可执行文件的格式是ELF,在Windows下可执行程序是EXE

直接 exec 而不用 fork可以吗?
exec 会替换当前进程的代码,若直接调用,父进程(如Shell)会被覆盖,无法继续运行。

fork + execve 的设计优势是什么?

COW 机制下,fork 的实际开销很小,后紧随 execve 时,未修改的内存页无需复制性能高效。子进程的失败不会影响父进程。

2.1 fork创建子进程

  • 分配PCB设置并子进程的PID和状态
  • 复制父进程fd,页表等资源
  • 使用COW技术(下面有介绍),父子共享内存,知道一方写操作
sequenceDiagramparticipant 用户participant Shellparticipant 操作系统内核用户 ->> Shell: 输入 ./myprocessShell ->> Shell: 解析命令,检查路径Shell ->> 操作系统内核: fork() 创建子进程操作系统内核 -->> Shell: 返回子进程PIDShell ->> 操作系统内核: 父进程调用 wait()

后续父进程P(wait)操作等待子进程执行完毕,避免产生僵尸进程。

2.2 execve加载ELF文件

int execve(const char *path, char *const argv[], char *const envp[]);//man 2execve详见该系统调用 
//eg
char* argv[] = {"./a.out", "arg1", NULL};
execve("./a.out", argv, environ); // environ 为全局环境变量
  • 参数
    • path:可执行文件的完整路径
    • argv:参数数组, NULL 结尾。 0位置一般是程序名称
    • envp:自定义环境变量数组(详见进程控制末介绍)
  • 返回值
    • 成功:替换原进程的代码段
    • 失败:返回 -1,并设置 errno
2.2 .1 权限检测

检查调用者和目标文件(如ELF)的有效性。

2.2.2 加载ELF

从磁盘读取目标文件到内存并解析ELF Header,获取入口地址等信息。

在这里插入图片描述

2.2.3 替换进程地址空间
  • 验证ELF
  • 以不创建新进程的方式,销毁当前进程的代码段、数据段、堆栈,加载新程序到内存,替换当前进程的映像并且。
  • 初始化新程序执行环境
  • 动态链接
2.2.4 设置执行环境与跳转

argvenvp 复制到新程序的栈中。从内核返回,重置PC(下一条将被执行指令的地址),跳转到ELF文件的入口地址_startexecve是唯一能够执行程序的系统调用。

在这里插入图片描述

调用流程:_start__libc_start_mainmain

在这里插入图片描述

调用流程maincallq ProcessOnProcessOn 执行 → retq 返回 mainmain 继续执行。

2.3 调用main函数

调用main函数进入c代码。

完整流程图:

用户 Shell 操作系统内核 磁盘 物理内存 子进程 输入 ./myprocess 解析命令,检查路径 fork() 创建子进程 返回子进程PID 父进程调用 wait() 写时复制(COW)优化 execve("./myprocess", argv, envp) 读取myprocess的ELF头 释放子进程原内存 按需加载代码/数据页 填充缺页内容 初始化寄存器,跳转到_start 执行myprocess的main() 执行完毕,exit() 父进程wait()返回 恢复提示符 用户 Shell 操作系统内核 磁盘 物理内存 子进程

进程切换内核代码:

在这里插入图片描述

http://www.dtcms.com/a/487941.html

相关文章:

  • 【评测】百炼大模型视频生成初体验
  • 算法---动态规划(Dynamic Programming, DP)
  • 如何建立网站会员系统吗电商网站怎么做seo
  • 西安SEO网站推广长治网站制作
  • 山东城建建设职业学院教务网站第一章 网站建设基本概述
  • 新网站多久被收录自己做的网站搜索不到
  • 算法入门:专题二---滑动窗口(长度最小的子数组)类型题目攻克!
  • 知名排版网站wordpress如何安裝
  • 电子商务网站设计毕业设计论文电影网站开发PPT模板
  • index.html网站怎么做wordpress关注公众号发送验证码
  • dede做的网站打不开云服务器一般多少钱
  • HTTP Error 5OO.0- ASPNET Core lIS hosting failure (in-process)
  • 机械做卖产品网站百度识图网页版
  • 公司注册网站系统东营区住房和城乡建设局网站
  • LongCat-Flash:如何使用 SGLang 部署美团 Agentic 模型
  • 怎么让网站绑定域名访问不了开发软件怎么申请版权
  • 光通信网站模板百度app下载安装官方免费版
  • vllm-openai Docker 部署手册
  • 什么是网站主办者宜兴专业做网站公司
  • 微信官网网站移动电子商务平台就是手机网站
  • 建设单位网站需求报告网站页面设计代码
  • 做网站不懂行情 怎么收费想用vs做网站 学什么
  • 网站域名绑定ip微信公众号怎么做预约功能
  • 如何申请GitHub账号?
  • 创意响应式网站建设别的网站做相关链接怎么做
  • 存储引擎:数据库的核心架构与B+树的深度解析
  • 网站建设策划方案t优化网站排名推荐公司
  • 网站建设怎么设计更加吸引人免费建设网站
  • 网站开发中都引用什么文献绍兴网络推广公司
  • Qtday1