HIT-csapp大作业:程序人生-HELLO‘s P2P

06-02 1382阅读

HIT-csapp大作业:程序人生-HELLO‘s P2P

计算机系统

大作业

        题          目  程序人生-Hellos P2P  

 专          业        计算学部         

   学       号        2023111813      

 班          级         23L0518        

学          生         鲁永哲          

 指 导 教 师          史先俊          

计算机科学与技术学院

2025年5月

摘要

        本篇论文解释了C语言程序如何从源代码转换为可执行文件。以hello.c程序为例,本文详细分析了计算机在生成hello可执行文件的预处理、编译、汇编、链接、进程管理等整个生命周期。探讨了这些工具的原理和方法,演示了它们的操作和结果,阐述了计算机系统的工作原理和体系结构,从而更深入地理解和掌握C语言程序的编译和执行过程。

关键词:计算机系统;体系结构;生命周期                            

目录

第1章 概述

1.1 Hello简介

1.2 环境与工具

1.3 中间结果

1.4 本章小结

第2章 预处理

2.1 预处理的概念与作用

2.1.1预处理的概念

2.1.2预处理的作用

2.2在Ubuntu下预处理的命令

2.3 Hello的预处理结果解析

2.4 本章小结

第3章 编译

3.1 编译的概念与作用

3.1.1编译的概念

3.1.2编译的作用

3.2 在Ubuntu下编译的命令

3.3 Hello的编译结果解析

3.3.1汇编初始部分

3.3.2 数据部分

3.3.3全局函数

3.3.4赋值操作

3.3.5算术操作

3.3.6关系操作

3.3.7 控制转移指令

3.3.8函数操作

3.3.9类型转换

3.4 本章小结

第4章 汇编

4.1 汇编的概念与作用

4.1.1汇编的概念

4.1.2汇编的作用

4.2 在Ubuntu下汇编的命令

4.3 可重定位目标elf格式

4.3.1 elf头

4.3.2 节头(section header)

4.3.3重定位节

4.3.4 符号表

4.4 Hello.o的结果解析

4.4.1命令

4.4.2 增加机器语言

4.4.3 操作数进制

4.4.4 分支转移

4.4.5 函数调用

4.5 本章小结

第5章 链接

5.1 链接的概念与作用

5.1.1链接的概念

5.1.2链接的作用

5.2 在Ubuntu下链接的命令

5.3 可执行目标文件hello的格式

5.3.2 节头

5.3.3 符号表

5.3.4程序头

5.3.5 动态节

5.4 hello的虚拟地址空间

5.5 链接的重定位过程分析

5.5.1分析hello与hello.o区别

5.5.2重定位过程

5.6 hello的执行流程

5.6.1 执行流程

5.6.2子程序名和地址

5.7 Hello的动态链接分析

5.8 本章小结

第6章 hello进程管理

6.1 进程的概念与作用

6.1.1进程的概念

6.1.2 进程的作用

6.2 简述壳Shell-bash的作用与处理流程

6.3 Hello的fork进程创建过程

6.4 Hello的execve过程

6.5 Hello的进程执行

6.5.1 逻辑控制流

6.5.2 时间片

6.5.3 上下文切换

6.5.4 用户态和内核态

6.5.5上下文信息

6.6 hello的异常与信号处理

6.6.1异常

6.6.2信号

6.6.3 异常的处理方式

6.6.4 运行结果及相关命令

6.7本章小结

第7章 hello的存储管理

7.1 hello的存储器地址空间

7.1.1逻辑地址

7.1.2线性地址

7.1.3虚拟地址

7.1.4物理地址

7.2 Intel逻辑地址到线性地址的变换-段式管理

7.3 Hello的线性地址到物理地址的变换-页式管理

7.4 TLB与四级页表支持下的VA到PA的变换

7.5 三级Cache支持下的物理内存访问

7.6 hello进程fork时的内存映射

7.7 hello进程execve时的内存映射

7.8 缺页故障与缺页中断处理

7.9本章小结

结论

附件

参考文献

第1章 概述 

1.1 Hello简介

P2P:即From Program to Process。指从hello.c(Program)变为运行时进程(Process)。要让hello.c这个C语言程序运行起来,需要先把它变成可执行文件,这个变化过程有四个阶段:预处理,编译,汇编,链接,完成后就得到了可执行文件,然后就可以在shell中执行它,shell会给它分配进程空间。

