EventLoop、Webkit、V8原理分析之基础知识

1,069 阅读6分钟

基础知识

CPU 是怎样工作的

CPU 指令集CPU 组成
x86/x64指令集控制器
ARM指令集运算符
MIPS指令集存储器(临时存储,不是内存,内存是CPU外面的
RISC指令集

详细架构

下面这句代码是怎么运行的

console.log('hello world');
  • js解释引擎 -> 词法分析 -> 语法分析 -> 语法抽象树 -> 机器指令 -> 机器语言

计算机语言的发展

  • 本源:二进制数据
  • 第一代语言:机器指令 01010...(面向机器)
  • 第二代语言:汇编指令(面向机器)
  • 第三代语言:高级语言 c(面向过程)
  • 第四代语言:面向对象语言 java c++ javascript

了解汇编语言

  • 最接近底层的机器语言
  • 直接操作硬件,没有任何抽象
  • 由指令和数据组成,没有任何语句
  • 指令收到硬件平台限制,可移植性较低
  • 了解一些底层语言知识,有助于理解计算机的运作机制和内存管理
section .data   ;数据段
  hello: db 'Hello World/n',10
  helloLen: equ $-hello  ;'Hello World!'字符串长度
section .text
  global _start  ;告诉操作系统,程序指令从这儿开始
_start:
  mov ax,4  ;4系统调用号,将数字4放到16位的寄存器中
  mov ebx,1  ;1:标准输出文件描述符,
  mov ecx,hello  ;存放hello字符串的首地址
  mov edx,helloLen  ;存放字符串长度
  int 80h  ;软中断,陷入内核
  mov ax,1  ;系统调用号
  move ebx,0 ;返回值,0表示没有错误.exit(0)
  int 80h

说白了,就是将 'hello world'和 描述该字符串的长度放到内存中

# c 语言
int main() {
  printf('hello world');
  # return 0;
  exit(0)
}

我xx你xx,这应该就是是面向医院编程了吧~

了解C语言

include <stdio.h>  // 引入标准输入输出库

int add(int x, int y)
{
  return x + y;
}

int main(int argc, char const *argv[])
{
  printf("hello world\n");
  printf("%d\n", add(100, 200)); // 是内味儿了,你就说python像不像它
  return 0;
}

C语言编译过程

C语言和JS的异同

  • C语言是编译型语言
  • JS是解释性语言
  • C语言要借助编译器转换成可执行程序
  • JS要借助解释引擎运行

C语言与C++语言的区别

  • C++是新的编程语言,并不是C的扩展
  • C语言是面向过程,C++是面向对象
  • C和C++都有标准库(可以理解为Java的JDK)
  • 目前C主要应用在网络相关和嵌入式方面
  • 目前C++主要应用在复杂引擎和应用软件方面

理解内存和指针

  • 内存:内存条(计算机硬件)
  • 内存地址:内存块编号
  • 指针:是保存着内存地址的变量
    • 注意:指针不是地址,而是一个变量,它保存着内存地址
  • 引用(无):作为指针与内存地址中间变量,防止频繁操作指针(改变指针的指向),高级语言才有的特性,C语言中没有引用
  • 指向变量(或数据)的指针
  • 指向指针的指针
    • 二级(多级)指针,打个比方(为什么要打比方,比方是我朋友😊),去车库取车 -> 找到哪个车库 -> 哪一层 -> 那块区域 -> 第几排第几列
  • 指向函数的指针
    • 程序本质上是通过函数来进行运算,即保存函数保存的地址
// 入口函数
int main() {
  int a = 10; // 声明一个整形的变量
  int b = a + 10; // 直接寻址,没有经过指针的参与
  // int * p_int = a // error 声明一个指针,指针必须是整形,指针不能直接a
  int *p_int = &a; // &符号表示寻找后面变量的地址,一级指针 *,二级指针 **
  // int c = p_int + 10; // error 这表示给 p_int 指针的内存地址 + 10,这是不对的,应该是通过 p_int 的内存地址找到变量的值 10 + 10,怎么取,*p_int
  int c = *p_int + 10;
  
  int d = 5;
  fn(d)
  // d = 5
}

// 函数 fn
void fn(int d) {
  d = 10; 
}

C语言如何实现引用

  • C语言是没有引用的,如何想实现类似引用的效果,需要借助二级指针
int main(){
  int i = 5;
  fn(i);
  // i = 5
}
void fn(int **a){
  **a = 10;
}

数组

int arr1[] = [1,2,3]; // arr1 相当于一个指针来用
int arr2[][] = [
       [1,2,3],
       [4,5,6]
    ]; // arr2 相当于二级指针来用

了解 C++ 语言

  • 支持数据的抽象与封装
  • 支持面向对象编程
  • 支持泛型编程
  • C++_几乎_是C语言的一个超集,它与C语言的基本语法有许多相同之处,例如变量和函数的声明,原生数据类型等等。
  • 10分钟快速了解C++
int main(int argc, char** argv){
  sizeof('c') == 1; // 字符字面量的大小是一个字节
  sizeof('c') == sizeof(10); //在C语言中,字符字面量的大小与int相同
  return 0; // 退出
}

内存动态分配

  • C语言没有垃圾自动回收
    • 申请连续的200byte大小的内存:int *memeory_a = malloc(200);用完手动归还内存:free(memeory_a)
  • java(JVM)、Node(V8虚拟机) 都是基于内存动态分配、垃圾自动回收的 | 内存 | 对应内存段位 | 描述 | 特性 | |:--|:--|:--|:--| | 栈区 | 数据段 | 是一个确定仓鼠(1-2M)不同平台大小不同,超出stackoverflow | 自动分配、自动释放 | | 堆区 | 数据段 | 用于动态内存分配 | 手动分配和释放 | | 全局或静态区 | 数据段 | 程序中明确被初始化的全局变量、静态变量(全局静态变量和局部静态变量)和常量数据(如字符串常量)| 只初始化一次 | | 程序代码区 | 代码段 | 代码区指令根据程序设计流程依次执行,对于顺序指令,则只会执行1次(进程);如果反复,则需要使用跳转指令。如果进行递归,则需要借助栈来实现 | 代码区的指令中包括操作码和被操作对象(或对象地址医用) |

后续文章

EventLoop、Webkit、V8原理分析之进阶知识

❤️ 加入我们

字节跳动 · 幸福里团队

Nice Leader:高级技术专家、掘金知名专栏作者、Flutter中文网社区创办者、Flutter中文社区开源项目发起人、Github社区知名开发者,是dio、fly、dsBridge等多个知名开源项目作者

期待您的加入,一起用技术改变生活!!!

招聘链接: job.toutiao.com/s/JHjRX8B