【CSAPP笔记】4. 汇编语言——基础知识
程序的机器级表示
计算机能读懂是机器代码(machine code)—— 用字节序列编码的低级操作 —— 也就是0和1。编译器基于编程语言的规则、目标机器的指令集和操作系统的规则,经过一系列阶段产生机器代码。由于机器语言全是由0和1组成的,所以对于编程人员来说编写机器代码十分困难,也不容易学习。汇编语言(assembly language)就是机器语言的可读形式,学习汇编语言有很多的好处。
An assembly (or assembler) language,[1] often abbreviated asm, is a low-level programming language for a computer, or other programmable device, in which there is a very strong (generally one-to-one) correspondence between the language and the architecture's machine code instructions.
Machine code or machine language is a set of instructions executed directly by a computer's central processing unit (CPU). Each instruction performs a very specific task, such as a load, a jump, or an ALU operation on a unit of data in a CPU register or memory. Every program directly executed by a CPU is made up of a series of such instructions......Numerical machine code (i.e., not assembly code) may be regarded as the lowest-level representation of a compiled or assembled computer program or as a primitive and hardware-dependent programming language.
我们在用高级语言编程时(例如C语言),高级语言本身提供的抽象级别比较高,因此有“程序设计”的概念,方便我们编程。大多数情况下,抽象级别比较高,工作效率就会提高,也更高效可靠。高级语言相较汇编语言的一个最大优点是:用高级语言编写的程序可以在很多不同的机器上运行,而汇编代码与硬件本身有关联,例如指令集不同那么汇编代码就不同。
Each assembly language is specific to a particular computer architecture. In contrast, most high-level programming languages are generally portable across multiple architectures but require interpreting or compiling.
那我们为什么要花时间学习汇编和机器代码呢?
纵观计算机的发展历程,有一个很重要的观点就是用分层的思路来构造整个系统,每个下层都对其上层隐藏本层的细节。这个抽象原理对于理解计算机很多方面的知识都有帮助,例如网络四层模型就是一个很典型的例子。扯回编程语言这块,由于语言是“高级”的,自然屏蔽了很多机器级实现过程的细节。例如,如果只是单纯的学习C语言,那对于寄存器、程序计数器、系统的栈、缓冲区溢出等知识点没有办法很好的理解,因为它们对于C语言程序员来说都是被隐藏的处理器状态。C语言的指针通常是引起错误和不理解的来源,但在汇编中访存、取地址都是很常见的操作。学习汇编,能让你学到一些在C语言学习中由于粒度不够细而学不到的东西。除此之外,读完这一章之后,你还能领略到C语言的伟大之处。
抽象和分层是很重要的思想,但对于严谨的学习者来说,并不意味只要懂得抽象原理就足够了。能够阅读和理解汇编代码是仍是一项很重要的技能。精通细节是理解更深和更基本概念的先决条件。随着时间的推移,对于汇编代码的学习需求也有变化,我们现在不需要直接用汇编语言编写程序,只需要能够阅读并理解编译器产生的代码就可以了。
处理器执行的指令,被编码成二进制形式。一个处理器支持的指令及其编码集称为指令集体系结构(Instruction-Set Architecture, ISA)。
An instruction set, with its instruction set architecture (ISA), is the interface between a computer's software and its hardware, and thereby enables the independent development of these two computing realms; it defines the valid instructions that a machine may execute.
ISA就是机器级程序的格式和行为,这种类型的指令,每一条完成的工作都是非常基本的,例如把两个数相加。因此学习汇编代码就有助于我们了解编译器在把C代码转换成机器代码时所做的转换。相对于C代码,编译器重新排列执行顺序、消除不必要的计算和变量、用基本的、快速的操作代替慢速操作,甚至用迭代替代了递归。学习逆向工程(reverse engineering),来研究高级语言,甚至研究系统创建的过程。(好书啊好书)
可以说,汇编语言很有其特殊性,高级语言的一些抽象的概念,都被归一和具象化了,C语言的指针,在汇编的世界里简直不值一提,因为地址,对地址的引用再平常不过了。另一方面,内存,缓存,寄存器,CPU,又构成了一个奇妙的世界,它们屏息恭立,静待主公的每一条喻令。
我不相信,一个人用纯手工一条条指令去雕琢他的程序,用手指感受计算机的呼吸时会无动于衷。……
作者:匿名用户
链接:https://www.zhihu.com/question/23088538/answer/23631875
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
Architecture
汇编内容比较多,部分涉及具体细节的内容有删减,仅做简单介绍,详情请参考书本。
处理器
Intel 处理器系列俗称 x86,经历了一个长期的、不断发展过程。1965年,Intel公司的创始人Gordon Moore,根据当时的芯片技术(那时他们能够在一个芯片上制造大概有64个晶体管的电路)做出推断:未来10年内,芯片上晶体管数量每年都能翻一番。这个预测就是著名的摩尔定律。正如事实所证明的那样,他的预测有点乐观,还有点短视。在超过45年中,半导体工业一直能够让晶体管数量每18个月翻一番。
指令集
就像上面讲到的那样,计算机系统用到了许多不同形式的抽象,利用简单的模型隐藏各种细节。其中之一就是指令集,也就是ISA。在学习汇编时,ISA模型给人的感觉好像看上去应该是顺序指令执行,也就是先取出一条指令,等到它执行完毕,再开始下一条。然而处理器的实际工作方式远比这种模式精细复杂,因为处理器可以并发执行多条指令,因此需要做很多的额外工作。在计算机科学中,用巧妙的方法在提高性能,并完成更多更复杂的功能的同时,又同时保持了一个更简单、更抽象的底层模型功能,这种想法是无处不在的。
IA32和x86-64就是两种ISA,也是着重介绍的重点。这两者是当今大多数计算机的主导语言,后者是前者在64位机器上的扩展版本。
IA32的机器代码和原始C代码差别非常大。下面这些对于C语言程序员隐藏的概念在IA32中是可见的:
程序计数器(Program Counter,简称PC)
- 用来指示将要执行的下一条指令的地址。
整数寄存器文件(Register File)
- 非常重要的概念。用来存储地址(对应C语言的指针)或者整数数据,或者用来记录程序的状态,或者保持临时数据,例如局部变量、函数的返回值等等。
条件码(Condition Code)
- 保持最近执行过的算术or逻辑指令的状态信息。用来实现控制或数据流条件变化。(对应C语言的if等等)
对于机器级编程来说,有第另一种极为重要的抽象,那就是把存储器地址抽象成虚拟地址(Virtual Memory),提供的模型,让机器代码只是简单地把存储器看成是一个非常大的字节数组。所以,C语言中的各种数据类型,和自定义数据类型(struct),在机器代码中都是用一组字节来表示。汇编代码不区分有符号、无符号常数,不区分各种类型的指针,甚至不区分指针和整数。
程序存储器(Program Memory)
- 包含程序的可执行机器代码,操作系统需要的一些信息,例如支持系统运行的栈,以及为用户分配的存储器块(例如malloc)。程序存储器用虚拟地址来寻址(Addressable),操作系统负责管理虚拟地址空间,将虚拟地址翻译成实际处理器中的物理地址。
处理器能够执行的操作其实是非常有限的,简单来说只有三种:存取数据、计算和传输控制。存取数据是在内存和寄存器之间传输数据,进行计算则是对寄存器或者内存中的数据执行算术运算,传输控制主要指非条件跳转和条件分支。
代码示例
下面给出一个C语言代码以及其汇编代码中的一些关键行。一开始看不懂没关系,我们只需要对其有一个感性认知。
int accum = 0;int sum(int x, int y)
{int t = x + y;accum += t;return t;
}
对应的由编译器产生的汇编代码(部分行)如下:
sum:pushl %ebpmovl %esp, %ebpmovl 12(%ebp), %eaxaddl 8(%ebp), %eaxaddl %eax, accumpopl %ebpret
观察汇编语言代码,我们可以看到第一个字符串就是操作符,后面可能跟着几个操作数,由逗号分开。操作符就被唯一解码成对应的机器指令,但汇编语言的操作符是能让我们看得懂的。
在汇编代码中,每一行都代表一条机器指令。例如pushl就是把寄存器%ebp的内容压入栈。这段代码已经不存在任何关于局部变量名和数据类型的信息(除了全局变量accum,还没有确定会放在哪里)。
如果使用汇编器(Assembler)将汇编语言翻译为机器语言,机器语言是二进制格式,无法直接查看。但其中有一列17个字节的字节序列:
55 89 e5 8b 45 0c 03 45 08 01 05 00 00 00 00 5d c3
这就是上面列出的汇编指令对应的机器代码。我们可以看出来,机器实际执行的就是对一系列指令进行编码的字节序列。机器对于我们写的C语言代码可以说是一无所知的。
See Also
- zhihu 学习汇编语言有什么好处?
- CMU 2017年春季学期 ICS课程网站
转载于:https://www.cnblogs.com/ZCplayground/p/6658954.html
【CSAPP笔记】4. 汇编语言——基础知识相关推荐
- 《Java并发编程实践》学习笔记之一:基础知识
<Java并发编程实践>学习笔记之一:基础知识 1.程序与进程 1.1 程序与进程的概念 (1)程序:一组有序的静态指令,是一种静态概念: (2)进程:是一种活动,它是由一个动作序列组成 ...
- 前端学习笔记(js基础知识)
前端学习笔记(js基础知识) JavaScript 输出 JavaScript 数据类型 常见的HTML事件 DOM 冒泡与捕获 流程控制语句 for..in 计时器 let,var,const的区别 ...
- LTE-V2X笔记:一些基础知识
原文转载地址:LTE-V2X笔记:一些基础知识 (1)LTE-V2X技术 频段:5905~5925MHZ(试验频段) 调制方式:QPSK 正交相移键控 功率:23dBm (2)LTE-V2X通信模式 ...
- 【学习笔记】网络安全基础知识总结
网络安全基础知识总结 前言 一.网络安全概述 1.1 引言 1.2 密码学的发展 1.3 密码学基础 1.4 对称密码 1.4.1 数据加密标准DES 二.数论知识 2.1 数论基础 2.2 有限域 ...
- Python基础笔记_Day01_计算机基础知识和Python开发环境搭建
Day01_计算机基础知识和Python开发环境搭建 目录 01.01_计算机基础知识(计算机概述)(了解) 01.02_计算机基础知识(软件开发和计算机语言概述)(了解) 01.03_计算机基础知识 ...
- JAVA学习笔记(1)【基础知识】
JAVA学习笔记DAY_1 提示:关于java系列的内容只是本人在老师的指导下和自学过程中的一些学习笔记,如果存在错误敬请批评指正! 文章目录 JAVA学习笔记DAY_1 前言 一.Java语言未来的 ...
- dw 快速html注释,笔记整理1-HTML基础知识与DW简单使用-工具-站长头条
笔记整理1 -- HTML基础知识与DW简单使用 笔记整理1 -- HTML基础知识与DW简单使用 概念 客户端和服务器端 文件名.基本名.扩展名 资源文件和站点 什么是HTML 关于W3C W3C的 ...
- x86汇编语言基础知识
文章目录 内存 总线 寄存器 通用寄存器 段寄存器 状态标志 EIP指令指针 数据表示 x86基本操作指令 指令格式 操作数 x86汇编语言必备知识 x86汇编语言主要包括总线.寄存器结构,数据类型, ...
- JS学习笔记二——JavaScript 基础知识
JavaScript 基础知识 一.JavaScript 变量 二.JavaScript 的输出 三.JavaScript 运算符 四.结语 一.JavaScript 变量 变量是指在程序运行过程中, ...
- 嵌入式linux编程,嵌入式Linux学习笔记 - 嵌入式Linux基础知识和开发环境的构建_Linux编程_Linux公社-Linux系统门户网站...
注:所有内容基于友善之臂Mini2440开发板 一.嵌入式Linux开发环境的构建 嵌入式开发一般分为三个步骤: 1.编译bootloader,烧到开发板 2.编译嵌入式Linux内核,烧到开发板 3 ...
最新文章
- angular select设置默认选中_改进 Angular + Jest 项目中组件测试的调试
- 策略模式,状态模式,监听模式之间的区分。
- Nginx配置proxy_pass转发的/路径问题
- Java设计模式—模板方法模式
- 删除Oracle数据库时常见问题(注册表方面,文件目录方面,环境变量方面)
- 前方危险-让很多“高逼格”高管深刻反思的文章
- B端产品经理,应从哪些方面理解业务?
- pythonxml读写_python xml读取和写入
- Flutter 系列文章:Flutter Text 控件介绍
- 数据库事务特征、数据库隔离级别,以及各级别数据库加锁情况(含实操)--read uncommitted篇...
- IntellJ IDEA可以单独调试一个类
- (转)高新技术在高频交易中的运用
- 微信小程序地图插件使用
- 数据结构实训——统计成绩
- 天线和频率(波长)关系
- 服务器2008系统 stop c0000218,电脑蓝屏STOP:C0000218错误解决方法实记
- destoon标签大集合
- 微信支付 django
- 支持iframe的div分隔线插件
- 洛谷 [P3975 [TJOI2015]弦论