020:即From Zero-0 to Zero-0。指最初内存并无hello文件的相关内容,shell用execve函数启动hello程序,把虚拟内存对应到物理内存,并从程序入口开始加载和运行,进入main函数执行目标代码,程序结束后,shell父进程回收hello进程,内核删除hello文件相关的数据结构。

1.2 环境与工具

硬件环境:

处理器:AMD Ryzen7 7730U with Radeon Graphics

机带RAM:16.0GB

系统类型:64位操作系统,基于x64的处理器

软件环境:Windows11 64位,VMware,Ubuntu 20.04 LTS

开发与调试工具:Visual Studio 2021 64位;Clion 2024 64位;vim objdump edb gcc gdb等工具

1.3 中间结果

hello.i         预处理后得到的文本文件

hello.s         编译后得到的汇编语言文件

hello.o        汇编后得到的可重定位目标文件

hello.asm      反汇编hello.o得到的反汇编文件

hello1.asm     反汇编hello可执行文件得到的反汇编文件

1.4 本章小结

本章介绍了hello的P2P,020流程;然后说明了本实验所需的硬件配置、软件平台、开发工具以及本实验生成的中间结果文件的名称和功能。

第2章 预处理

2.1 预处理的概念与作用

2.1.1预处理的概念

预处理步骤是指预处理器在程序运行前,对源文件进行简单加工的过程。预处理过程主要进行代码文本的替换工作,用于处理以#开头的指令,还会删除程序中的注释和多余的空白字符。预处理指令可以简单理解为#开头的正确指令,它们会被转换为实际代码中的内容(替换)。

2.1.2预处理的作用

预处理过程中并不直接解析程序源代码的内容,而是对源代码进行相应的分割、处理和替换,主要有以下作用:

头文件包含:将所包含头文件的指令替代。

宏定义:将宏定义替换为实际代码中的内容。

条件编译:根据条件判断是否编译某段代码。

其他:如注释删除等。

简单来说,预处理是一个文本插入与替换的过程预处理器。

2.2在Ubuntu下预处理的命令

预处理的命令:gcc -E hello.c -o hello.i

HIT-csapp大作业:程序人生-HELLO‘s P2P

图1 预处理命令截图

2.3 Hello的预处理结果解析

在Linux下打开hello.i文件,对比源程序和预处理后的程序。发现除了预处理指令被扩展成了几千行之外,源程序的其他部分都保持不变。

在main函数代码出现之前的大段代码源自于的头文件   的依次展开。

以 stdio.h 的展开为例:预处理过程中,#include指令的作用是把指定的头文件的内容包含到源文件中。stdio.h是标准输入输出库的头文件,它包含了用于读写文件、标准输入输出的函数原型和宏定义等内容。

当预处理器遇到#include时,它会在系统的头文件路径下查找stdio.h文件,一般在/usr/include目录下,然后把stdio.h文件中的内容复制到源文件中。stdio.h文件中可能还有其他的#include指令,比如#include或#include等,这些头文件也会被递归地展开到源文件中。

预处理器不会对头文件中的内容做任何计算或转换,只是简单地复制和替换。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图2  部分hello.i截图

2.4 本章小结

本章讲述了在linux环境中,如何对C语言程序进行预处理,以及预处理的含义和作用。用hello程序演示了从hello.c到hello.i的过程,并分析了预处理后的结果。通过分析,可以发现预处理后的文件hello.i包含了标准输入输出库stdio.h的内容,以及一些宏和常量的定义,还有一些条件编译指令。

第3章 编译

3.1 编译的概念与作用

3.1.1编译的概念

计算机程序编译的概念是指将用高级程序设计语言书写的源程序,翻译成等价的汇编语言格式程序的翻译过程。

3.1.2编译的作用

计算机程序编译的作用是使高级语言源程序变为汇编语言,提高编程效率和可移植性。计算机程序编译的基本流程包括词法分析、语法分析、语义分析、中间代码生成、代码优化和目标代码生成等阶段。

注意:这儿的编译是指从 .i 到 .s 即预处理后的文件到生成汇编语言程序

