《程序是怎么样跑起来的》学习记录

提示:这本书和《计算机是怎么样跑起来的》和《网络是怎么样连接的》一样,都是介绍计算机基础知识的入门书籍,都以大白话辅之图讲解,适合跨行的初学者,看完之后绝对有意想不到的收获,有时间的同学可以直接看纸质原版书籍或电子书,没时间的直接看我总结的重点即可 !


第一章 对程序员来说CPU是什么

1)程序是什么?
指示计算机每一步动作的一组指令
2)程序由什么组成?
指令和数据
3)什么是机器语言?
CPU可以直接识别并使用的语言
4)正在运行的程序存储在什么位置?
内存
5)什么是内存地址?
内存中,用来表示命令和数据存储位置的数值
6)计算机的构成原件中,负责程序的解释和运行的是哪个?
CPU

在这里插入图片描述
CPU和内存是有许多晶体管组成的电子部件:统称为IC(集成电路)
CPU:寄存器、控制器、运算器、时钟四个部分构成
寄存器:暂存指令、数据等处理对象,看作是内存的一种
控制器:把内存上的指令,数据读入寄存器,根据指令的执行结果控制整个计算机
运算器:负责运算从内存读入寄存器的数据
时钟:负责发出CPU开始计时的时钟信号,也有一些计算机的时钟位于CPU的外部
时钟信号的频率:1GHz=10亿次/秒,时钟信号的频率越高,CPU运行速度越快
在这里插入图片描述
内存:计算机的主存储器,简称主存
主存通过控制芯片与CPU相连,主要负责存储指令和数据
主存由可读写的元素构成,每个字节(1字节=8位)都带有一个地址编号
CPU可以通过该地址读取主存中的指令和数据,当然也可以写入数据
主存中存储的指令和数据会随着计算机的关机而自动清除
在这里插入图片描述
程序启动时
1)根据时钟信号,控制器从内存读取指令和数据,加以解释和运行
2)运算器会对数据进行运算,控制器根据运算结果来控制计算机:主要就是数据输入输出的时机控制
在这里插入图片描述
汇编器:将汇编语言转化成机器语言的程序
编译器:将高级语言(C++,java)转化为机器语言

CPU是具有各种功能的寄存器的集合体
CPU每执行一个指令,程序计数器的值就会自动加1
CPU的控制器会参照程序计数器的数值,从内存读取命令并执行
程序计数器决定者程序的流程

顺序执行:指按照地址内容顺序执行,每执行一个指令程序计数器的值就自动加1
条件分支:根据条件执行任意地址的指令
循环:重复执行同一地址的指令

溢出(overflow):是指运算的结果超出了寄存器的长度范围
奇偶校验:是指检查运算结果的值是偶数还是奇数

标志寄存器:根据运算结果是正数,0,还是负数,自动设定三个位

函数调用:通过把程序计数器的值设定成函数的存储地址来实现
在这里插入图片描述
在这里插入图片描述
函数调用使用的call指令,而不是跳转指令
1)call指令会把调用函数后要执行的指令地址存储在名为栈的主存内
2)函数处理完毕后,再通过函数的出口来执行return命令,
把保存在栈中的地址设定到程序计数器中

通过基址寄存器和变址寄存器对主存上特定的内存区域进行划分
在这里插入图片描述

第二章 数据是用二进制数表示的

1)32位是几个字节?
4字节,8位=1字节
2)二进制数01011100转换成十进制数是多少?
64+16+8+4=92
3)二进制数00001111左移两位后,会变成原数的几倍?
4倍
4)补码形式表示的8位二进制数11111111,用十进制表示的话是多少?
-1
5)补码形式表示的8位二进制数10101010,用16位的二进制数表示的话是多少?
1111111110101010
6)反转部分图形模式时,使用的是什么逻辑运算?
XOR运算,反转与1相对应的位

在这里插入图片描述
IC的所有引脚,只有直流电压0V或5V两个状态,IC的一个引脚,只能表示两个状态
8位二进制数被称为1个字节,字节是最基本的信息计量单位,位是最小单位
如果数字小于存储数据的字节数(二进制的位数),高位用0填充
100111这个6位二进制数,用8位(1字节)表示时为00100111

移位运算能代替乘法和除法运算
左移后空出来的低位,要补0,二进制数左移1位就是扩大了2倍

