程序是怎样跑起来的

出版日期:2015-4
ISBN:9787115385130
作者:[日] 矢泽久雄
页数:272页

内容概要

作者简介:
矢泽久雄
YAZAWA股份有限公司董事长兼总经理。GrapeCity信息技术集团顾问。电脑作家之友会会长。
曾在某大型电子公司从事过电脑生产,在Software House做过程序员,现主要从事软件包的开发工作。工作之余笔耕不缀,从电路到编程语言均有涉及。代表作有《计算机是怎样跑起来的》《使用C语言学习程序设计的基础》《征服C++类和继承》等。自称软件艺人。
译者简介:
李逢俊
北京易网联信信息技术有限公司CEO。
哈尔滨工业大学硕士毕业后在日工作8年,曾在日本知名游戏公司担任移动互联网部门负责人,拥有丰富的移动游戏开发及运营经验。2011年回国创业,创建易网联信团队(www.easymobi.cn),致力于精品手机游戏的开发及运营。

书籍目录

第1章 对程序员来说CPU是什么  1
1.1 CPU的内部结构解析  3
1.2 CPU是寄存器的集合体  6
1.3 决定程序流程的程序计数器  9
1.4 条件分支和循环机制  10
1.5 函数的调用机制  13
1.6 通过地址和索引实现数组  16
1.7 CPU的处理其实很简单  17
第2章 数据是用二进制数表示的  19
2.1 用二进制数表示计算机信息的原因  21
2.2 什么是二进制数  23
2.3 移位运算和乘除运算的关系  25
2.4 便于计算机处理的“补数”  27
2.5 逻辑右移和算术右移的区别  31
2.6 掌握逻辑运算的窍门  34
COLUMN 如果是你,你会怎样介绍?——向小学生讲解CPU和二进制  38
第3章 计算机进行小数运算时出错的原因  41
3.1 将0.1累加100次也得不到10  43
3.2 用二进制数表示小数  44
3.3 计算机运算出错的原因  46
3.4 什么是浮点数  47
3.5 正则表达式和  EXCESS系统  50
3.6 在实际的程序中进行确认  52
3.7 如何避免计算机计算出错  55
3.8 二进制数和十六进制数  56
第4章 熟练使用有棱有角的内存  59
4.1 内存的物理机制很简单  61
4.2 内存的逻辑模型是楼房  65
4.3 简单的指针  67
4.4 数组是高效使用内存的基础  69
4.5 栈、队列以及环形缓冲区  71
4.6 链表使元素的追加和删除更容易  75
4.7 二叉查找树使数据搜索更有效  79
第5章 内存和磁盘的亲密关系  81
5.1 不读入内存就无法运行  83
5.2 磁盘缓存加快了磁盘访问速度  84
5.3 虚拟内存把磁盘作为部分内存来使用  85
5.4 节约内存的编程方法  88
5.5 磁盘的物理结构  93
第6章 亲自尝试压缩数据  97
6.1 文件以字节为单位保存  99
6.2 RLE  算法的机制  100
6.3 RLE  算法的缺点  101
6.4 通过莫尔斯编码来看哈夫曼算法的基础  103
6.5 用二叉树实现哈夫曼编码  105
6.6 哈夫曼算法能够大幅提升压缩比率  109
6.7 可逆压缩和非可逆压缩  110
COLUMN 如果是你,你会怎样介绍?——向沉迷游戏的中学生讲解内存和磁盘  114
第7章 程序是在何种环境中运行的  117
7.1 运行环境=操作系统+硬件  119
7.2 Windows克服了CPU以外的硬件差异  122
7.3 不同操作系统的API不同  124
7.4 FreeBSD Port帮你轻松使用源代码  125
7.5 利用虚拟机获得其他操作系统环境  127
7.6 提供相同运行环境的 Java虚拟机  128
7.7 BIOS和引导  130
第8章 从源文件到可执行文件  133
8.1 计算机只能运行本地代码  135
8.2 本地代码的内容  137
8.3 编译器负责转换源代码  139
8.4 仅靠编译是无法得到可执行文件的  141
8.5 启动及库文件  143
8.6 DLL文件及导入库  145
8.7 可执行文件运行时的必要条件  146
8.8 程序加载时会生成栈和堆  148
8.9 有点难度的Q&A  150
第9章 操作系统和应用的关系  153
9.1 操作系统功能的历史  155
9.2 要意识到操作系统的存在  157
9.3 系统调用和高级编程语言的移植性  160
9.4 操作系统和高级编程语言使硬件抽象化  161
9.5 Windows操作系统的特征  163
COLUMN 如果是你,你会怎样介绍?——向超喜欢手机的女高中生讲解操作系统的作用  170
第10章 通过汇编语言了解程序的实际构成  173
10.1 汇编语言和本地代码是一一对应的  175
10.2 通过编译器输出汇编语言的源代码  177
10.3 不会转换成本地代码的伪指令  180
10.4 汇编语言语法是“操作码+操作数”  182
10.5 最常用的mov指令  185
10.6 对栈进行push和pop 185
10.7 函数调用机制  187
10.8 函数内部的处理  189
10.9 始终确保全局变量用的内存空间  191
10.10 临时确保局部变量用的内存空间  196
10.11 循环处理的实现方法  199
10.12 条件分支的实现方法  202
10.13 了解程序运行方式的必要性  204
第11章 硬件控制方法  209
11.1 应用和硬件无关?  211
11.2 支撑硬件输入输出的IN指令和OUT指令  212
11.3 编写测试用的输入输出程序  215
11.4 外围设备的中断请求  218
11.5 用中断来实现实时处理  221
11.6 DMA可以实现短时间内传送大量数据  222
11.7 文字及图片的显示机制  224
COLUMN 如果是你,你会怎样介绍?——向邻居老奶奶说明显示器和电视机的不同  226
第12章 让计算机“思考”  229
12.1 作为“工具”的程序和为了“思考”的程序  231
12.2 用程序来表示人类的思考方式  232
12.3 用程序来表示人类的思考习惯  235
12.4 程序生成随机数的方法  237
12.5 活用记忆功能以达到更接近人类的判断  239
12.6 用程序来表示人类的思考方式  242
COLUMN 如果是你,你会怎样介绍?——向常光临的酒馆老板讲解计算机的思考机制  245
附录 让我们开始C语言之旅  247
C语言的特点  247
变量和函数  248
数据类型  249
标准函数库  250
函数调用  251
局部变量和全局变量  254
数组和循环  255
其他语法结构  256