3.2 在Ubuntu下编译的命令

编译的命令:gcc -S hello.i -o hello.s

HIT-csapp大作业:程序人生-HELLO‘s P2P

图3 编译的命令截图

3.3 Hello的编译结果解析

3.3.1汇编初始部分

main函数前有部分字段展示了节名称:

HIT-csapp大作业:程序人生-HELLO‘s P2P

图4 hello.s初始部分

.file               声明出源文件

.text               表示代码节

.section   .rodata    表示只读数据段

.align              声明对指令或者数据的存放地址进行对齐的方式

.string              声明一个字符串

.globl              声明全局变量

.type               声明一个符号的类型

3.3.2 数据部分

(1)参数argc

参数argc是main函数的第一个参数,被存放在寄存器%edi中

HIT-csapp大作业:程序人生-HELLO‘s P2P 寄存器%edi地址被压入栈

HIT-csapp大作业:程序人生-HELLO‘s P2P该地址上的数值与立即数5判断大小,从而得知argc被存放在寄存器并被压入栈中。

(2)字符串程序有两个字符串存放在只读数据段中,如图:

HIT-csapp大作业:程序人生-HELLO‘s P2P

hello.c中唯一的数组是main函数中的第二个参数(即char*argv),数组的每个元素都是一个指向字符类型的指针。由知数组起始地址存放在栈中-32(%rbp)的位置,被两次调用作为参数传到printf中。

分别将rdi设置为两个字符串的起始地址:

HIT-csapp大作业:程序人生-HELLO‘s P2P

HIT-csapp大作业:程序人生-HELLO‘s P2P

(3)局部变量

程序中的局部变量只有i

HIT-csapp大作业:程序人生-HELLO‘s P2P

局部变量i是被存放在栈上-4(%rbp)的位置。

3.3.3全局函数

hello.c中只声明了一个全局函数int main(int arge,char*argv[])

HIT-csapp大作业:程序人生-HELLO‘s P2P

3.3.4赋值操作

赋值操作有for循环开头的i=0,该赋值操作体现在汇编代码上是用mov指令实现。

int型变量i是一个32位变量,使用movl传递双字实现。

3.3.5算术操作

hello.c中的算术操作为for循环的每次循环结束后i++,在汇编代码使用指令add实现,由于变量i为32位,使用指令addl。HIT-csapp大作业:程序人生-HELLO‘s P2P

3.3.6关系操作

hello.c中存在两个关系操作,分别为:

  1. 条件判断语句if(argc!=5)

    HIT-csapp大作业:程序人生-HELLO‘s P2P

使用了cmpl指令比较立即数5和参数argc大小,并且设置了条件码,如果不相等则执行该指令后面语句,否则跳转到.L2。

2.在for循环每次循环结束要判断一次i hello.asm分析hello.o的反汇编,并与第3章的 hello.s进行对照分析。

HIT-csapp大作业:程序人生-HELLO‘s P2P

HIT-csapp大作业:程序人生-HELLO‘s P2P 

图11 hello.o 反汇编

4.4.2 增加机器语言

每一条指令增加了一个十六进制的表示,即该指令的机器语言。而hello.s中并没有。如下图:

HIT-csapp大作业:程序人生-HELLO‘s P2Phello.s中的部分指令

HIT-csapp大作业:程序人生-HELLO‘s P2Phello.asm中的部分指令

4.4.3 操作数进制

反汇编文件中的所有操作数都由十进制改为十六进制。

由4.4.2的截图不难看出,立即数由hello.s中的$5变为了$0x5,地址表示也由-20(%rbp)变为-0x14(%rbp)。可见进制表示改变,数值并未发生改变。

4.4.4 分支转移

反汇编的跳转指令中,所有跳转的位置表示为主函数+段内偏移量,而不再是段名称(例如.L3)。例如下面的jmp指令,反汇编文件中为

HIT-csapp大作业:程序人生-HELLO‘s P2P

而hello.s文件中为HIT-csapp大作业:程序人生-HELLO‘s P2P

4.4.5 函数调用

