<汇编语言系列>计算机硬件系统与汇编
寒假时,有幸拜读了卡内基-梅隆大学(CMU)的Randal E.Bryant 和 David R.O'Hallaron的名著——深入理解计算机系统(Computer System: A Programmer's Perspective)。这本书是来自CMU的一门叫做“计算机系统导论”的课程。让人遗憾的是,国内的大学貌似喜欢开这么一门课。计算机系统导论是个什么层次的课呢?它涉及到的知识有计算机组成原理,汇编语言,操作系统,编译原理,网络编程等。也就是说,它是一个涉及许多CS基础理论的一门课程,它的目的就是让一个Programmer对于计算机系统有一个宏观的感受与认识,知道自己所学的每一门知识是干什么的,以及它与其他知识的联系。这样,在具体的学习时就有了一个比较清晰的概念了。而不是,学一门知识,听得懵懵懂懂,学得有气无力,学完如释重负,等到需要用到时才恍然大悟,却又痛惜那门课学得时候,瞌睡太多了。
吐槽少说,还是回到主题。假期时,主要学习的章节就是书中第3章——程序的机器级表示,关于汇编语言的部分。所有就此记录整理汇编的知识及一些自己的思考。因为本书所讲的汇编乃是基于IA32(Intel 32bit Archtechture)的汇编,而汇编的格式使用的是AT&T的格式,即寄存器名前加"%"符号,如%esp, 指令名小写,如 mov, 指令的最后一位(汇编代码后缀)表示操作数的大小(b: byte, w: word, l: double word; word表示16位);与此相对应的是Intel和Windows使用的另一种格式,寄存器前不加"%"符号,指令名大写。编程环境为ubuntu 14.04, 编译器为gcc。
平时我们所接触到的语言——工作和学习中使用的,一般都是高级语言,如C++或Java之类。而汇编语言,让多数人讳莫如深,因为它和硬件关系密切,使得不懂计算机原理或体系结构,很难学习汇编。由此也更加让许多人远离了汇编,因为懒得因为要学习汇编就去学习计算机原理。然而汇编是如此重要的一门语言,学习它,不一定要用它,至少你可以更好的理解计算机系统和软件的底层实现。CS领域的一位前辈说过:所有的CS问题,都可以通过增加一个中间层而解决。一个中间层,就是对底层的封装与抽象,并提供友好的接口(Interface)给上一层使用。多数时候我们不需要关系更底层的东西,但是有时候,我们还是不得不到下一层的臭水沟去看看,到底是哪里的问题。
计算机硬件系统由处理器(CPU),主存(Memory),I/O控制器及I/O设备。而处理器又由算数逻辑单元(ALU),控制器,及寄存器文件组成。程序的执行是由处理器控制单元控制I/O设备,如硬盘,将数据加载到主存,再通过对数据的读取,由指令数据控制数据在主存和寄存器间的转移及ALU中的计算。寄存器是一个高速存储文件,可以和处理器进行快速的数据交换,而主存就要慢一些了。在汇编语言中会涉及到的,主要就是对主存和寄存器的操作,因为它们是存储数据的实体。同时,最终的计算还是得有ALU进行。由于存储器的虚拟内存及分页技术,我们所使用到的内存地址都是虚拟地址,而对于汇编语言,存储器被抽象为一个字节数组,每一个字节都有一个地址与之对应,并且可以通过这个这个地址对这一字节存储器中存储的数据进行直接访问。这个虚拟地址,也就是我们在C语言中理解的指针。而虚拟地址到物理地址的转化是存储器的控制器做的事,其实就是一个映射关系。(突然觉得映射是高中数学所学概念中,用得最多的一个之一。记得当时还在想,映射这个鬼东西学了能有什么用。。在哈希表中也会用到它。)
一般把计算机语言的发展划分为几个阶段:最初是针对不同机器的指令集的汇编语言;然后有了对汇编语言进行封装的FORTRAN和C;而在面向对象概念提出后有了C++,C#和Java;而近二十年左右,因为硬件资源的改善而出现了对于程序员友好而对效率不那么友好的各种动态语言,即脚本语言,如Python, Ruby, PHP, Javascript,Perl,Lisp。一层层地往上搭建。我们都知道,计算机中的数据是以二进制编码的,机器是只认识0和1这10种数的。所以,所有的程序代码最终都得翻译成二进制代码。(涉及信息的机器级表示及信息论与编码相关知识。) 最开始的汇编,针对不同的指令集(ISA,Instruction Set Architecture),可以直接由汇编指令通过汇编器翻译成机器代码(二进制代码)。之后的C/C++得先用编译器编译成可执行代码,而在编译器编译的过程中,是先使用编译器将C/C++源码翻译成汇编代码,然后再由汇编器将汇编代码翻译成机器代码。而Java及各种脚本语言则是可以先编译成特定的二进制代码,再通过其解释器(Interpreter),解释运行的。而其解释器,通常是由C/C++编写的。解释器就是一个中间层。如非常著名的Java虚拟机(JVM, Java Virtual Machine)。
深入理解计算机系统讲解汇编语言的方式,就是通过讲解汇编语言的基础语法,并通过将C语言翻译成汇编代码来学习汇编。同时,阅读gcc产生的汇编代码及反汇编器通过目标文件(*.o后缀,UNIX/Linux 系统中的一种中间二进制代码)生成的汇编代码来了解C/C++这样的高级语言是如何实现为汇编代码的,并同时研究其优化。之后内容大致分为:
1>IA32寄存器及其访问;
2>数据传送指令;
3>三种类型操作数与寻址方式;
4>算术和逻辑操作;
5>条件码与控制;
6>过程的程序栈实现;
7>数组的分配与访问;
8>异质的数据结构与指针;
9>gcc编译中,汇编语言与C语言的对应关系总结;
转载请注明地址<http://www.cnblogs.com/qiuyi116/p/4320956.html >,谢谢!
<汇编语言系列>计算机硬件系统与汇编的更多相关文章
- 【基于Android的ARM汇编语言系列】之三:ARM汇编语言程序结构
作者:郭嘉 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell [ ...
- redhat系列linux系统 修改主机名的正确方法
##注:无特别说明,以下称呼的linux系统统一视为redhat系linux redhat系列linux系统 如果想修改主机名 很多人可能都会以为是: $hostname NEW-NAME 或者在 / ...
- 制作macOS10.12系列的系统镜像文件
制作macOS10.12系列的系统镜像文件步骤,过程也比较简单,十来个命令.以10.12.6为例,首先,在苹果商店下载系统安装包APP,或者网上下载后把安装APP复制到 应用程序 文件夹. 然后打 ...
- 【基于Android的ARM汇编语言系列】之五:ARM指令集与Thumb指令集
作者:郭嘉 邮箱:allenwells@163.com 博客:http://blog.csdn.net/allenwells github:https://github.com/AllenWell [ ...
- 前端学习 node 快速入门 系列 —— 报名系统 - [express]
其他章节请看: 前端学习 node 快速入门 系列 报名系统 - [express] 最简单的报名系统: 只有两个页面 人员信息列表页:展示已报名的人员信息列表.里面有一个报名按钮,点击按钮则会跳转到 ...
- USB系列之五:用汇编实现的一些USB功能
前面的USB系列一至四,实现了我们需要的一些USB功能,但都是用C语言的32位代码,之后我们插进了三篇关于DOS下设备驱动程序的文章,我们现在应该清楚,当我们要在DOS下写一个U盘的驱动时,最好使用汇 ...
- 在Debian系列Linux系统Ubuntu上安装配置yum的试验
用习惯了Red Hat系统的都知道我们习惯于三种安装方式:一种是rpm包的方式安装,一种就是tar包的方式来安装,还有一种方式就是yum源的安装. 首先rpm包的用法,我们一般是在Red Hat光驱里 ...
- 【Qt编程】基于Qt的词典开发系列<十一>系统托盘的显示
本文主要讨论Qt中的系统托盘的设置.系统托盘想必大家都不陌生,最常用的就是QQ.系统托盘以简单.小巧的形式能让人们较快的打开软件.废话不多说,下面开始具体介绍. 首先,新建一个Qt Gui项目,类型选 ...
- sql server 备份与恢复系列八 系统数据库备份与恢复分析
一.概述 在前面讲过"sql server 备份与恢复系列"都是集中在用户数据库上.sql server还维护着一组系统数据库,这些系统数据库对于服务器实例的运行至关重要.在每次进 ...
随机推荐
- NSCocoaErrorDomain Code=3840 "The operation couldn’t be completed. (Cocoa error 3840.)"
原文: http://stackoverflow.com/questions/19874935/afnetworking-2-0-post-issue-cocoa-error-3840json-tex ...
- [二]Ajax基本实现
<script text="text/javascript"> function ajax(){ var httpRequest; if(windows.httpReq ...
- 最火的Android开源项目(二)
在<直接拿来用!最火的Android开源项目(一)>中,我们详细地介绍了GitHub上最受欢迎的TOP20 Android开源项目,引起了许多读者的热议,作为开发者,你最常用的是哪些开源项 ...
- Dublin Core
DC(Dublin Core) 是数字图书馆中使用的一组简单的包括15个“核心元素”的元数据元素集合,主要用于描述数字对象.馆藏管理和元数据交换. 这15项元数据不仅适用于电子文献目录,也适用于各类电 ...
- 关于IOS中UIWebView 加载HTML内容
NSString *strContent=[info objectForKey:@"newContent"]; { NSArray *paths = NSSearchPathFor ...
- android 文件读取(assets、raw)
需要注意的是,来自Resources和Assets 中的文件只可以读取而不能进行写的操作. assets文件夹里面的文件都是保持原始的文件格式,需要用AssetManager以字节流的形式读取文件. ...
- jrae源代码解析(二)
本文细述上文引出的RAECost和SoftmaxCost两个类. SoftmaxCost 我们已经知道.SoftmaxCost类在给定features和label的情况下(超參数给定),衡量给定权重( ...
- 宽字节SQL注入
1.联想lelink站 例1, 联想lelink站user参数存在宽字节SQL注入 提交,user=wctest%df’ and 1=2%23 结果,出现了”運”字,如图:
- IPv6 neighbor discovery
IPv6 neighbor discovery By stretch | Thursday, August 28, 2008 at 5:03 a.m. UTC Neighbor Discovery P ...
- python调用smtplib模块发送邮件
#!/usr/bin/env python #coding: utf-8 import smtplib from email.mime.text import MIMEText from email. ...