昨日解惑
1.汇编语言(ASM CODE)
一种低级的编程语言,是一种方便人类阅读的抽象机器语言。汇编语言运用许多助记符,达成类似C语言的关键词和函数等特殊功能,但使用汇编语言需要了解计算机的底层结构和指令集。
但为什么要写汇编语言需要了解硬件呢 ? 因为汇编语言是助记符,本质是机器语言,机器语言是跟硬件搭勾的。比如1001 1000这串,它可以是字面值,指令码,设备地址,取决于它在哪个寄存器里面,在cs里面是代码段地址,在ip里是代码段偏移,在ss里是堆栈栈底内存,在bs里面是当前context的堆栈栈底,在sp里面是当前context栈顶,在ax里面可能是操作数,可能是内存地址。
因此基于计算机不同的架构和指令集差异,汇编语言的代码在不同的平台上不一定通用,它只能运行在特定架构的CPU上,广泛运用于ARM架构和Intel芯片的X86架构。
但学会汇编语言方便我们了解计算机底层是如何运作的,它就是可以用来直接操作计算机的硬件,同时它也被广泛应用于定位设备驱动和嵌入式系统上的底层性能问题。
周末找时间入门一下。
2.空循环体
打比方有以下两种写法,循环结构后面直接跟上;号,循环体内无其他内容。空循环常规用于让程序"暂停"一段时间,或者等待某一个外部条件跳出循环,否则一直阻塞在这个循环。
while(1);这种叫做无穷循环,它永远不会结束。
for(x = 0;x < 500000;x++);
while(!kbhit());
还需测试,我应该知道设计的空循环体会延迟多久。
3.编译器
我们平时所说的程序,是指双击后就可以直接运行的程序,这样的程序被称为可执行程序(Executable Program)。在 Windows 下,可执行程序的后缀有 .exe 和 .com(其中 .exe 比较常见);在类 UNIX 系统(Linux、Mac OS 等)下,可执行程序没有特定的后缀,系统根据文件的头部信息来判断是否是可执行程序。
可执行程序的内部是一系列计算机指令和数据的集合,它们都是二进制形式的,CPU 可以直接识别,毫无障碍;但是对于程序员,它们非常晦涩,难以记忆和使用。
//举例说明
puts("VIP会员");
//对应的二进制数据如下
//指令部分 ------------------------ 数据部分 ---------------------------
10110000 10101011 00110001 00011100 00110011 00111110 01010011 11110000
//输出指令 V I P 会 员
为了方便理解提高生产力,程序员设计了各类编程语言。但计算机只能理解二进制语言,所以需要编译器将C语言等编程语言重新转换为机器能够识别的二进制指令和数据,也就是将代码加工成 .exe 程序。这就是编译器,它的执行过程又称“编译”,可以理解为翻译。感兴趣可以自行阅读《编译原理》一书,但不必了解具体的编译原理。
因此,编译器会指出报错你的代码语法是否存在错误。
C语言的编译器有很多种,不同的平台下有不同的编译器,例如:
Windows 下常用的是微软编译器(cl.exr),它被集成在 Visual Studio 或 Visual C++ 中,一般不单独使用;
Linux 下常用的是 GUN 组织开发的 GCC,很多 Linux 发行版都自带 GCC;
Mac 下常用的是 LLVM/Clang,它被集成在 Xcode 中(Xcode 以前集成的是 GCC,后来由于 GCC 的不配合才改为 LLVM/Clang,LLVM/Clang 的性能比 GCC 更加强大)。
//还需了解
4.集成环境
实际开发中,除了编译器是必须的工具,我们往往还需要很多其他辅助软件,例如:
编辑器:用来编写代码,并且给代码着色,以方便阅读;
代码提示器:输入部分代码,即可提示全部代码,加速代码的编写过程;
调试器:观察程序的每一个运行步骤,发现程序的逻辑错误;
项目管理工具:对程序涉及到的所有资源进行管理,包括源文件、图片、视频、第三方库等;
漂亮的界面:各种按钮、面板、菜单、窗口等控件整齐排布,操作更方便。
这些工具通常被打包在一起,统一发布和安装,例如 Visual Studio、Dev C++、Xcode、Visual C++ 6.0、C-Free、Code::Blocks 等,它们统称为集成开发环境(IDE,Integrated Development Environment)。
相当于一台主机需要多个硬件组成,我还需要知道一些具体的常见的,比如windows系统下的集成开发环境有哪些。
第2章 基本概念
ANSI C的任何一种实现中,存在两种不同的环境。
一种是翻译环境,源代码被转换为可执行的机器指令。
第二种是执行环境,用于实际执行代码。
这两种环境不必位于同一台机器上,交叉编译器和操作系统就是这个道理。标准也讨论了独立环境,就是不存在操作系统的环境,在嵌入式系统中,如微波炉控制器中可以遇到这类型的环境。
1.翻译环境
翻译的过程,也就是昨日解惑中翻译器的运作原理,将源文件的源代码转换为机器可以识别的二进制数据。只是一个程序往往包含多个源文件,每个源文件被解析后的目标代码会经由链接器捆绑在一起形成一个整体可执行的程序。
编译过程也分为三个阶段,预处理 -> 解析 -> 优化。在解析过程中报错,在程序调试完毕之后才会正式优化处理,优化过程会占用较多的时间。
书中第二部分,编译和链接,采用UNIX系统中,被称作cc的C编译器,描述了
"cc program.c"
"cc main.o lookup.o sort.c"
"cc -c main.c sort.c lookup.c"
等调用、命令方式执行指令。
这一块并不理解,或许今后也用不到。
2.执行环境
将程序载入到内存中,在宿主环境中(具有操作系统的环境)初始化变量 -> 负责收集命令行参数等日常事务 -> 调用main函数 -> 执行代码 -> 中止代码。
在绝大多数机器的执行过程中,程序将使用一个运行时堆栈,它用于存储函数的局部变量和返回地址。程序同时也可以使用静态内存,存储于静态内存中的变量在程序的整个执行过程中将被一直保留。
3.词法规则
一个ANSI C程序由声明和函数组成。函数定义了需要执行的工作,声明描述了函数或函数要操作的数据类型,有时是数据本身。注释可以散步在源文件各处。
标准并未规定C环境必须使用哪种字符集,但它规定了英语所有大小写,数字0-9和常见符号,字符集还包括换行符,空格、水平制表符、垂直制表符和格式反馈字符。
此外,标准还定义了三字母词,比如 ??) 表示 ] ,在部分printf打印结果下可能产生程序员意料之外的结果,需要注意。
此外,K&R C定义了几个转义序列和字符转义。
\? 在书写连续多个问号时使用,防止他们被解释为三字母词
\" 用于表示一个字符串常量内部的双引号
\' 用于表示字符常量
\\ 用于表示一个反斜杠,防止它被解释为一个转义序列符
\a 警告字符。他将奏响终端铃声或产生其他一些可听见或看见的信号。
\b 退格键
\f 进纸字符
\n 换行符
\r 回车符
\t 水平制表符
\v 垂直制表符
\ddd ddd表示1~3个八进制数字,这个转义符表示的字符就是给定的八进制数值所代表的字符
\xddd 与上例类似,只是表示十六进制数
标识符就是变量、函数、类型等的名字。他们由大小写字母、数字和下划线组成,但不能以数字开头。以下C语言关键字是被保留的,他们不能作为标识符使用:
char | signed | for | if | switch | auto | const |
short | unsigned | do | else | case | extern | sizeof |
int | struct | while | goto | default | register | typedef |
long | void | break | return | static | volatile | |
float | union | continue | ||||
double | enum |
注释不允许嵌套。
课后习题
尚待学习尝试。
感言
1.慢慢地理清楚一些以前只会用的工具到底是什么,心里稍微有点底。
2.有制作图片的话更方便理解回顾,我争取补足。
3.富文本编辑器写文章好像有很多功能没法实现?比如目录文字链接这种,是否需要学习MD编辑器。
4.还是有点烦躁,下班后并不乐意,还是说学习代码的时间不充裕。目前仅仅是概念性的东西较多,之后务必需要大量时间用来撰写调试程序的。
英语
assembly汇编 compile翻译 compiler编译器 stack堆栈 token标记
identifier标识符
2024.3.28发布