二进制表示负数时,一般会把最高位作为符号来使用,符号位为0表示正数,为1表示负数
在这里插入图片描述
计算机做减法运算时,实际内部是在做加法运算
在这里插入图片描述
补数就是用正数来表示负数,取反+1即可
例如1是 00000001
1取反后是11111110
+1后是 11111111(-1的8位二进制数表示)

此时1+(-1)=00000001+ 11111111=100000000,
最高位溢出,故得00000000=0
在这里插入图片描述
知道一个数是负数,那负负可得其正数
比如知道11111111是负数,对其取反+1=00000001=1就是其正数,
因此就知道了11111111代表-1

整数数据类型的解释?
以下都是2字节(16位)的变量,可以表示2^16=65536种值,但范围不一样
unsigned short:不能处理负数,范围是0~65535,将最高位为1的数值看做32768以上的值
short:-32768~32767,将最高位为1的数值看做补数
为啥负数比正数多一个,因为把0划分到正数了
最高位是0的正数有032767共32768个,最高位是1的负数有-1-32768共32768个
在这里插入图片描述
逻辑右移:当二进制数表示图形模式而非数值时,移位后最高位补0,类似霓虹灯往右滚动,溢出的低位被忽略掉
在这里插入图片描述
算术右移:当二进制数作为带符号的数值进行运算时,移位后要在最高位填充移位前符号位的值(0或者1)
如果数值是用补数表示的负数值,那么右移后空出来的最高位补1,就可以正确的实现1/2,1/4的运算,如果是正数,只需在最高位补0

例如-4=11111100,右移两位,逻辑右移=00111111=63
算术右移=11111111=-1,就是-4的1/4
在这里插入图片描述
计算机能处理的运算大体可分为算术运算和逻辑运算
算术运算:将二进制数表示的信息作为四则运算的数值来处理
逻辑运算:像图形模式那样,将数值处理为单纯的0和1的罗列
在这里插入图片描述
CPU的引脚有电流通过的时候数值是1,没有电流通过的时候数值为0

第三章 计算机进行小数运算时出错的原因

1)二进制数0.1,用十进制数表示的话是多少?
0.5=2^-1
2)用小数点后有3位的二进制数,能表示十进制数0.625吗?
0.101=12-1+0*2-12^-2=0.625
3)将小数分为符号、尾数、基数、指数4部分进行表现的形式称为什么?
浮点数(浮点数形式)
4)二进制数的基数是多少?
2
5)通过把0作为数值范围的中间值,从而在不使用符号位的情况下表示负数的表示方法称为什么?
EXCESS系统表现
6)10101100.01010011这个二进制数,用16进制数表示的话是多少?
AC.53二进制数的4位相当于16进制数的1位

计算机出错的原因:有一些十进制数的小数无法转换成二进制数,
例如十进制0.1,就无法用二进制数正确表示
实际上十进制0.1转换成二进制后会变成0.00011001100…这样的循环小数
就好像无法用十进制数来表示1/3一样,1/3=0.3333…循环小数
计算机是无法处理无限循环小数的,会根据变量数据类型所对应的长度将
数值从中间截断或四舍五入
在这里插入图片描述
小数点后4位用二进制数表示时的数值范围为0.0000~0.1111
因此只能表示0.5,0.25,0.125,0.0625这4个二进制数小数点后面的位权组合而成
(相加总和)的小数
在这里插入图片描述
浮点数0.1234510^3 定点数:123.45
浮点数0.12345
10^-1 定点数:0.012345
在这里插入图片描述
double:双精度浮点数用64位
float:单精度浮点数用32位
浮点数是指用符号、尾数、基数和指数这4部分来表示小数,二进制基数为2
符号:使用一个数据位表示数值的符号,1表示“负”,0表示“正或者0”
小数就是用“尾数部分*2^指数部分次幂”
尾数部分用的是“将小数点前面的值固定为1的正则表达式”
指数部分用的是:EXCESS系统表现
在这里插入图片描述
正则表达式:按照特定的规则来表示数据的形式即为正则表达式
除小数外,字符串以及数据库都有各自的正则表达式
在这里插入图片描述
EXCESS系统表现:通过将指数部分表示范围的中间值设为0,使得负数不需要用符号来表示
通俗说法:假设有一个游戏1~13(A-K)的扑克牌表示负数,将中间的7这张牌当成0
10就是+3,3就是-4
在这里插入图片描述
如何避免计算机出错
1)回避策略,得到近似值即可,微小误差可以忽略
2)将小数转换成整数来计算,扩大成整数计算后再缩小回来即可
除此之外,BCD是一种使用二进制表示十进制的方法,用4位来表示0-9的1位数字,涉及财务的计算不允许出现误差,要确保准确的数值
在这里插入图片描述
二进制数的4位相当于16进制数的1位,二进制数能缩短为原来的1/4
只需在数值的开头加上0x就表示十六进制数
在这里插入图片描述

