# 编程之路（一）：c语言的出现

我们都知道C语言程序会被编译为汇编语言程序，然后会被执行，实际执行时，是将汇编语言程序通过汇编器转换为机器指令才能执行。想想在没有C语言、汇编语言的时候，程序员的编程只能是通过一堆 0 和 1 的组合、编写来实现，也就是机器语言的编程，而描述机器语言的规则（0/1组合的协议）有一个统一名称：指令集架构 Instruction Set Architecture（ISA）

# ISA

## 简介

什么是指令集架构？

指令集体系结构（ISA）是计算机抽象模型的一部分，它定义了软件如何控制 CPU。ISA充当硬件和软件之间的接口，指定处理器能够做什么以及如何做。

ISA 是用户能够与硬件交互的唯一途径。它可以被视为程序员手册，因为它是机器的一部分，对汇编语言程序员、编译器编写者和应用程序程序员来说都是可见的。

ISA 定义了：支持的数据类型、寄存器、硬件如何管理主存、关键功能（如虚拟内存）、微处理器可以执行的指令以及多个 ISA 实现的输入/输出模型。ISA 可以通过添加指令或其他功能，或者通过添加对更大地址和数据值的支持来扩展。

参考：

[GLOSSARY-Instruction Set Architecture (ISA)](https://www.arm.com/glossary/isa)

[LCSO-What is instruction set architecture](https://www.learncomputerscienceonline.com/instruction-set-architecture/)

为什么需要了解ISA？

从定义我们知道 ISA 是软件与硬件之间沟通的桥梁，是 CPU 厂商提供给我们的支持的功能说明，软件程序实际执行还是会回归到硬件、回归到 CPU，汇编程序经汇编器生成的机器指令也都必须符合特定平台的 ISA 规则才能执行。如上所述，了解 ISA 可以帮助我们更好的理解编译器的输出，编写更高效的代码。我们可以把 ISA 看作是所有编程语言的始祖，是所有程序员应必备的开发手册。

## 分类

ISA 指令集主要分为两种类型：复杂指令集 CISC（Complex Instruction Set Computer）、精简指令集 RISC（Reduced Instruction Set Computer）

CISC 指令集内部执行时会被拆分为更细粒度的指令执行，提供的功能也更加定制化、强大，可能一条指令就能实现复杂的操作，RISC 则更加精简。

> ### **Characteristics of RISC**
> 
> 1. Relatively few instructions.
>     
> 2. Relatively few addressing modes.
>     
> 3. Memory access is limited to load and store instructions.
>     
> 4. All operations are done within the registers of the CPU.
>     
> 5. Fixed-length, easily decoded instruction format.
>     
> 6. Single-cycle instruction execution.
>     
> 7. Hardwired rather than microprogrammed control.
>     
> 8. A relatively large number of registers in the processor unit.
>     
> 9. Use of overlapped register windows to speed-up procedure call and return.
>     
> 10. Efficient instruction pipeline.
>     
> 11. Compiler support for efficient translation of high-level language programs into machine language programs.
>     
> 
> ### **Characteristics of CISC**
> 
> 1. A larger number of instructions – typically from 100 to 250 instructions
>     
> 2. Some instructions that perform specialized tasks and are used infrequently
>     
> 3. A large variety of addressing modes – typically from 5 to 20 different modes
>     
> 4. Variable-length instruction formats
>     
> 5. Instructions that manipulate operands in memory
>     

RISC 阵营的典型代表是ARM，CISC 阵营的典型代表是Intel

有关这两种类型之间的详细对比，参考：[Difference Between RISC and CISC](https://alldifferences.net/difference-between-risc-and-cisc/)

要选择一个平台进行深入了解的话，这里推荐 Intel 平台，因为 CISC 类型提供的指令功能更加强大，加上 Intel 目前也较为常用，这样可以通过 Intel 平台提供的开发手册进行详细分析。

Intel开发手册下载：[Intel® 64 and IA-32 Architectures Software Developer Manuals](https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html)

# 汇编语言简介

面对一堆只有 0 和 1 的代码，机器语言程序的编写既繁琐又不容易理解、维护，因此为了方便开发，降低理解难度，发展出了汇编语言，以助记符的形式提升开发效率。我们可以将汇编语言看作一张映射 Hash 表，汇编器实际做的工作就是将助记符与具体机器指令之间进行对应、转换。

站在 CPU 的角度，我们可以想象 ISA、汇编程序 无非都是操作的 CPU 和 内存，CPU提供控制、计算的作用，内存 则是 CPU 的数据来源。一条计算机指令，包括了要操作的目的、要操作的对象，分别对应指令中的 操作码 和 操作数。对数据的操作指令会有以下一些类型：

1. 移动：内存 -&gt; CPU、CPU -&gt; 内存
    
2. 运算：+、-、\*、/
    
3. 移位、逻辑运算
    
4. ……
    

汇编语言中的操作码包括 mov、add、sub 等命令，同时我们需要知道操作内存时候具体的大小，内存寻址的最小单位是 1 byte，以 mov 举例，movw、movl、movq 分别对应 2、4、8 个字节的内存空间移动操作。

# C语言的引入

汇编语言的使用，要求开发人员熟悉内存操作的具体单位、并且需要知晓 CPU 中寄存器的分类、应用细节，对程序员要求较高，开发也不方便。因此在汇编的基础上，又进行一次抽象，屏蔽掉诸多细节，让语言符合人类的认知。

设计这样一门语言，具体包括如下需求要点：

1. 设计类型系统，屏蔽对内存单元大小的访问；
    
2. 定义符号，抽象对数据的操作，比如使用 +、-、\*、/ 来替换具体操作指令；
    
3. 添加语言自身的特性。
    

这些设计需求，就是汇编语言上层更高级语言的由来，而基于此，C语言完成了对汇编语言最纯粹的抽象：实现了自己的类型系统，定义了支持的符号，并没有自己其他任何的特性。

# 小结

本篇重点介绍了 ISA 的概念以及分类，同时基于此介绍汇编语言、C语言的由来，知其所以然，才能更好地去学习、掌握上层的语言。