hello.s中,函数调用直接使用了函数的名称。反汇编代码中,call目标地址是当前指令的下一条指令地址。因为hello.c中调用的函数都是共享库(如stdio.h,stdlib.h)中的函数,如puts,exit,printf,需等待链接器链接之后才能确定响应函数地址。机器语言中对于这种不确定地址的调用,会将下条指令的相对地址全部设置为0,然后在.rel.text节中为其添加重定位条目,等待链接时确定地址。

观察下面两个call指令调用函数,在hello.s中为

HIT-csapp大作业:程序人生-HELLO‘s P2P

而在反汇编文件中调用函数为

HIT-csapp大作业:程序人生-HELLO‘s P2P

可重定位文件中call后面不再是函数名称,而是一条重定位条目指引的信息。

4.5 本章小结

这一章介绍了汇编的含义和功能。以Ubuntu系统下的hello.s文件为例,说明了如何把它汇编成hello.o文件,并生成ELF格式的可执行文件hello.elf。将可重定位目标文件改为ELF格式观察文件内容,对文件中的每个节进行简单解析。通过分析hello.o的反汇编代码(保存在hello.asm中)和hello.s的区别和相同点,让我理解了汇编不仅完成了从汇编语言到机器语言的转换,还通过生成可重定位目标文件,为后续链接和程序执行提供基础。

第5章 链接

5.1 链接的概念与作用

5.1.1链接的概念

 链接是将各个单独的二进制代码文件加载到同一个文件,并使之可以加载到内存中执行的一个过程。链接可以在编译时被执行,也可以在程序运行中被执行。文件表示为若干个.o文件被合并成一个单独的可执行文件(Linux下默认为.out文件)。

5.1.2链接的作用

在现代系统中,链接是由链接器(1inker)自动执行的,使分离编译成为可能。不用再将一个大型的应用程序组织为一个巨大的源文件,而可以把它分解为更小、更好管理的模块,允许独立地修改和编译这些模块。当改变这些模块中的一个时,只需简单地重新编译它,并重新链接应用。

5.2 在Ubuntu下链接的命令

Ubuntu下链接的命令为:

ld -o hello -dynamic-linker /lib64/ld-linux-x86-64.so.2 /usr/lib/x86_64-linux-gnu/crt1.o /usr/lib/x86_64-linux-gnu/crti.o hello.o /usr/lib/x86_64-linux-gnu/libc.so /usr/lib/x86_64-linux-gnu/crtn.o

HIT-csapp大作业:程序人生-HELLO‘s P2P

图12 链接命令

5.3 可执行目标文件hello的格式

5.3.1 ELF头(ELF Header)

终端输入readelf -h hello > hello1.elf查看hello文件的elf头。

hello1.elf中的ELF头与hello.elf中的ELF头包含的信息种类基本相同,以描述了生成该文件的系统的字的大小和字节顺序的16字节序列Magic开始,剩下的部分包含帮助链接器语法分析和解释目标文件的信息。与hello.elf相比较,hello1.elf中的基本信息未发生改变(如Magic,类别等),而类型改变为可执行文件EXEC,程序头大小和节头数量增加,并且获得了入口地址。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图13 hello的ELF头

5.3.2 节头

终端输入命令readelf -S hello查看节头部表信息。

HIT-csapp大作业:程序人生-HELLO‘s P2PHIT-csapp大作业:程序人生-HELLO‘s P2P

图14 hello的节头

elf文件中,每个节都有一个对应的节头表,用于描述和定位各个节的信息,通过节头表,可以获取关于每个节的详细信息,如名称、偏移、大小等。链接器链接时,会将各个文件的相同段合并成一个大段,并且根据这个大段的大小以及偏移量重新设置各个符号的地址。

5.3.3 符号表

终端输入命令readelf -s hello查看符号表

HIT-csapp大作业:程序人生-HELLO‘s P2P

HIT-csapp大作业:程序人生-HELLO‘s P2P

图15 hello的符号表

可以发现经过链接之后符号表的符号数量显著增加,说明经过连接之后引入了许多其他库函数的符号加入到了符号表中。

5.3.4程序头

程序头部分是一个结构数组,描述了系统准备程序执行所需的段或其他信息。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图16 程序头

5.3.5 动态节