第四章 熟练使用有棱有角的内存

1)有十个地址信号引脚的内存IC(集成电路)可以指定的地址范围是多少?
2^10=1024个地址
用二进制数来表示的话是0000000000~11111111111,
用十进制数来表示的话就是0~1023

2)高级编程语言中的数据类型表示的是什么?
占据内存区域的大小和存储在该内存区域的数据类型
例如short:表示占据2字节的内存区域,并且存储整数

3)在32位内存地址的环境中,指针变量的长度是多少位?
32位,指针指的是用于存储内存地址的变量
4)与物理内存有着相同构造的数组的数据类型长度是多少?
1字节,物理 内存是以字节为单位进行数据存储的
5)用LIFO方式进行数据读写的数据结构称为什么?

6)根据数据的大小链表分叉成两个方向的数据结构称为什么?
二叉查找树BST

内存实际上是一种名为内存IC的电子元件
ROM:只读内存
RAM:可读可写内存
DRAM:需要经常刷新保存数据
SRAM:不需要刷新电路即可保存数据
内存IC:有电源,地址信号,数据信号,控制信号等用于输入输出的大量引脚(IC的引脚),通过为其指定地址来进行数据的读写
在这里插入图片描述
数据信号引脚有八个,表示一次可输入8位(1字节)的数据
地址信号引脚有A0到A9共10个,表示可以指定0000000000~11111111111共1024个地址
在这里插入图片描述
地址表示数据的存储场所,故这个内存IC可以存储1024个1字节的数据
1024bytes=1K,故该内存IC的容量就是1KB
在这里插入图片描述
通常情况下计算机的内存IC会有更多的地址信号引脚,用少量的内存IC达到更大的容量
在这里插入图片描述
编程语言中的数据类型:表示存储的何种类型的数据,从内存来看,就是占用的内存大小(占有的楼层数)

变量的数据类型不同,存储相同的数据占用的内存大小也不一样
用合适的袋子装合适的物品

低字节序:把多字节数据的低位字节存储在内存低位地址的方式
高字节序:把多字节数据的高位字节存储在内存低位地址的方式

指针也是一种变量:表示的不是数据的值,而是存储着数据的内存的地址
通过是一种指针,就可以对任意指定地址的数据进行读写
指针前面的数据类型表示的是从指针存储的地址中一次能够读写的数据字节数
在这里插入图片描述
数组:多个同样数据类型的数据在内存中连续排列的形式
索引:作为数据元素的各个数据会通过连续的编号被区分开,称为索引
指定索引后,就可以对该索引所对应的内存进行读写操作
索引和内存地址的变换工作是有编译器完成的
在这里插入图片描述
栈和队列:都可以不通过指定地址和索引来对数组的元素进行读写
如果每次都要指定地址和索引,程序会变得麻烦,
适合需要临时保存计算过程中的数据

链表:增加删除方便,除了数据的值之外,为其附带上下一个元素的索引
二叉查找树:查询方便,搜索更有效率

第五章 内存和磁盘的亲密关系

1)存储程序方式指的是什么?
在存储装置中保存程序,并逐一运行的方式
2)通过使用内存来提高磁盘访问速度的机制称为什么?
Disk Cache(磁盘缓存)
3)把磁盘的一部分作为假想内存来使用的机制称为什么?
虚拟内存(virtual memory)
4)Windows中,在程序运行时,存储着可以动态加载调用的函数和数据的文件称为什么?
DLL(DLL文件)
5)在EXE程序文件中,静态加载函数的方式称为什么?
静态链接
6)在Windows计算机中,一般磁盘的1个扇区是多少字节?
512字节

在这里插入图片描述
内存(主内存):利用电流来实现存储,高速高价,小容量
磁盘(硬盘):利用磁效应来实现存储,低速廉价,高容量