作者简介

本书从计算机的内部结构开始讲起,以图配文的形式详细讲解了二进制、内存、数据压缩、源文件和可执行文件、操作系统和应用程序的关系、汇编语言、硬件控制方法等内容,目的是让读者了解从用户双击程序图标到程序开始运行之间到底发生了什么。同时专设了“如果是你,你会怎样介绍?”专栏,以小学生、老奶奶为对象讲解程序的运行原理,颇为有趣。本书图文并茂,通俗易懂,非常适合计算机爱好者及相关从业人员阅读。


 程序是怎样跑起来的下载 精选章节试读 更多精彩书评



发布书评

 
 


精彩书评 (总计2条)

  •     这两周读了日本作者矢泽久雄写的[《程序是怎么跑起来的》][1],解开了我这个作为通信专业的软件从业者的很多困惑,为了避免日后遗忘,将一些看了这本书之后的问题的解答记录下来。 Q:电脑的CPU中包含哪些部分?各自的作用有哪些? A:CPU包含寄存器,控制器,时钟和运算器四种主要的结构。 - 控制器负责将内存上的指令、数据等读入到寄存器,并根据运算的结果控制整个计算机; - 寄存器用来暂存数据、指令等处理对象,一般CPU包含20~100个不同的寄存器; - 时钟负责CPU开始计时的时钟信号; - 运算器负责运算从内存读入寄存器的数据 从程序员的角度来说,CPU可以看作寄存器的集合。CPU中包含不同种类的寄存器,各自有不同的功能。 Q:一个典型的C语言源代码在电脑中运行的基本流程是怎样的? A:C语言写成的源代码是高级语言程序,但是CPU运行的代码是本地机器语言,因此C的源代码并不能立即运行。实际上,一个C的源代码需要经过编译、和链接生成.exe的可执行文件之后,电脑会将.exe文件的副本复制到内存中再运行。 Q:内存内部结构如何?内存的数据存取都有哪些数据结构? A:内存是计算机的主存储器,通过芯片与计算机相连,主要负责存储指令和数据,CPU通过基址寄存器和变址寄存器读取和写入内存中的数据。内存由连续的长度为8bit(1个字节)的基本元素构成,程序启动之后CPU的控制寄存器根据时钟信号从内存中读取指令和数据。 存取内存的数据结构包括数组、栈、堆、队列、链表和二叉树。我们可以通过指针直接访问和改变对应内存地址中的变量的数值。 - 数组是多个同样类型的数据在内存中连续的排列的形式,可以通过数组的索引访问数组元素; - 栈可以不通过指定地址和索引对数组元素进行读写。栈由栈底、栈顶描述,一般用来临时保存运算过程中的数据、连接在计算机设备上或者输入输出的数据; - 队列与栈相似,栈的元素是FILO,但是队列是FIFO,队列一般用环形缓冲区实现; - 链表与数组不同,它在内存中不是连续存储的,每个元素都有一个直接后继,像串珠一样将每个元素串联起来,最大优势是增减元素方便快捷; - 二叉树中除了最终的子节点之外,每个元素都有两个后继结点,有序二叉树使得搜索变得更有效 Q:数据和程序是如何保存在计算机中的? A:程序和数据是保存在计算机的硬盘中的,但是程序运行需要将机器语言的程序加载到内存,因为CPU的程序计数器指定内存地址才能读出程序内容。内存和磁盘因为自身特点的差异,它们之间具有紧密的联系。 - 磁盘缓存。由于磁盘的读取速度较慢,为了加快程序的运行,将磁盘中的部分数据加载到内存中缓存起来,之后在访问同一个数据的时候就直接从内存中读取数据,这样的机制叫**磁盘缓存**; - 虚拟内存。**虚拟内存**刚好与之相反,在运行比较大的程序或者内存资源比较紧张可以将部分磁盘当作**假想的内存**来用。实现虚拟内存机制需要在磁盘为内存预留空间,并在程序运行时与内存中的内容进行置换(swap),window中提过**分页式虚拟内存机制**。一般虚拟内存的大小与内存相当或者是内存的两倍。 Q:什么是动态链接和静态链接?二者有何不同? A:DLL(Dynamic link libary)是在程序运行时候动态加载的文件。 所謂動態链接,就是把一些經常會共用的程式碼(靜態链接的OBJ程式庫)製作成DLL檔,當執行檔呼叫到DLL檔內的函數時,Windows作業系統才會把DLL檔載入記憶體內,DLL檔本身的結構就是可執行檔,當程式需求函數才進行链接。透過動態链接方式,記憶體浪費的情形將可大幅降低。 简单来说,已经编译成汇编语言的程序文件,在进一步链接时如果直接将库文件链接进exe可执行文件,则该链接文件就是静态库,如果仅仅在程序运行时才进行链接称为动态链接,链接的目标文件就是动态链接库(windows中为dll文件)。需要说明的是,在链接之后,exe文件中包含了静态链接库的所有内容,所以会比较大,而动态链接库相对轻巧,并且**动态链接库可以在被多个同时运行的程序所共有,并且保证内存中只有一个dll文件中调用函数的副本**,这样就节省了程序运行的空间。实际上window操作系统的大部分API目标文件是动态链接库,动态链接库一般由导入库导入,导入库中并不存在目标函数的实体,仅仅保存目标函数所在的动态链接库的名称及路径。 关于动态链接和静态链接的详细介绍请参考博文[C++静态库与动态库](http://www.cnblogs.com/skynet/p/3372855.html "C++静态库与动态库")。 **Q:一个C语言源程序是如何变成可执行文件(exe)的?又是如何在操作系统中运行的?** **A**:这是个比较大的问题,作者在书中举了个C语言的例子。大体来说,C的源程序需要通过编译器编译成汇编语言(asm文件),进一步链接需要的库文件(dll文件)生成可执行文件(exe文件),最后点击exe将可执行文件导入内存运行程序。以Sample.c文件为例 #include <stdio.h> #include <windows.h> char *title = "messgae box"; double average(double a, double b) { return (a + b)/2.0; } int WINAPI WinMain(HINSTANCE h, HINSTANCE d, LPSTR s, int m) { double ave; char buff[80]; ave = average(123,456); sprintf(buff, "average value is %f", ave); MessageBox(NULL, buff, title, MB_OK); return 0; } 1. **编译**该文件,在源文件目录上运行命令`bcc32 -W -c Sample.c`,生成sample.obj目标文件; 2. **链接**需要的库文件,运行命令`ilink32 -Tpe -c -x -aa c0w32.obj Sample.obj, Sample.exe,, import32.lib cw32.lib` 需要说明的是,c0w32.obj文件是与所有程序起始位置相结合的处理内容,称为程序的**启动**。在源程序中,我们**调用**了系统函数sprintf和messagebox,因此,需要将这两个函数对应的库函数(其中的内容与exe文件相同,都是本地代码)**链接**进来,告诉链接器去哪里找这两个函数对应的本地代码。 sprintf的本地代码在cwlib32.lib中,编译之后会将它的目标函数合成到exe文件中,称为**静态链接**;而messagebox的本地代码在库文件user32.dll里,使用import32.dll是为了告诉连接器“messagebox在库文件user32.dll中,以及user32.dll在哪里”,所以import32.dll称为导入库。程序运行时,执行从DLL文件调出的MessageBox()函数这一信息就会和exe文件结合,称为**动态链接**。 **Q:可执行文件包含哪些内容?它加载到内存中是什么样子?** **A**:可执行文件中包含了源程序的变量和函数的虚拟地址,在加载到内存之后需要必要的信息将虚拟地址转换成实际地址,转换需要的信息就在exe文件开始的部分,称为再配置信息。exe文件被加载到内存之后,就将这些虚拟内存转换成实际内存,程序运行中会生成栈和堆,因此在内存中的样子如下图所示 [![3gXgTTNBST7Ua27e9SaE2B5d.jpg](https://s20.postimg.org/ttpdsl5rx/3g_Xg_TTNBST7_Ua27e9_Sa_E2_B5d.jpg)](https://postimg.org/image/bqwb1d9x5/) **Q:c,o,a,lib,obj,dll这些文件分别是什么?他们之间是什么关系?** **A**:c是C语言的源文件,如博文[Linux的.a、.so和.o文件](http://blog.csdn.net/chlele0105/article/details/23691147 "Linux的.a、.so和.o文件") 中所述 > lib,dll,exe都算是最终的目标文件,是最终产物。而c/c++属于源代码。源代码和最终目标文件中过渡的就是中间代码obj,实际上之所以需要中间代码,是你不可能一次得到目标文件。比如说一个exe需要很多的cpp文件生成。而编译器一次只能编译一个cpp文件。这样编译器编译好一个cpp以后会将其编译成obj,当所有必须要的cpp都编译成obj以后,再统一link成所需要的exe,应该说缺少任意一个obj都会导致exe的链接失败。而 .o,是Linux目标文件,相当于windows中的.obj文件,.so文件为共享库,是shared object,用于动态连接的,相当于windows下的dll,.a为静态库,是好多个.o合在一起,用于静态链接 **Q:什么是_BSS段和_DATA段?全局变量和局部变量在程序运行时有何不同?** **A**:这是汇编语言的概念,编译器将高级语言源程序转换成汇编文件(.asm文件),有如下的源文件sample2.c int AddNum(int a, int b) { return a + b; } void MyFun() { int c; c = AddNum(123,456); } 经过编译之后的汇编文件(软件环境win10,gcc编译器)内容如下: ``` .file "sample.c" .text .globl _AddNum .def _AddNum; .scl 2; .type 32; .endef _AddNum: pushl %ebp movl %esp, %ebp movl 8(%ebp), %edx movl 12(%ebp), %eax addl %edx, %eax popl %ebp ret .globl _MyFun .def _MyFun; .scl 2; .type 32; .endef _MyFun: pushl %ebp movl %esp, %ebp subl $24, %esp movl $456, 4(%esp) movl $123, (%esp) call _AddNum movl %eax, -4(%ebp) leave ret .ident "GCC: (tdm-1) 4.9.2" ``` 汇编程序最接近机器语言,而且其与C语言一一对应,所以通过汇编文件就可以了解程序运行的大体情况。从上面的汇编文件,可以看到如下的结果 1. 寄存器esp指向栈顶元素地址,每个元素占据4个字节的数据; 2. 在每个函数开始的时候,都要将寄存器ebp的数据压入栈中进行保护; 3. 上述程序中隐藏的一个关键步骤是在第21行,call AddNum时,计算机已经将MyFun函数的下一个指令的地址压入栈中,在调用完AddNum时(第12行),返回函数Myfun时候会自动将栈中的返回指令的地址出栈交给CPU的程序计数器,这样就可以实现在调用函数之后仍然返回原来的调用的地方; 4. 函数的入参被保存在栈中,返回值被保存在寄存器里。 ```c int a; int b; float fl; int c = 9; int d = 10; int e = 11; int f = 12; void MyFun(void) { int a1,b1,c1; float fl1; a1 = 1; b1 = -1; fl1 = -99.34; c1 = -87; a1 = a; b1 = b; fl1 = fl; c1 = c; } ``` 以上的C源代码转换成汇编语言是 ``` .file "sample2.c" .comm _a, 4, 2 .comm _b, 4, 2 .comm _fl, 4, 2 .globl _c .data .align 4 _c: .long 9 .globl _d .align 4 _d: .long 10 .globl _e .align 4 _e: .long 11 .globl _f .align 4 _f: .long 12 .text .globl _MyFun .def _MyFun; .scl 2; .type 32; .endef _MyFun: pushl %ebp movl %esp, %ebp subl $16, %esp movl $1, -4(%ebp) movl $-1, -8(%ebp) movl LC0, %eax movl %eax, -12(%ebp) movl $-87, -16(%ebp) movl _a, %eax movl %eax, -4(%ebp) movl _b, %eax movl %eax, -8(%ebp) movl _fl, %eax movl %eax, -12(%ebp) movl _c, %eax movl %eax, -16(%ebp) leave ret .section .rdata,"dr" .align 4 LC0: .long -1027166700 .ident "GCC: (tdm-1) 4.9.2" ``` 从中可以看出全局变量保存在.comm和.globl段,局部变量保存在寄存器中,因此在程序运行的整个过程中,全局变量可以随时访问,但是局部变量却会在用过之后消失。 关于windows的汇编的内容可进一步参考文章[汇编与逆向分析](http://www.mouseos.com/assembly/index.html "汇编与逆向分析") --- 以上是此书最干货的部分,书中该介绍了计算机二进制数,和计算机硬件的部分内容,再次略过不提。
  •     本书和《计算机是怎么跑起来的》是一对,分别对应着计算机科学导论,计算机组成原理这些书的简明版。这个是我看过的第4本日系技术书,日系技术书,特别是图灵日系书,特点就是书的开本比较小,全彩印刷,内容相对简单,整本书很轻,不过说实话,不建议购买,对于小白来说还是有难度的,但对有经验的人来说大部分可能都太简单,难的依然很难,简单的太简单。对于《程序是怎么跑起来的》,可看性可能比《计算机是怎么跑起来的》更好,其中讲CPU、内存和磁盘、压缩算法可以说是整本书的精华所在了。

精彩短评 (总计50条)

  •     本书和另外一本一样,很基础。从计算机核心部件的基本组成和数据的表示,到程序和内存的本质,再到操作系统等基础知识,以及还包括了很具体的函数调用实现机制。总的来说,看完后对整个计算机软硬件都有了更深的理解。
  •     通俗易懂
  •     计算机组成原理的趣味解读版,语言通俗易懂,图解很到位,很适合初学者。
  •     比教科书好看易懂,深度刚好。
  •     整体非常不错,简洁易懂。对于我们这种非计算机专业,然后又经常需要编程的人来说,比较合适,一两天就能了解底层的东西。汇编和CPU那部分讲的很好。
  •     像我这样如果不是科班出身,又啃不动《计算机组成原理》这种大部头的话,阅读这种寓教于乐的版本是非常合适的
  •     有许多重要的地方讲得不是很清楚,但确实是计算机书里面看着很轻松的
  •     日本人真会写书。
  •     终于看完了,学到很多冷知识 -- 因为有些其实已经不适用了
  •     周日下午的时间,再次复习了程序的编译、装载和运行。这类书的阅读难度从易到难:《程序是怎样跑起来的》-->《程序员的自我修养》-->《链接器和装载器》。
  •     复习计算机组成原理?
  •     读起来还真得有点基础,但作者已经尽力了,计算机这东西本来就是工程领域的创造,必须具备一定理论基础才能读懂。
  •     一本剖析程序如何运行科普书籍,从源代码、编译器、本地代码执行有一个完整和详细的解说。对初学者有很大的帮助。
  •     嘛 挺有趣
  •     太粗浅,当温故用吧。
  •     通俗 读完一遍就好
  •     零基础女生小白表示看起来略费劲。。语言干巴巴的
  •     一个简化版的 CSAPP,还不错
  •     一本有趣有基础的书,内容不多,但足以引发兴趣。
  •     我一直推崇日本的技术书,比如图解TCP/IP,可是这本书确实真的一般般,前面针对基础知识的讲解还算是可以的,但是后面就天马行空,根本抓不住主题了。
  •     印刷错误好多……内容不错,搞清了一些小问题,但总体来说太浅了。
  •     通俗易懂,内容范围广。 汇编那里依旧有点懵逼,不过还是懂了不少。 猜拳游戏那里很有意思
  •     看到压缩那里都能理解,后面汇编呀,操作系统开始理解起来就有点不懂了。基础性知识还是有点欠缺。
  •     很有意思的一本书,一看就懂。不像老师上课和那些“教课范本”那样枯燥。看完就想去学汇编了,感觉好有趣!
  •     2015年9月读:这本书并不适合已经看过人邮大部头著作的人回头看,它就是专门为新手而写,涉及各个概念且讲解的通俗易懂,当然浅,但这正是新手所需要的特质,后面补人邮大部头。
  •     怎么样?是不是发现有一些问题无法简单地解释清楚呢?下面是笔者的答案和解析,供大家参考。
  •     大体心里有个谱!完全了解是不够的。
  •     书薄,简单,易懂,适合外行爱好者。
  •     你们说说我他妈是不是有病(是(从未否认
  •     为了买《图解密码技术》,凑数买了这本书,虽然基本都理解,但是却不是什么通俗读物,不能算入门读物挂着入门读物的名字,不知道为啥要搞个彩色版。三星凑合吧
  •     很棒的入门书,比科班的教材有趣多了,但是看完了还是得去看教材。但再读教材就不是完全零基础了。算是帮助理解的课外读物吧。
  •     想入门组成原理还是去看 编码 吧
  •     开头比较水,中间从C语言到汇编那段有点干货
  •     通俗语言版本的编码,在硬件介绍的同时也兼顾了软件,阅读时间1下午足够,可以回顾很多细节,以及一些理解的不是特别透彻的地方
  •     初中教材应该这样!
  •     科普计算机组成原理,然而这方面缺乏背景知识读的有点囫囵吞枣
  •     书中有些小错误,特别是讲到第10章汇编,有些图片中的寄存器标错了。翻译有些地方比较拗口,比如“参阅”,我觉得应该翻译成“访问”。
  •     计算机组成原理和操作系统的简化版本,注意不是简单版本,适合随便翻翻
  •     内容太简单
  •     看到评论说 浅显易懂 的时候,对自己绝望了…
  •     入门时候遇到这本书就好了!
  •     介绍了计算机科学常识和软件运行的机理。
  •     怎么说呢 日本人写的科普…说是写给电脑白痴看的…然而我还是看不懂…由此可以推出…什么…结论…呢?我连二进制的逻辑右移和算数右移无法好好领悟 活着还有什么用…
  •     2015.09.26
  •     开了个小差
  •     通俗易懂,虽然深度很浅,但其本质目的达到了,确实是好书
  •     内容浅显易懂。码代码的人还需了解底层啊。
  •     和 一样值得推荐,计算机的本质本没有那么复杂,都被专家教授的一大堆外星语搞得没人想学,这本书用人类可以理解的语言配合示例简要的介绍了cpu,内存,硬盘,操作系统等基本概念,及他们是如何演变成现在这样的。将一个概念讲出来不难,但将一个概念给别人讲懂了才难。
  •     计算机基础
  •     从硬件底层讲解了程序是如何跑起来的,包括IC,汇编指令,C语言,编译器,内存,CPU。
 

外国儿童文学,篆刻,百科,生物科学,科普,初中通用,育儿亲子,美容护肤PDF图书下载,。 零度图书网 

零度图书网 @ 2024