Dynamic Section(动态节)是 ELF文件中的一个关键数据结构,用于存储程序动态链接所需的元信息。它包含一系列标记-值对(tag-value pairs),记录程序依赖的共享库(如 DT_NEEDED)、符号表地址(DT_SYMTAB)、字符串表(DT_STRTAB)、重定位表(DT_RELA)等关键数据,供动态链接器(如 ld-linux.so)在加载时解析依赖、绑定符号并完成内存地址修正。是程序运行时动态链接的核心枢纽。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图16 动态节

5.4 hello的虚拟地址空间

使用edb打开hello文件,从数据转储窗口观察hello加载到虚拟地址的情况,查看各段信息。HIT-csapp大作业:程序人生-HELLO‘s P2P

图17 edb打开hello可执行文件

如text段,由5.3.2可得,.text的起始虚拟地址为0x4010f0

HIT-csapp大作业:程序人生-HELLO‘s P2P

在edb中查询地址可以得到如下图的结果。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图18 数据转储窗口text段

其他段以此类推,都可以在edb中查找到对应的信息。

5.5 链接的重定位过程分析

使用命令objdump -d -r hello > hello1.asm生成反汇编文件hello1.asm

HIT-csapp大作业:程序人生-HELLO‘s P2PHIT-csapp大作业:程序人生-HELLO‘s P2P

图19 查看hello可执行文件反汇编结果

5.5.1分析hello与hello.o区别

与第四章中hello.o的反汇编结果hello.asm进行比较,发现hello的反汇编代码与hello.o的反汇编代码在结构和语法上基本相同,但hello的反汇编代码多了很多内容,不同之处如下:

  链接后的反汇编文件hello1.asm中,多出了.plt,puts@plt,printf@plt,getchar@plt,exit@plt,sleep@plt等函数的代码。这是因为动态链接器将共享库中hello.c用到的函数加入到可执行文件中。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图20 hello1.asm部分截图

函数调用指令call的参数发生变化。

链接过程中,链接器解析了重定位条目,call之后的字节代码被链接器直接修改为目标地址与下一条指令的地址之差,指向相应的代码段,从而得到完整的反汇编代码。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图21 函数调用变化

(3)跳转指令参数发生变化

在链接过程中,链接器解析了重定位条目,并计算相对距离,修改了对应位置的字节代码为PLT 中相应函数与下条指令的相对地址,从而得到完整的反汇编代码。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图22 跳转指令参数变化

5.5.2重定位过程

重定位由两步组成:

(1)重定位节和符号定义。在这一步中,链接器将所有相同类型的节合并为同一类型的聚合节。然后链接器将运行时的内存地址赋给新的聚合节,赋给输入模块定义的每个节,以及赋给输入模块定义的每个符号。至此程序中每条指令和全局变量都有唯一的运行内存地址。

(2)重定位节中的符号引用。这一步中链接器修改代码节和数据节中对每个符号的引用,使得它们指向正确的运行时地址。要执行这一步,链接器依赖于可重定位目标模块中称为重定位条目的数据结构。

(3)重定位过程地址计算方法伪代码如下:

foreach section s

{

        foreach relocation entry r

        {

                refptr = s + r.offset;

                if (r.type == R_X86_64_PC32)

                {

                        refaddr = ADDR(s) + r.offset;

                        *refptr = (unsigned) (ADDR(r.symbol) + r.addend - refaddr);

                }

                if (r.type ==R_X86_64_32)

                        *refptr = (unsigned) (ADDR(r.symbol) + r.addend);

        }

}

5.6 hello的执行流程

5.6.1 执行流程

HIT-csapp大作业:程序人生-HELLO‘s P2P

图23  hello执行流程

(1)开始执行:_start、_libe_start_main

(2)执行main:_main、printf、_exit、_sleep、getchar

(3)退出:exit

5.6.2子程序名和地址

程序名               程序地址

_start                0x4010f0

_libc_start_main       0x2f12271d

main                0x401125

_printf               0x4010a0

_sleep               0x4010e0

_getchar             0x4010b0

_exit                0x4010d0

5.7 Hello的动态链接分析

  动态链接的基本思想是将程序的链接过程推迟到程序运行时进行,而不是在编译时完成。这种方法使得程序可以在启动时加载所需的动态链接库(如.so文件),而不必将库的代码在编译时静态地链接到程序中。通过动态链接,多个程序可以共享同一个库的实现,减少内存占用和磁盘空间使用,并且使得库的更新和维护更为灵活和简便。