存储在磁盘的程序需要读入到内存后才能运行
在这里插入图片描述
磁盘缓存(实际是内存):把从磁盘中读出的数据存储到内存空间,
当接下来需要读取同一数据时,就不用通过实际的磁盘
而是从磁盘缓存中把内容读出,大大改善磁盘数据的访问速度

虚拟内存(实际上是磁盘):把磁盘的一部分作为假想的内存来使用
这与磁盘缓存是假想的磁盘(实际是内存)相对

虚拟内存实现:把实际内存(物理内存)的内容和磁盘上的虚拟内存的内容进行部分置换,并同时运行程序
在这里插入图片描述
虚拟内存有分页式和分段式两种
Windows采用分页式:在不考虑程序构造的情况下,将运行的程序按照一定大小的页(page)进行分割,并以页为单位在内存和磁盘间进行置换
Page In:磁盘的内容读出到内存
Page Out:内存的内容写入到磁盘
Windows计算机的页大小是4KB,就是说大程序用4KB来进行切分,并以页为单位放入磁盘(虚拟内存)或内存中

分段式:把要运行的程序分割成以处理集合及数据集合等为单位的段落
然后再以分割后的段落为单位在内存和磁盘之间进行数据置换

虚拟内存无法彻底解决内存不足的问题:使用虚拟内存时发生的Page in和
Page out往往伴随着低速的磁盘访问,因此应用的运行会迟钝起来
内存不足解决办法:
1)增加内存容量:花费高
2)把运行的应用文件变小
2-1)通过DLL文件实现函数共有
在这里插入图片描述
DLL:程序运行时可以动态加载Library(函数和数据的集合)的文件
多个应用可以共有一个DLL文件,节约内存
优点:在不变更EXE的情况下:只升级DLL文件就可以更新软件
在这里插入图片描述
静态链接:导致内存的利用率降低
2-2)通过调用_stdcall来减小程序文件的大小
栈清理处理:把不需要的数据从接受和传递函数的参数时使用的内存上的栈区域中清理出去
在被函数调用方处理时(_stdcall)比在函数调用方处理可以节约一些内存
在这里插入图片描述
磁盘划分方式
1)扇区方式:将磁盘划分为固定长度的空间
2)可变长方式:将磁盘划分为长度可变的空间
磁道:把磁盘表面分成若干个同心圆的空间
扇区:把磁道按照固定大小(能存储的数据长度相同)划分而成的空间
扇区是磁盘进行物理读写的最小单位:1扇区=512字节

对磁盘进行读写的单位是扇区的整数倍簇
根据磁盘容量的不同,1簇可以是512字节(1簇=1扇区),1KB(1簇=2扇区)等
磁盘容量越大,簇的容量也越大
在软盘中,1簇=1扇区=512字节,簇和扇区的大小是相等的
不同的文件是不能存储在同一个簇中的,否则只有一方的文件不能被删除
不管是多么小的文件,就会占用1簇的空间

如果减少簇的容量,磁盘访问次数就会增加,导致读写文件时间变长
扇区和簇的大小,是由处理速度和存储 容量的平衡来决定的。

第六章 亲自尝试压缩数据

