1.计算机系统漫游(1)

1.以"hello world"程序的生命周期,对计算机系统的主要概念做了一个整体的介绍。

(创建)→(编译)→(运行)→(退出)

#include <stdio.h>

int main()

{

printf ( "hello, world\n") ;

return 0;

}

保存得到一个后缀名为.c的文件 hello.c

通过linux> gcc -o hello hello.c,即可完成对源代码的编译,生成可执行程序 hello

这个过程虽然是通过一条命令完成的,然而实际上编译系统的处理过程却是非常复杂的,大致可以分为四个阶段,分别为预处理、编译、汇编以及链接。

step1 预处理

预处理器会根据以#开头的代码,来修改原始程序。例如hello程序中引入了头文件 stdio.h ,预处理器会读取该头文件中的内容,将其中的内容直接插入到源程序中,结果就得到了另外一个 C 程序,这个经过预处理器处理后得到的文件通常以 .i 结尾,说白了就是, hello.c 经过预处理器后得到 hello.i,这个 hello.i 仍旧是一个文本文件。

step2 编译

编译器将 hello.i 文件翻译成 hello.s 文件,这一过程我们称为编译。

其中编译这一阶段包括词法分析、语法分析、语义分析、中间代码生成以及优化等等一系列的中间操作。可以康康《编译原理》。

对于编译阶段,输入hello.i,经过编译得到输出文件hello.s

step3 汇编

汇编器根据指令集将汇编程序 hello.s 翻译成机器指令,并且把这一系列的机器指令按照固定的规则进行打包,得到可重定位目标文件 hello.o 。此时 hello.o 虽然是一个二进制的文件,但是还不能执行,还要经历最后一个阶段:链接。

step4 链接

在 hello 这个程序中,调用了printf 函数,这个函数是标准C库中的一个函数,每一个C语言的编译器都会提供。当调用 printf 这个函数时,编译器就知道要在屏幕上打印输出内容,它会将这行代码翻译成计算机可以理解的指令。

这个printf 函数在是在名为 printf.o 的文件中,这个文件呢是一个提前编译好的目标文件,链接器(ld)负责把 hello.oprintf.o 进行合并(遵循一定规则的)。

正是因为链接器要对hello.oprintf.o 的进行调整,所以hello.o 才会被称之为可重定位目标文件。最终经过链接阶段可以得到可执行目标文件 hello

此时,得到的 hello 就可以被加载到内存中执行了。

2.为什么要理解编译系统是如何工作的?

第一、理解编译系统可以优化程序的性能

现代编译器是非常成熟的工具,通常可以生成很好的代码,作为一个程序员,我们没有必要为了写出高效的代码,而去研究编译器的内部是如何工作的。但是,我们还是需要对机器执行的代码有一个基本的了解,这样我们就知道编译器把不同的C代码转换成的机器代码是什么。

我们在写代码的时候可能会有这样的困惑,或者面试中会被问到以下类似的问题:

例如:一个switch语句是不是要比一连串的if-else要高效的多?一个函数调用的开销有多大?while循环比for循环更高效么?(3-5章有讲解)

第二、理解编译系统可以帮助我们理解链接过程中出现的错误

当你试图去构建大型程序的时候,往往涉及到各种函数库的调用。根据以往的经验,一些奇奇怪怪的错误往往都是与链接器有关的。

例如:静态变量和全局变量的区别是什么?静态库和动态库的区别是什么?

更严重的是,还有一些链接错误直到程序运行的时候才会出现。(第7章有答案)

第三、避免安全漏洞。

多年以来,缓冲区溢出(buffer overflow)是导致互联网安全漏洞的主要原因,如何避免写出的代码存在安全漏洞,第一步就是要理解数据和控制信息在程序栈上是如何存储的,了解不严谨不规范的书写方式会引起什么样的后果。(第三章中,会讲述堆栈的原理和缓冲区溢出错误,以及如何利用操作系统、编译器来降低攻击的风险)

详细请看:
CSDN [计算机系统-01] 计算机系统漫游:https://blog.csdn.net/qq_29051413/article/details/116450610
Bilibili CSAPP-深⼊理解计算机系统:https://www.bilibili.com/video/BV1cD4y1D7uR?p=1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
three.js是一款非常流行的JavaScript 3D库,它提供了许多有用的功能,包括创建3D场景、模型加载、纹理映射、动画等等。在three.js中实现漫游系统需要使用摄像机和控制器,下面是一个简单的示例代码: ```javascript // 创建场景 var scene = new THREE.Scene(); // 创建相机 var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(0, 0, 5); // 创建渲染器 var renderer = new THREE.WebGLRenderer(); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // 添加一个立方体到场景中 var geometry = new THREE.BoxGeometry(1, 1, 1); var material = new THREE.MeshBasicMaterial({ color: 0x00ff00 }); var cube = new THREE.Mesh(geometry, material); scene.add(cube); // 创建控制器 var controls = new THREE.OrbitControls(camera, renderer.domElement); // 渲染场景 function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate(); ``` 在这个示例中,我们创建了一个简单的场景,并向其中添加了一个绿色的立方体。我们还创建了一个透视相机,并将其放置在Z轴上,以便我们可以看到场景中的物体。最后,我们使用OrbitControls控制器来允许用户通过鼠标拖动和缩放来漫游场景。 相关问题: 1. 如何使用three.js创建3D场景? 2. three.js中的摄像机有哪些类型? 3. 如何在three.js中添加模型? 4. 什么是控制器?如何使用它们?

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值