在调用共享库函数时,编译器没有办法预测这个函数的运行时地址,因为定义它的共享模块在运行时可以加载到任意位置。正常的方法是为该引用生成一条重定位记录,然后动态链接器在程序加载的时候再解析它。延迟绑定是通过GOT和PLT实现的,根据hello.elf文件可知,GOT起始表位置为0x404000。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图24  GOT起始表位置

GOT表位置在调用dl_init之前0x404008后的16个字节均为0。

HIT-csapp大作业:程序人生-HELLO‘s P2P

图25 调用dl_init前GOT表位置内容

调用了dl_init之后内容发生改变,如下图:

HIT-csapp大作业:程序人生-HELLO‘s P2P

图26 调用dl_init后GOT表位置内容

对于变量而言,利用代码段和数据段的相对位置不变的原则去计算正确地址。

对于库函数而言,需要plt、got合作。plt初始存的是一批代码,它们跳转到got所指示的位置,然后调用链接器。初始时got里面存的都是plt的第二条指令,随后链接器修改got,下一次再调用plt时,指向的就是正确的内存地址。接下来执行程序的过程中,就可以使用过程链接表plt和全局偏移量表got进行动态链接。

hello在动态连接器加载前后的重定位是不一样的,在加载之后才进行重定位。

5.8 本章小结

本章介绍链接过程,首先阐述了链接的概念作用,给出链接指令。研究了可执行目标文件hello的ELF格式和可执行文件hello的反汇编代码,并用edb查看了虚拟地址空间内容,之后依据重定位条目分析了重定位的过程,并借助edb研究了程序中子程序的执行流程,最后用edb查取虚拟内存,分析了动态链接的过程。

第6章 hello进程管理

6.1 进程的概念与作用

6.1.1进程的概念

进程是操作系统中程序的一次执行过程,也是系统进行资源分配和调度的基本单位。每个进程拥有独立的地址空间、代码、数据以及其他资源,能够独立运行,并与其他进程并发执行。每个进程由操作系统分配唯一的进程标识符(PID)。

进程的经典定义是一个执行程序中的实例,每次用户通过向shell输人一个可执行目标文件的名字,运行程序时,shell 就会创建一个新的进程,然后在这个新进程的上下文中运行这个可执行目标文件。应用程序也能够创建新进程,并且在这个新进程的上下文中运行它们自己的代码或其他应用程序。

每个进程都有一个独立的地址空间,并由操作系统通过进程控制块(PCB)来管理。PCB 内部存储了进程的状态(就绪、运行、阻塞等)、优先级、资源分配情况以及进程标识符(PID)等信息。换句话说,进程是操作系统进行资源分配和调度的基本单位,是应用程序执行时动态产生的实体。

6.1.2 进程的作用

进程是操作系统进行资源分配和调度的基本单位,它为程序运行提供独立的执行环境,确保内存、CPU等资源的隔离与安全,并支持多任务的并发执行。通过进程,操作系统能够同时运行多个程序,实现用户与系统的交互,同时通过进程间通信(IPC)机制协调不同任务,保障系统的稳定性与效率。简而言之,进程是程序动态执行的载体,是操作系统实现功能和管理计算资源的核心实体。

6.2 简述壳Shell-bash的作用与处理流程

Shell-Bash是用户与操作系统内核之间的核心接口,其作用主要包括命令解释与执行、环境管理和自动化任务处理。它接收用户输入的命令(交互式或脚本形式),解析并转化为系统调用,最终由内核执行底层操作。Bash还支持变量、条件判断、循环等编程特性,能够编写脚本实现复杂逻辑,同时管理进程、I/O重定向和管道,协调多个程序的协作。

处理流程可分为以下步骤:

1.读取输入:从终端或脚本读取命令字符串。

2.解析与扩展:分割命令为参数,处理通配符(*)、变量替换($VAR)、命令替换($(cmd))等语法扩展。

3.执行命令:若为内置命令(如cd),直接由Shell处理;若为外部程序,则创建子进程并通过exec加载执行。

4.控制流程:处理管道(|)、重定向(>/

免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

目录[+]

取消
微信二维码
微信二维码
支付宝二维码