1)文件储存的基本单位是什么?
1字节=8位
2)DOC,LZH和TXT这些扩展名,哪一个是压缩文件的扩展名?
LZH
3)文件内容用"数据的值*循环次数"来表示的压缩方法是RLE算法还是哈夫曼算法?
RLE算法,例如AAABB压缩后就是A3B2
4)在Windows计算机经常使用的SHIFT JIS字符编码中,1个半角英数是用几个字节的数据来表示的?
1字节=8位,汉字等全角字符是用两个字节表示的
5)BMP(BITMAP)格式的图像文件,是压缩过的吗?
没有压缩过,JPEG压缩过
6)可逆压缩和非可逆压缩的不同点是什么?
压缩后的数据能复原的是可逆压缩,无法复原的是非可逆压缩(如JPEG

文件中的字节数据时连续存储的
在这里插入图片描述
RLE算法:“数据*重复次数”的形式来压缩
在这里插入图片描述
缺点:实际文本文件中,同样字符多次重复出现的情况并不多见
针对相同数据经常连续出现的图像、文件等,可以有不错的效果
并不适合文本文件的压缩
在这里插入图片描述
莫尔斯编码:通过嗒嘀嗒嘀这些长点和短点的组合来传递文本信息
把1看作短点(嘀),11看作长点(嗒)
把一般文本中出现频率高的字符用短编码表示
在这里插入图片描述

哈夫曼算法:多次出现的数据用小于8位的字节数来表示
不常用的数据则可以用超过8位的字节数来表示
为各压缩对象文件分别构造最佳的编码体系,并以该编码体系为基础来进行压缩,

哈夫曼树:不使用字符区分符号的情况下,也可以构建能够明确进行区分的编码体系
频率越低的数据到达根部的枝条数就越多,编码的位数也就随之增多
在这里插入图片描述
压缩后的数据能复原的是可逆压缩(GIF),无法复原的是非可逆压缩(如JPEG)
BMP:未压缩图像格式,原始图像
JPEG:数码相机 常用的一种图像数据形式,将高频率(强烈的颜色变化)的部分剪切掉了,颜色强烈的变化部分有一些模糊
TIFF:在文件头中包含“标签”就能够显示出数据性质的图像数据形式
GIF:要求色数不超过256色,怀远后颜色信息会有一些缺失,导致模糊
在这里插入图片描述
压缩算法种类很多:因为压缩比率,压缩需要的处理时间(程序的复杂程度)以及各种文件的需求等是不一样的

第七章 程序是在何种环境中运行的

1)应用的运行环境,指的是什么?
操作系统和计算机本身(硬件)的种类
2)Macintoch用的操作系统(MacOS),在AT兼容机上能运行吗?
无法运行
3)Windows上的应用,在MacOS上能运行吗?
无法运行
4)FreeBSD提供的Ports,指的是什么?
通过使用源代码来提供应用,并根据运行环境进行整合编译,
从而得以在该环境下运行的机制
5)在Macintoch上可以利用的Windows环境模拟器称为什么?
Virtual PC for Mac
6)Java虚拟机的功能是什么?
运行Java应用的字节代码

运行环境=操作系统+硬件

CPU只能解释其自身固有的机器语言
在这里插入图片描述
本地代码:机器语言的程序
源代码:高级语言编写的文本文件
编译器:将源代码转化成本地代码

移植porting:根据不同的运行环境来重新调整程序

虚拟机:运行其他操作系统的应用
在这里插入图片描述
Java虚拟机:把Java字节代码逐一转换成本地代码一边运行
Java虚拟机就是运行环境
缺点:
1)不同的Java虚拟机之间无法进行完整互换
2)运行速度慢,每次运行都要把字节代码变换成本地代码

BIOS:预先内置在计算机主机的内部的程序
除了键盘、磁盘、显卡等基本控制程序外,还有启动“引导程序”的功能
引导程序:把在硬盘等记录的OS加载到内存中运行
虽然启动应用是OS的功能,但OS 并不能自己启动自己,通过引导程序启动

第八章 从源文件到可执行文件

1)CPU可以解析和运行的程序形式称为什么代码?
本地代码(机器语言代码)
2)将多个目标文件结合生成EXE文件的工具称为什么?
链接器
3)扩展名为.obj的目标文件的内容,是源代码还是本地代码?
本地代码
4)把多个目标文件收录在一起的文件称为什么?
库文件
5)仅包含Windows的DLL文件中存储的函数信息的文件称为什么?
导入库
6)在程序运行时,用来动态申请分配的数据和对象的内存区域形式称为什么?

任何变成语言编写的源代码,最后都要翻译成本地代码,否则CPU就不能理解
每个编写源代码的变成语言都需要其专用的编译器
EXE文件的程序内容:使用的就是本地代码
本地代码的真实面目就是数值的罗列
同样的源代码可以转换成适用于不同处理器的本地代码

确定编译器种类的三个关键词:1)什么语言 2)什么CPU 3)什么环境
在这里插入图片描述
链接:把多个目标文件结合,生成1个EXE文件的处理

源代码.c->编译->目标文件.obj(本地代码)->链接多个目标文件->exe文件

库文件:把多个目标文件收录在一起
外部符号:其他目标文件中的变量和函数
无法解析的外部符号:无法找到记述目的变量及函数的目标文件,无法进行链接

API:应用程序接口,以函数的形式为应用提供了各种功能

导入库:仅包含Windows的DLL文件中存储的函数信息的文件
静态链接库:存储者目标文件的实体,并直接和EXE文件结合的库文件形式
DLL文件:程序运行时动态结合文件

