Q:源代码是怎么变成可执行文件的,每一步的作用是什么?
(预编译,词法分析,语法分析,语义分析,中间语言生成目标代码生成,汇编,链接)
步骤如下:
1、驱动程序首先调用C预处理器(CPP)把源文件翻译成一个ASCII中间文件mian.i,预处理器会把#include所包含的内容都插入到声明的位置,并且做宏替换,把main.c 文件的第3行 的SIZE替换成2(注意这里只是做简单的文本替换)。
2、接下来驱动程序的C编译器将main.i翻译成汇编语言程序main.s
3、然后驱动程序的汇编器将汇编语言程序main.s 翻译成可重定位的二进制文件main.o
4、最后运行链接器将main.o 与swap.o 以及一些必要的系统目标文件(比如你将调用的printf函数就是printf.o)连接起来变成一个可执行的二进制文件。
Q:虚拟内存空间是什么,为什么要有虚拟内存空间。
所谓的虚拟地址空间,是指应用程序自己认为,自己所处的地址空间。它区别于物理地址空间。后者是真实存在的,比如电脑有一根8G的内存条,物理地址空间就是0~8Gb。CPU的MMU负责把虚拟地址转换成物理地址。
因为 虚拟地址空间可以大于物理地址空间,进行分页交换,弥补了进程太多时,物理地址空间不够用。
Q:静态链接和动态链接分别表示什么
静态链接:在生成可执行文件的时候(链接阶段),把所有需要的函数的二进制代码都包含到可执行文件中去。
缺点:程序体积会相对大一些。
动态链接:在编译的时候不直接拷贝可执行代码,而是通过记录一系列符号和参数,在程序运行或加载时将这些信息传递给操作系统,操作系统负责将需要的动态库加载到内存中,然后程序在运行到指定的代码时,去共享执行内存中已经加载的动态库可执行代码,最终达到运行时连接的目的。
缺点: 由于是运行时加载,可能会影响程序的前期执行性能。
Q:进程的内存格局是怎样的?(堆、栈、全局/静态区,代码区,常量区)
Q:堆和栈的区别,函数调用和栈的关系
一个由C/C++编译的程序占用的内存分为以下几个部分
1、栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等。其
操作方式类似于数据结构中的栈。
2、堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回
收 。注意它与数据结构中的堆是两回事,分配方式倒是类似于链表,呵呵。
3、全局区(静态区)(static)—,全局变量和静态变量的存储是放在一块的,初始化的
全局变量和静态变量在一块区域, 未初始化的全局变量和未初始化的静态变量在相邻的另
一块区域。 - 程序结束后由系统释放。
4、文字常量区 —常量字符串就是放在这里的。 程序结束后由系统释放
5、程序代码区—存放函数体的二进制代码。
栈和堆的区别:
栈由系统自动分配,堆由程序员自己申请管理
申请大小的限制:iOS栈为一块连续的内存,最大为1M,堆是不连续的,受限于计算机的虚拟内存,由此可见,堆获取的空间比较灵活。
申请效率,栈由系统分配,速度较快。堆由malloc分配,速度慢,容易产生内存碎片。
堆和栈的存贮内容:
栈:在函数调用的时候,第一个进栈的是执行函数后的笑一个指令,然后是函数的参数,然后是函数里面的局部变量.出栈和这个相反.
堆:堆的头部用一个字节存放堆的大小.
Q:进程和线程的区别
进程:是程序运行的实例,是系统进行资源分配和调度的一个独立单位,它包括独立的地址空间,资源以及1个或多个线程。
线程:可以看成是轻量级的进程,是CPU调度和分派的基本单位。
区别:
1.调度 :从上面的定义可以看出一个是调度和分派的基本单位,一个是拥有资源的基本单位
2.共享地址空间,资源:进程拥有各自独立的地址空间,资源,所以共享复杂,需要用IPC,同步简单; 线程共享所属进程的资源,共享简单,但同步复杂,要通过加锁等措施。
3.占用内存,cpu: 进程占用内存多,切换复杂,CPU利用率低; 线程占用内存少,切换简单,CPU利用率高。
4.相互影响: 进程间不会相互影响; 一个线程挂掉会导致整个进程挂掉。
网友评论