双击EXE文件,就会把EXE文件的内容加载到内存中
EXE文件中给变量和函数分配的是虚拟的内存地址,程序运行时,虚拟的内存地址会转换成实际的内存地址

再配置信息:链接器在EXE文件的开头,追加转换内存地址所需的必要信息
EXE文件的再配置信息:就成为了变量和函数的相对地址
相对地址:表示的是相对于基点地址的偏移量,也就是相对距离
在这里插入图片描述
EXE文件的内容:再配置信息,变量组,函数组
程序加载到内存后,还会生成栈和堆两个组
EXE文件并不存在栈和堆的组,栈和堆所需要的内存空间是在EXE文件加载到内存后开始运行时得到分配的
:存储函数内部临时使用的变量(局部变量),以及函数调用时所用的参数的内存区域
栈中对数据进行存储和舍弃的点=代码是编译器自动生成的,不需要程序员的参与,使用栈的内存空间,每当函数调用时都会申请分配,函数处理完毕后自动释放
:存储程序运行时的任意数据及对象的内存领域
堆的内存空间,由程序员自己申请分配和释放,掌握不好就会内存泄漏

不管是什么程序,程序的内容都是由处理和数据构成的,
用函数来表示处理,变量来表示数据

垃圾回收机制:对处理完后的不再需要的堆内存空间的数据和对象进行清理,释放它们所使用的内存空间,java和C#自动进行垃圾回收

第九章 操作系统和应用的关系

1)监控程序的主要功能是什么?
程序的加载和运行,监控程序也可以说是操作系统的原型
2)在操作 系统上运行的程序称为什么?
应用和应用程序
3)调用操作系统功能称为什么?
系统调用(system call)
4)Windows Vista是多少位的操作系统?
32位(也有64位的版本)
5)GUI是什么的缩写?
图形用户界面(Graphical User Interface)
6)WYSIWYG是什么的缩写?
What You See Is What Your Get(所见即所得)

应用并不是直接控制硬件,而是通过操作系统来间接控制硬件
在这里插入图片描述
高级编程语言的机制:使用独自的函数名,然后再编译时将其转换成相应操作系统的系统调用(也有可能是多个系统调用的组合)

移植性:同样的程序在不同的操作系统 下运行时需要花费的时间,费时越少说明移植性越好
在这里插入图片描述
通过使用操作系统的系统调用,程序员就没必要编写直接控制硬件的程序了
有时甚至无需考虑系统调用的存在,因为操作系统和高级编程语言能够使硬件抽象化

文件是操作系统对磁盘媒介空间的抽象化

Windows通过名为API的函数集来提供 系统调用的
API是联系做成应用的程序员与操作系统之间的接口
在这里插入图片描述
多任务处理:Windows通过时钟分割技术来实现
在这里插入图片描述
时钟分割技术:短时间间隔内,多个程序切换运行的方式
在用户看来,就是多个程序在同时运行
多线程:以程序中的函数为单位来进行时钟分割
线程是操作系统分配给CPU的最小运行单位
源代码中的一个函数就相当于一个线程
多线程处理就是指在一个程序中同时运行多个函数

中间件:处于操作系统和应用的中间,比如网络功能和数据库功能

程序是操作系统、中间件、应用等所有软件 统称
程序员制作的应该是应用,而不是操作系统

第十章 通过汇编语言了解程序的实际构成

1)本地代码的指令中,表示其功能的英语缩写称为什么?
助记符
2)汇编语言的源代码转换成本地代码的方式称为什么?
汇编
3)本地代码转换成汇编语言的源代码的方式称为什么?
反汇编
4)汇编语言的源文件的扩展名,通常是什么格式?
.asm,是assembler(汇编器)的略写
5)汇编语言程序中的段定义指的是什么?
构成程序的命令和数据的集合组
6)汇编语言的跳转指令,是在何种情况下使用的?
将程序流程跳转到其他地址时需要用到该指令

在这里插入图片描述
使用助记符的编程语言称为汇编语言

CD:Change Dirctory变更目录

汇编语言的源代码:
1)操作码(转换成本地代码的指令)
2)伪指令(针对汇编器):负责把程序的构造及汇编的方法指示给汇编器
在这里插入图片描述
段定义:命令和数据等程序的集合体,是一个连续的内存空间
segment伪指令表示段定义的起始
ends伪指令表示段定义的结束
在这里插入图片描述
汇编语言的语法:操作码(动词)+操作数(宾语)
操作码:类似mov这样的指令
操作数:指令对象的内存地址及寄存器
在这里插入图片描述
mov指令:指定数据的存储地和读出源

函数的参数是通过栈来传递,返回值是通过寄存器来返回的
在这里插入图片描述
在这里插入图片描述
没有初始化的全局变量会被设置成0

局部变量会在寄存器被用于其他用途时自动消失
在这里插入图片描述

第十一章 硬件控制方法

1)在汇编语言中,是用什么指令在同外围设备进行输入输出操作的?
IN指令和OUT指令
2)I/O是什么的缩写?
Input/Output
3)用来识别外围设备的编号称为什么?
I/O地址或I/O端口号
4)IRQ是什么的缩写?
Interrup Request:执行硬件中断请求的编号
5)DMA是什么的缩写?
direct Memory Access:不经过CPU,外围设备直接同计算机主内存进行数据传输
6)用来识别具有DMA功能的外围设备的编号称为什么?
DMA通道

在这里插入图片描述
IN指令:通过指定端口号的端口输入数据,并将其存储在CPU内部的寄存器中
OUT指令:把CPU寄存器中存储的数据,输出到指定端口号的端口
在这里插入图片描述
端口:I/O控制器中有用于临时保存输入输出数据的内存,这个内存就是端口,也称为I/O地址
就像是计算机主机和外围设备之间进行货物(数据)装卸的港口
I/O控制器内部的内存,也称为寄存器,但和CPU内部的寄存器功能不同
CPU内部的寄存器:数据的运算处理
I/O寄存器:临时存储数据
在这里插入图片描述
中断处理
0)CPU接收到中断请求后,会把当前运行的主程序中断,并切换到中断处理程序
1)把CPU所有寄存器的数值保存到内存的栈中
2)在中断处理程序中完成外围设备的输入输出后
3)把栈中保存的数值还原到CPU寄存器中
4)然后继续对主程序进行处理
在这里插入图片描述
没有中断,主程序就必须持续不断的检测外围设备是否有数据输入(轮询)

DMA:短时间内传送大量数据
在这里插入图片描述

第十二章 让计算机思考

1)用计算机进行的模拟试验称为什么?
计算机模拟
2)伪随机数指的是什么?
通过公式产生的伪随机数,具有周期性
3)随机数的种子指的是什么?
生成伪随机数的公式中使用的参数
4)计算机有思考功能吗?
没有
5)计算机有记忆功能吗?
有,比如内存和磁盘
6)AI是什么的缩写
Artificial InterIIigence

在这里插入图片描述
线性同余法:Ri+1=(a*Ri+b)mod c
如果a=5,b=3,c=8,Ri初始值为1,产生8次随机数后就会出现周期性(伪随机数)
C语言中的rand()函数也是通过某种公式得到的伪随机数
a,b,c,Ri称为随机数种子
srand(time(NULL))中的time(NULL)就是用来获取当前时间的参数
以time(NULL)的值为基础,来设定随机数种子的值
由于当前时间是一直变化的,就会得到真正的随机数

//1)随意出拳的猜拳游戏示例
#include<stdio.h>
#include<ctime>
#include<stdlib.h>

void main() {
	//计算机出拳的变量
	int computer;

	//等待用户键盘输入
	printf("石头剪刀.......");
	getchar();
	printf("布!\n");

	//计算机决定出拳
	srand(time(NULL));//随机数种子,按当前时间
	computer = rand() % 3;//0,1,2

	//输出计算机的出拳信息
	if (computer == 0) {
		printf("计算机的出拳是:石头 \n");
	}
	else if (computer == 1) {
		printf("计算机的出拳是:剪刀 \n");
	}
	else {
		printf("计算机的出拳是:布 \n");
	}
}
//2)具有习惯的猜拳游戏程序示例
//比如喜欢出石头剪刀布的概率为:5:3:2
#include<stdio.h>
#include<ctime>
#include<stdlib.h>

void main() {
	//计算机出拳的变量
	int computer;

	//等待用户键盘输入
	printf("石头剪刀.......");
	getchar();//输入一个字符串,按回车结束
	printf("布!\n");

	//计算机决定出拳
	srand(time(NULL));//随机数种子,按当前时间
	computer = rand() % 10;//0,1,2,3,4,5,6,7,8,9

	//输出计算机的出拳信息
	if (computer >0&&computer<=4) {
		printf("计算机的出拳是:石头 \n");
	}
	else if (computer>=5&&computer<=7) {
		printf("计算机的出拳是:剪刀 \n");
	}
	else {
		printf("计算机的出拳是:布 \n");
	}
}
//3)利用经验来决定出拳的游戏程序示例
//发现人类出完石头后喜欢出剪刀
//石头0,剪刀1,布2
//二维数组表示先出了什么之后再出什么的次数
//              出石头的次数   出剪刀的次数    出布的次数
//前一回出石头  player[0][0]   player[0][1]    player[0][2]
//前一回出剪刀  player[1][0]   player[1][1]    player[2][2]
//前一回出布    player[2][0]   player[2][1]    player[2][2]
#include<stdio.h>
#include<ctime>
#include<stdlib.h>

void main() {
	//对手的出拳
	int human;
	//假设对手刚才出了石头
	int prev = 0;
	//记录对手出拳的二维数组
	int memory[3][3] = { {0,0,0},{0,0,0}, {0,0,0} };
	//预测的对手出拳信息
	int max;
	//猜拳的回合数
	int counter = 0;
	//计算机的出拳
	int computer;
	//随机数种子,按当前时间
	srand(time(NULL));

	//重复猜拳
	while (1) {
		//等待用户键盘输入
		printf("石头剪刀(0=石头,1=剪刀,2=布,其他=退出游戏).......");
		scanf_s("%d",&human);
		printf("布!\n");
		//输入0,1,2以外的数值时游戏结束
		if (human < 0 || human>2) break;
		//记录猜拳的回合数
		counter++;
		//计算机决定出拳信息
		if (counter < 10) {
			computer = rand() % 3;
		}
		else {
			//高于10次,根据记忆出拳
			max = 0;
			if (memory[prev][max] < memory[prev][1]) max = 1;
			if (memory[prev][max] < memory[prev][2]) max = 2;
			computer = (max + 2) % 3;//预测中了可赢
		}

		//输出计算机的出拳信息
		if (computer == 0) {
			printf("计算机的出拳是:石头 \n");
		}
		else if (computer == 1) {
			printf("计算机的出拳是:剪刀 \n");
		}
		else {
			printf("计算机的出拳是:布 \n");
		}
		printf("\n");

		//记录对手的出拳信息
		memory[prev][human]++;
		prev = human;
	}
}
//4)根据思考方式来决定出拳的游戏程序示例,人类输掉多次后会改变自己的出拳习惯
//让计算机输掉2次后就改变出拳方式,赢一场输一场不改变
//假设有下面2种出拳方式
//"石头、石头、布、剪刀"
//“剪刀、石头、石头、布”
#include<stdio.h>
#include<ctime>
#include<stdlib.h>

void main() {
	//表示思考方式的二维数组
	int pattern[2][4] = { {0,0,2,1},{1,0,0,2} };
	//连续输的次数
	int lose = 0;
	//切换思考方式的变量,0和1之间切换
	int p = 0;
	//根据思考方式决定出拳信息
	int n = 0;
	//对手的出拳
	int human;
	//计算机的出拳
	int computer;
	//猜拳 
	while (1) {
		printf("石头剪刀(0=石头,1=剪刀,2=布,其他=退出游戏).......");
		scanf_s("%d", &human);
		printf("布!\n");
		//输入0,1,2以外的数值时游戏结束 
		if (human < 0 || human>2) break;
		//计算机决定出拳信息
		computer = pattern[p][n];
		n = (n + 1) % 4;

		//输出计算机的出拳信息
		if (computer == 0) {
			printf("计算机的出拳是:石头 \n");
		}
		else if (computer == 1) {
			printf("计算机的出拳是:剪刀 \n");
		}
		else {
			printf("计算机的出拳是:布 \n");
		}
		printf("\n");
		if ((human == 0 && computer == 1) ||(human == 1 && computer == 2) ||(human == 2 && computer == 0)){
			lose++;
		}
		else {
			lose = 0;
		}
	
		//连续输2次以上变换思考方式
		if (lose >= 2) {
			p = (p + 1) % 2;
			n = 0;
		}
	}
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值