导图社区 计算机原理和汇编语言思维导图
超详细的计算机原理和汇编语言学习笔记思维导图来啦!下图清晰地梳理了加法器、电子管、存储器、控制器、全自动计算、标志寄存器、硬盘读取等重点内容的脉络。一张思维导图帮助快速掌握计算机原理和汇编语言相关知识!
编辑于2018-10-21 13:16:29汇编语言
第一天(10.15号)
废话
浅谈计算机
思考题
有的朋友开始忍不住提问了:高级语言不能直接转换为机器语言吗?为什么要先用编译器,再用汇编器? 这个问题提的非常有水平,从技术上是可以实现的,但不是最优的解决方案,为什么?将来学完编译原理就知道了。
机器语言
不同公司制定的机器语言指令不同
汇编语言
汇编器定义
汇编器相当于一个翻译,把人类写好的汇编代码翻译成机器语言,这样子计算机就听懂了。
高级语言
编译器定义
编译器负责把高级语言翻译成汇编语言。 汇编器再把汇编语言翻译成机器语言。
1-18节 全OK
24之前全OK
异或
图示
记忆:男性和女性能生出孩子,否则就不行。
40连续相加的机器
复习指引
本节不要复习。。。
回忆-多种加法器图示
连续加法器图示
连续加法器原理
就是将寄存器用在加法器当中。。(具体怎么连电路不需要复习)
Tips
总线
在逻辑电路里,大家共用的公共线路称为:总线
传输门
图示
作用:打开它,信号可以从一边传到另一边,关上它,就传不成了
27原码反码补码
复习题
复习题:8bit位的有符号数和无符号数分别可以代表几个数字?
请简述有符号模式和无符号模式
一般不会使用逻辑门来实现减法器,乘法器,除法器,是利用数学规律在加法器的基础上进行拓展, 那减法是怎么样变成加法的
正数和负数的表示方法
有符号模式
第一位不代表数字而代表符号,0表示正数 1表示负数
计算规则
有符号数计算的时候,一律采用补码模式进行相加计算。 (这样子就可以把减法成功转换成加法计算)
例子
5-3=2 5-7=-2的例子
用有符号数表示0
保存规则
有符号数不管是正的还是负数,都按补码形式保存在内存中
特殊数字表示规则
0的表示规则
00000000 表示0
-128表示规则
正码和补码[1000 0000]代表都代表-128
这里老师没讲好,讲稿也不清楚;下周学计算机组成原理再搞定他吧
无符号模式
第一位不代表符号而代表数字
Tips
大部分汇编指令,不区分有符号数和无符号数。
原码、反码、补码
定义(很棒的图)
Tips
有符号数中,如果一个数大于等于0,那么它的原码、补码、反码全都一样,没有区别。 有符号数中,如果一个数小于0,那么就得进行转换成补码形式。
28有符号数计算原理推导
本节不用复习
Tips
本节证明这个
推导核心逻辑:124-77=124-77+100 -100=124+ (99-77)+1-100
推导过程PPT
29计算机存储单位
字节和位
1个字节[byte]代表8个[bit]
2个字节自然就是16[bit]位,英文用word来表示,中文用[字]来表示
4个字节是32[bit]位,英文用double word来表示,中文用[双字]来表示
两套单位转化制度
1024制:微软的实际单位应该是KiB、MiB、GiB、TiB、PiB(但是常常改为KB、MB、GB、TB、PB).
1000制:我们的内存和硬盘设计的时候,采用1000进制的编码规则,缩写KB、MB、GB、TB、PB
带宽的单位
宽带网络里面说的兆,Mb(全称为Mbps)这是电信部门衡量网络带宽的单位,意思是兆比特位每秒
bps是bit Per Second的缩写,翻译成中文就是比特位每秒,也就是表示一秒钟传输多少位(bit)的意思。
30反馈和振荡器
振荡器和反馈图示
首尾相连的非门,这样就形成了一个反馈
细枝末节
反馈和振荡器的关系
制造振荡器的其中一个方法就是在电路中加入一个反馈
以前,所有的电路都靠手工地断开或闭合开关来改变状态,而振荡器却不需要人的干涉,它可以自主地工作。
振荡器产生的方波总是被称为“脉冲
脉冲图示
31电子管
电子二极管
没啥用的
电子三极管
历史
人们称赞福雷斯特,说他:“推动了无线电技术的迅猛发展,引发了一场革命并奠定了近代电子工业的基础”。 福雷斯特一直活到1961年,一生中共拥有300多项发明专利。被人们尊称为“无线电之父“。
优点
它的振荡频率足够高,就能向很远的地方发射无线电波,而且它的优势是可以获得极高的振荡频率
计算机一开始是机械齿轮的,后来是继电器的,再后来是电子管和晶体管,现在是光线和量子的
电子管是新材料,继电器能做的事情,它也能做。
缺点:电子管体积太大,数量一多就比较占地方。 还有,要让它老老实实地干活,必须依靠灯丝把阴极烧热。这灯丝跟灯泡一样,吃的是电
032.会记忆的RS触发器
原始版RS触发器
原始版RS触发器结构图示
原始版RS触发器真值表
复习指引
只要知道改装版的RS触发器的输入和输出关系即可
复习题
RS触发器的记忆功能体现在什么地方?
爹不打,妈不打的时候,以前和谁亲近现在就和谁亲近
就是说:输入撤销之后,输出依然能够维持
改装版RS触发器
改装本质:电路图的边没移动,仅仅移动端点(改装后和改装前的电路图图属于图论中的同构图)
Tips
改装后RS触发器真值表和改装前真值表没变
以后都是用改装后的RS触发器这张图,而不是改装前的
RS触发器使用规则
R和S必须一个开一个关
仅仅上Q作为触发器的输出
RS触发器的意义
RS触发器是构成其它各种功能触发器的基本组成部分。 触发器是构造电子计算机的重要组成元器件。
RS触发器没有实际作用 他的演变才有作用
改装版RS触发器图示
输入和输出关系
要使上Q=0,S必须为0,R必须为1. 要使上Q=1,S必须为1,R必须为0.
加法器
25节-全加器
全加器定义
两个一bit位相加的机器
全加器真值表
符号说明
3个全加器组成一个加法器(用于3位二进制加法运算)
横轴和纵轴的方框分别输入 0和1即可在绿色方框输出结果
加法器内部结构
从真值表到电路图的流程原理
第一步:得到真值表
第二步:得到逻辑表达式
简单版阐述
繁琐版阐述
第三步:根据逻辑表达式画电路图
这一步过程很繁琐也很无脑。。你不需要真正的搞清楚如何把逻辑表达式变成电路图
第四步:简化布尔代数+简化电路
具体的如何简化过程你不需要关心
从真值表到电路图(全加器例子)
第一步:得到真值表
第二步:得到逻辑表达式
第三步:根据逻辑表达式画电路图
注意:这个电路图仅仅表示一个全加器,即只能实现第一步真值表的运算
第四步:简化布尔代数+简化电路
具体的如何简化过程你不需要关心
全加器的串接最终形成加法器
敬礼!
乘法 减法 除法器实现原理
加法:全加器的串接。 减法:利用数学规律变成加法。 乘法:利用数学规律变成加法。 除法:利用数学规律变成乘法,再把乘法变成加法。
任务:请使用图灵机和有限状态机实现加法器(你分别画个图灵机和FSM的状态图即可)
34上升沿D触发器
上升沿D触发器图示
电路图
制造一个上升沿D触发器,其实很简单,它的秘密在于,将两个D触发器首尾相连,并加一个非门
抽象图
图中的三角形的意思是这里有非门
上升沿D触发器的应用
存储器的一比特单元就是用上升沿D触发器制作的
工作原理
只有在CP端从0~1的瞬间(上升沿)才会把D端的值保存进来
复习指引
和33节很像,做复习题即可
复习题
请画出上升沿D触发器的图
请说明上升沿D触发器何时才能存数据?你画个图给我看看
33节讲的不就是下降沿触发器吗?
不是的;CP=1时,一直触发存储效果(联想流水灯为什么不能使用D触发器)
35流水灯
复习题
那为什么制作这样一个流水灯非得使用上升沿D触发器呢?
振荡器所产生的是脉冲信号,是一连串交替变化的0和1,如果使用普通的D触发器,只要CP=1,流水灯就会被连续触发,灯泡全亮,就产生不了“流水”的感觉了
流水灯是用什么触发器实现的?
请你画出流水灯的电路图
请你回忆一下流水灯 嘿咻嘿咻 是什么意思?
请问流水灯的学术专业别名叫什么?为什么取这个别名?他在哪里有应用?
循环移位寄存器
在控制器中有循环移位寄存器的组件
命名原因:实现了一个比特位依次在多个上升沿D触发器中传递的效果
复习指引
看这里
看这里
玩一下模拟软件
流水灯图示
手动流水灯
手动实现开关
自动流水灯
振荡器实现开关
流水灯工作原理
啰嗦版阐述
简洁版阐述
利用D上沿触发器的瞬间储存性质
多个D上沿触发器串联
开关每开一次(CP从0-1),D的值向右传递一次(因此亮灯泡也向右传递一次)
36T触发器
复习题
t触发器的t指的是什么?想象一下为什么这么命名?
请画出t触发器的图(包括开关和灯泡)
t触发器的date接口的数据来源是谁?
下Q
t触发器的应用?
复习指引
看复习题就好
图示
只是简单地改装了一下,用一个普通的上升沿D触发器,在它的D和下Q之间连了一根电线
t触发器的D的值不是人为输入或者通过别的方式输入的,而是通过下Q来输入
t触发器的作用
t触发器就像一根管道,D上的比特被保存后,需要经历一个小小的延迟,才能使上Q和下Q发生变化
37晶体管
和电子二极管一样,晶体二极管只具有单向导电性,不具备放大作用
和电子管一样,晶体管也是制作逻辑门,以及各种触发器的好材料
这个新的半导体材料像电子三极管一样,具有放大作用。相应的,它被称为晶体三极管
图示
38计数器
复习题
计数器已经计数到最大,如果再来一个脉冲信号,会怎么样呢?
计数器的内部结构是怎么样的?请设计(画图)一个最大计数15的计数器
计数器用到哪种类型的触发器?
如何增大计数器的计数量?
如果想让计数器能统一更多的脉冲,唯一的办法就是增加这种T触发器的数量
请开启学习软件玩一下计数器
复习指引
复习
看这种图即可,回忆计数器的细节原理
计数器图示
4个t触发器组成的计数器(最大计数15)图示
药厂计数药房的例子
计数器原理
首先计数器必须要带有储存功能,这个储存功能就依靠t触发器的储存功能来实现
利用t触发器的“延时”存储特性 +二进制的加法进位机制 设计出了 “相加”的特性,来一个加一个!
39寄存器
寄存器图示
电路图
多个上升沿触发器的CP端串联(而流水灯是除了下Q所有端口都串联)
抽象图
注意那个三角形,这表明该寄存器只有在CP脉冲的上升沿才会工作
复习题
请画出寄存器的抽象图
请说出寄存器的本质
请说出寄存器和流水灯的电路图区别
寄存器原理
寄存器的本质就是多个上升沿触发器拼起来而已。。上升沿触发器的原理就是寄存器的原理
上升沿触发器的原理就是在CP上升(0~1)的瞬间存储数据
33 D触发器
复习指引
只要知道D触发器的输入和输出关系即可
复习题
请画出来D触发器
官方复习题
答案
0
D触发器图示
电路图
抽象图
D触发器工作原理
繁琐表述
记忆CP就是管理员,D(data)是数据
文件写入
CP=1,D=1或0
管理员打开仓库,D可以向内存入数据
保存成功(此时D无法修改文件)
CP=0
管理员关闭仓库,D存入的数据已经被管理员保存好了,并且仓库已关闭,D的变化不会引起仓库内对应文件的值了。
只有打开仓库,才能修改文件
若想再次改变文件的值,你只能请求管理员CP再次打开大门吧!
通俗表述
在D触发器中,控制端CP就相当于你进入公司的门卡,去某个旅游景点的门票。 这些东西,都是存在一个有效期,一旦失效,你也就意味着失去了那些权利。 同样,在D触发器中,当CP=1时,在它的持续期内,D触发器无论如何变化,都会进入触发器,存储到上Q中。 而一旦CP变成0的时候,就意味着过了有效期,触发器将不能保存新的比特。
基本知识
字 位 双字 字节
1字节=8个二进制位(简称位) 1字=2字节=16位 1双字=2字=4字节=32位
第4-29天(10.17)
021.第一个汇编程序
复习指引
本节是基本操作,不太需要复习。
复习题
times 510-($-$$) db 0x00 (重复501次 db 0x00),如果db也占字节长度那么岂不是超过512个字节了?
db是伪指令,不占字节长度
a.img相当于硬盘
用txt打开a.img,能看到类似右图
主引导扇区最后两个字节必须是 0x55和0xAA
实战
实战1:写第一个汇编程序
写有4条命令的汇编程序,并利用times+db命令将程序填充至512字节
times+db自动填充
times 510-($-$$) db 0x00 ; 510-($-$$) ($-$$) 代表的就是上面的9个字节 db 0x55,0xAA;这是MBR约定必须要有的结束标志 ;510+2=512
$是当前行的汇编地址,$$是本程序最后一个字符的汇编地址的汇编地址
将以上程序编译成机器指令,然后放到a.img(硬盘)
利用老师封装好的write.exe来完成此步骤
偷懒操作
配置editplus的自定义工具功能
直接在editplus进行编译汇编程序文件,然后写入到a.img
CRTL+1
CRTL+2
然后打开虚拟机
开启虚拟机,执行机器指令
实战2:配置editplus的调试工具
如图
目前我的电脑上用不了这个工具- -
问题
调试无法弹出write
自己也无法打开write
现实无法执行此应用
033.loop
复习题
相对跳转和绝对跳转的定义?
cx寄存器的作用?
n指令和s指令的区别?
复习指引
看这里 3
n指令和s指令
s单步步入指令
当碰到一些循环指令,s会把循环过程演示出来
n单步步过指令
当碰到一些循环指令,n会自动把这个循环过程完成
cpu执行loop指令的过程:
1.dec cx 2.判断cx中的值是否为零,如果cx寄存器里的值不为0,则转到标号处执行程序; 3.如果cx中的值为0则向下执行其他的指令。 cx中存放的就是loop循环的次数。
loop指令语法
mov cx,3 mark: inc ax loop mark
cx寄存器
cx中存放的就是loop循环的次数。
相对跳转和绝对跳转
绝对跳转
修改了段寄存器和IP寄存器的值
相对跳转
只修改了IP寄存器的值
相对跳转最大的范围是0x0000-x0FFFF
loop就属于相对跳转
举例
绝对: end: jmp 0x07C0:end
相对
023.屏幕显示输出
复习题
优先复习
文本模式起始地址的左上角显示一个H偏移地址是?右下角显示一个H的偏移地址是?
左上角
显卡在文本模式下工作的时候,起始的物理地址是0xB8000。 段地址是0xB800,偏移地址是0x0000。(当然,段地址可以改,只要是在显卡领域内的段地址都行)
右下角
80 x 25的文本模式。 在这种模式下,屏幕上可以显示25行字符,每行80个字符,屏幕上总共2000个字符
因此右下角是第2000个字符,ASCI码每个字符1个字节,因此偏移地址就是2000个字节
疑问:我觉得1个字符对应2个字节(因为要包括显示信息),因此2000个字符是4000个字节。 因此偏移地址=4000个字节*8=32000D=0X7D00
第2行第1列
P145给的答案是0xa0 我感觉不对啊
文本模式和图像模式的区别?
什么是显存映射?
汇编语言,在屏幕上,打印“I Miss You”
显卡如何控制像素?
答案是显卡内部都有自己的存储器,也称显示存储器(Video RAM:VRAM),简称显存,要显示的内容都预先写入显存。
复习指引
知道文本模式和图像模式的区别
知道显存映射
显卡科普
显卡的主要作用是将CPU提供的指令和数据进行相应的处理变成显示器能够接受的文字或图象后显示出来,以便为用户继续运行或终止程序提供依据。 显卡(Video card,Graphics card)全称显示接口卡,是计算机最基本配置、最重要的配件之一。一般分为集成显卡、独立显卡、核芯显卡三种。 显卡作为电脑主机里的一个重要组成部分,是电脑进行数模信号转换的设备,承担输出显示图形的任务。 集成显卡:集成显卡是将显示芯片、显存及其相关电路都集成在主板上,与其融为一体;集成显卡的显示芯片有单独的,但大部分都集成在主板的北桥芯片中。 独立显卡:独立显卡是指将显示芯片、显存及其相关电路单独做在一块电路板上,自成一体而作为一块独立的板卡存在,它需占用主板的扩展插槽(ISA、PCI、AGP或PCI-E)。 核芯显卡:芯显卡是Intel产品新一代图形处理核心,和以往的显卡设计不同,Intel凭借其在处理器制程上的先进工艺以及新的架构设计,将图形核心与处理核心整合在同一块基板上,构成一颗完整的处理器。
文本模式和图像模式
文字模式
文本模式功能
:显存的值直接转化为屏幕上的文字(如01000001转化为A)
通俗表达
:文本模式和图像模式的关系就像汇编语言和机器语言的关系一样。文本模式对于程序员来说,操作更加简单快捷(字节输入ASCI码就能打印到屏幕,你说简不简单)
图示
文本模式字符格式
我们用2字节(16位)的存储单元去表示一个字符,第一个字节是ASCII编码,第二个字节是颜色信息
Tips:本图详细说明见书P50-p51
图像模式
原理:显存的值转化为屏幕上的像素
黑白图像模式-图示
彩色图像模式-图示
显存
显存的作用
就是显卡的内存,用于控制像素
显存在内存中的分布图
显存映射内存
为什么要把显存映射到内存?
显存是位于显卡上的,我们要让CPU和显卡打交道,自然要比和内存打交道多一道手续。 自然速度和效率要慢了很多。 就如同你打电话告诉你朋友,你朋友再打电话告诉你父母一样,肯定没有你亲自往家里打电话来的直接。 特别是后来的电脑为了实现游戏动画效果和播放高清电影,必须能够让CPU直接读写显存。
如何映射?
内存有一块地址0xB800~0xBBFFF和显存之间有映射关系(我猜应该是单射,而不是满射)
映射到ES段寄存器上(地址在 0xB800~0xBBFFF之间)
代码
mov ax,0xb800 mov es,ax
我猜 这个0xb800改成 0xB800~0xBBFFF之间的任意地址都行
课题代码
建立映射关系 mov ax,0xb800 mov es,ax 在文字模式打印字符 mov byte [es:0x0000],0x48 mov byte [es:0x0001],0x07 mov byte [es:0x0002],0x65 mov byte [es:0x0003],0x07 times 510-($-$$) db 0x00 db 0x55,0xAA
MOV指令
复习题
什么情况下操作数不需要大小修饰符(hj)
两种不同的地址书写方式是什么?
复习指引
看这个
类比int double
操作数包含寄存器,不需要修饰符
操作数不包含寄存器,不需要修饰符
Byte- 1字节
word-2字节
例
双杀
向内存地址写入2字节的数据
mov word[ds:0001],0x1122 mov dx,word[ds:0001]
图
四杀
向内存地址写入4字节的数据
mov dword[ds:0001],0x11223344 mov edx,dword[ds:0001]
两种地址书写方式
指定前缀:mov byte [es:0x0003],0x07
无前缀-默认DS寄存器:mov byte [0x0003],0x07
MOV陷阱
内存单元之间不得直接操作
段寄存器和内存单元不得直接操作
不能将立即数直接存入段寄存器
数据宽度不同错误
mov ax,bl
不能直接指定一个20位的内存地址
直接指定一个20位的内存地址,是错误的方式。 mov al,[0x07C00] 这就是错误的写法。
图
024.输出I Miss You
复习指引
本节就是23节的代码实战
我的电脑搞不出来啊。。。!
代码
;以下代码的功能为在屏幕上输出:I Miss You ; mov ax,0xB800 mov es,ax ;I Miss You ;I=0x49 空格=0x20 M=0x4D i=0x69 s=0x73 Y=0x59 o=0x6F u= 0x75< /FONT> mov byte [es:0x0000],'I' mov byte [es:0x0001],0x07 mov byte [es:0x0002],' ' mov byte [es:0x0003],0x07 mov byte [es:0x0004],'M' mov byte [es:0x0005],0x07 mov byte [es:0x0006],'i' mov byte [es:0x0007],0x07 mov byte [es:0x0008],'s' mov byte [es:0x0009],0x07 mov byte [es:0x000A],'s' mov byte [es:0x000B],0x07 mov byte [es:0x000C],' ' mov byte [es:0x000D],0x07 mov byte [es:0x000E],'Y' mov byte [es:0x000F],0x07 mov byte [es:0x0010],'o' mov byte [es:0x0011],0x07 mov byte [es:0x0012],'u' mov byte [es:0x0013],0x07 times 510-($-$$) db 0x00 db 0x55,0xAA
025.标号
复习题
利用标号写代码:代码功能用 jmp 跳1行。。
复习指引
本节介绍了一个基本概念:标号
看这里 2
标号的功能
标号的作用是让"汇编器"快速替我们计算出一些长度信息。
标号的应用场景
当我们在汇编语言要进行跳转,或者定位一些指令或者数据信息的时候,会非常方便。
标号语法原理
代码实战
标号的功能:目的从 add ax,0x0002跳到add ax,0x0004 mov ax,0x0000 add ax,0x0001 add ax,0x0002 jmp 0x07C0:mark add ax,0x0003 mark: add ax,0x0004 times 510-($-$$) db 0x00 db 0x55,0xAA
022.times和db
复习指引
不太需要复习,本节很基础
times
times 3 mov ax,0x1111 重复3次
$-$$
代码如图
mov ax,0x1111 mov ax,0x2222 mov ax,$-$$ ; $-$$ = mov ax,0x2222的内存位置减去mov ax,0x1111=6
Tips
在汇编语言程序中,'1' 表示输入和1对应的ASCI码
这三种方式等价
db '123'(注意,这是单引号)
db '1',2','3'
db 0x31,0x32,0x33
028.优化输出
复习题
请用汇编语言实现如下优化
优化前(24节) fmt.print('I Miss You') 优化后 str := 'I Miss You' fmt.print(str) str := '123+456= ' fmt.print(str)
代码核心:利用db+标号+jmp,完美结合啊! db负责卡位 标号负责统计数字 jmp负责躲避
请用汇编语言实现死循环
死循环 … … for{} …
复习指引
本节就是在干这个事情
复习这个
db=Declare Byte
db的中文翻译就是声明字节
很像高级语言里的变量初始化如 a := “hello"
db的效果
db的意思是把后面的内容转换成对应的字节。 。。然后按照顺序 像指令一样存入内存。。
举例
mov ax,0xB800 3字节 mov es,ax //末尾是07C04 db 'I Miss You' //I就是07CO5 M是07C07。。以此类推
体会这个例子 I M I S S等字母在内存的位置,你就懂了db的作用了
代码
代码核心:利用db+标号+jmp,完美结合啊! db负责卡位 标号负责统计数字 jmp负责躲避
代码核心:这个string标号真像声明一个字符串数组变量啊。。后面的string+0 string+1也非常像。。
代码内容
mov ax,0xB800 mov es,ax mov ax,0x07C0 mov ds,ax jmp 0x07C0:code //这里必须跳跃,为了防止CPU去执行 db '123+456= ' 这个没有意义的命令 ;'I Miss You' string: db '123+456= ' code: mov al,[ds:string+0] mov byte [es:0x0000],al mov byte [es:0x0001],0x07 mov al,[ds:string+1] mov byte [es:0x0002],al mov byte [es:0x0003],0x07 mov al,[ds:string+2] mov byte [es:0x0004],al mov byte [es:0x0005],0x07 mov al,[ds:string+3] mov byte [es:0x0006],al mov byte [es:0x0007],0x07 mov al,[ds:string+4] mov byte [es:0x0008],al mov byte [es:0x0009],0x07 mov al,[ds:string+5] mov byte [es:0x000A],al mov byte [es:0x000B],0x07 mov al,[ds:string+6] mov byte [es:0x000C],al mov byte [es:0x000D],0x07 mov al,[ds:string+7] mov byte [es:0x000E],al mov byte [es:0x000F],0x07 mov al,[ds:string+8] mov byte [es:0x0010],al mov byte [es:0x0011],0x07 mov al,[ds:string+9] mov byte [es:0x0012],al mov byte [es:0x0013],0x07 end: jmp 0x07C0:end times 510-($-$$) db 0x00 db 0x55,0xAA
代码鬼图解析
030.div指令
复习题
假设往ax里面存放一个三位的十进制数(100~999之间的一个数字),如:123D。 再把ax的值输出到屏幕上怎么办呢?
优化前: '123' var b int b = func_only_123(strconv.Atoi(a)) fmt.print(b) 优化后(我们要做的就是要取消func_only_123的限制) a := '123' strconv.Atoi(a) fmt.print(a)
复习指引
本节就只要复习div语法即可,不需要复习本节代码
看这里
高一半规律
被除数的高一半,必须小于除数。 如果数据不满足这样的条件,被除数的高一半大于或者等于除数,就会产生除法溢出,继而引发程序“崩溃”
本节代码
实现这个函数功能:通过3次使用div命令来获取一个三位数的三个余数,利用的数学原理就是求余法(29节有介绍)
代码
mov ax,0xB800 mov es,ax mov ax,0x07C0 mov ds,ax jmp 0x07C0:code ; 百位,十位,个位 temp: db 0x00,0x00,0x00 code: mov ax,871 ;准备好被除数 mov cl,10D ;准备好除数 ;=================================== divcl ; al=12,ah=3 ;ax = ah+al ax=0x030C mov byte[ds:temp+2],ah mov ah,0x00 div cl mov byte[ds:temp+1],ah mov ah,0x00 div cl mov byte[ds:temp+0],ah ;=================================== mov al,byte [ds:temp+0] add al,48 mov byte[es:0],al mov byte[es:1],7 mov al,byte [ds:temp+1] add al,48 mov byte[es:2],al mov byte[es:3],7 mov al,byte [ds:temp+2] add al,48 mov byte[es:4],al mov byte[es:5],7 ;=================================== end: jmp 0x07C0:end times 510-($-$$) db 0x00 db 0x55,0xAA
情况一:16位 除以 8位(无符号除法)
实例
代码效果 123/10商=12,余数=3 运算代码 mov ax,123D mov cl,10 div cl 结果 ax = ah + al ah =3=0x03 al =12=0x0C ax = 0x030C
语法要求
被除数在AX中,商在AL中,余数在AH中。 (除数的位置随意,除数存放到一个8位的寄存器或者内存地址)
格式也可以和idiv一样
32位除以16位 div 16位寄存器 div 16位内存 被除数在DX:AX中,商在AX中,余数在DX中。
情况2:32位除以16位(还没学) idiv
语法要求
第二种用法: 32位除以16位 div 16位寄存器 div 16位内存 被除数在DX:AX中,商在AX中,余数在DX中。
例子
如果被除数是:65535(0x0000FFFF)(DX:AX),除数是10(0x000A)(BX),商就是(6553)(0x1999)AX,余数就是5(DX)里面
Tips
这是(Unsigned Divide),要求除数和被除数都是无符号数
031.and、or、not、xor
复习题
无
复习指引
不用复习。。
四条命令
and
mov ax,0xFFFF ax=1111 1111 1111 1111 mov bx,0xF0F0 bx=1111 0000 1111 0000 and ax,bx 1111 1111 1111 1111 1111 0000 1111 0000 and ___________________________________ 1111 0000 1111 0000 所以ax的值就变成了0xF0F0
or
mov ax,0xFF00 ax=1111 1111 0000 0000 mov bx,0x00FF bx=0000 0000 1111 1111 or ax,bx 1111 1111 0000 0000 0000 0000 1111 1111 or ___________________________________ 1111 1111 1111 1111 所以ax的值就变成了0xFFFF
not
mov ax,0x1234 ax=0001 0010 0011 0100 not ax 0001 0010 0011 0100 not _______________________________________ 1110 1101 1100 1011 ax=0xEDCB
xor
mov ax,0x1234 ax=0001 0010 0011 0100 xor ax,ax 0001 0010 0011 0100 0001 0010 0011 0100 xor ______________________________ 0000 0000 0000 0000 ax= 0x0000
032.inc、dec、sub
复习指引
不用复习,很基础很简单
dec 和inc
语法
inc 操作数 dec 操作数
功能
dec ax = sub ax,1 inc ax= add ax,1
inc= increase
dec = decrease
sub
sub和add相反。
常识
026.抽象与封装
027.代码规范
029.进制转换
复习指引
不用复习
N进制转化为10进制
求余法:只要不停地除以对应的进制基数,直到商为0,然后将每一步得到的余数倒着串起来即可。
例
把26D转换成十六进制,使用求余法如下: 26 / 16 = 1 余 A 1 / 16 = 0 余 1 26D=1AH
第5天(10.18)
034.大小端模式
复习题
什么是大端模式,小端模式?
复习指引
看这里1,知道大小端模式的定义即可
本节很简单很基础不容易忘
大小端模式
我们目前学习的课程接触的都是小端模式存储
定义
小端模式:数据低位在内存低位,数据高位在内存高位
大端模式:反过来
图示
小
大
058.基址变址寻址(笔记在别处)
036.有符号数和无符号数
复习题
无
复习指引
知道FD能表示-3和253并且理论完全自洽(不会引发任何意义上的矛盾)
本节是常识
几乎所有的指令,既能操作无符号数,又能操作有符号数
FD即代表-3也代表253
有符号:-3
无符号:253
举例
写代码测试一下: mov al,-3 inc al //结果为:-2 mov al,253 inc al //结果为:254
037.数据的存放长度
复习题
无
复习指引
看这里1
规律:同一有符号数负数的8-16-32位的表示区别
繁琐表达
假设一个有符号数,如果是8位。 想把这个8位的有符号数变成16位的有符号数,或者说,把一个8位寄存器里面的有符号数,如果放到16位寄存器里面。 只要把16位的高8位,全部用符号位填充就行了。 (32位同理)
通俗表达:高位部分填充F
举例(不复习)
那如果是十进制数字(-3D)(有符号负数)的话,怎么样在8位的寄存器里面存放呢? 如果把-3放到一个8位的寄存器。 +3的8位原码是0000 0011 -3的8位原码是1000 0011 -3的8位反码是1111 1100 -3的8位补码是1111 1101 = 0xFD 我们知道,一个有符号数(不论正负),在计算机里面都是以补码的形式存放。 但是有符号正数的(原码反码补码)全都是一致的,而有符号负数的原码反码补码是不一样的。 如果把-3放到一个16位的寄存器。 +3的16位原码是0000 0000 0000 0011 -3的16位原码是1000 0000 0000 0011 -3的16位反码是1111 1111 1111 1100 -3的16位补码是1111 1111 1111 1101 = 0xFFFD 如果把(-3)放到一个32位的寄存器。 +3的32位原码是0000 0000 0000 0000 0000 0000 0000 0011 -3的16位原码是1000 0000 0000 0000 0000 0000 0000 0011 -3的16位反码是1111 1111 1111 1111 1111 1111 1111 1100 -3的16位补码是1111 1111 1111 1111 1111 1111 1111 1101=0xFFFF FFFD
规律:同一无符号数和有符号正数的8-16-32位的表示区别
通俗表达:高位部分填充0
举例(不复习)
数字是15D的三种存放效果 如果把15D转换成1个字节(有符号数格式)存放,并且用二进制来表示的话那就是:0000 1111 mov al,15 al=0000 1111=0x0F 如果把15D转换成2个字节存放,并且用二进制来表示的话那就是:0000 0000 0000 1111 mov ax,15 ax=0000 0000 0000 1111 =0x000F 如果把15D转换成4个字节存放,并且用二进制来表示的话那就是:0000 0000 0000 0000 0000 0000 0000 1111 mov eax,15 eax=0000 0000 0000 0000 0000 0000 0000 1111=0x0000 000F
038.拓展数据长度相关指令
复习题
超大数据存不下怎么办?
在16位汇编语言中,如果AX存放一个数,存放不下的时候,往往会借助于DX寄存器合成一个32位寄存器,来表示更大的数。 而在32位汇编语言中,如果EAX存放不下一个数,往往会借助于EDX寄存器,合成一个64位的寄存器,来表示更大的数。
复习指引
不用复习,当做检索资料
四条拓展长度命令
cbw (convert byte to word) 这条指令,会自动把al里面的有符号数,拓展到ax中。 cwd (convert word to doubleword)这条指令,会把ax里面的有符号数,拓展到DX:AX中。 cwde(convert word to extended double)这条指令,会把ax里面的有符号数,拓展到:EAX中。 cdq (convert doubleword to quadword)把EAX拓展到64位数:EDX:EAX中。
只能用于有符号数拓展 ? 但是老师的视频里演示了3使用上面4条命令啊!第8分左右
039.neg
复习题
无
复习指引
neg语法
neg 寄存器 neg byte [内存] neg word [内存] neg dword[内存]
neg相当于 给一个数字加一个负号
neg的目的操作数即可以是无符号数也可以是有符号数
040.多种方式观察内存(瞄一眼)
复习题
无
复习指引
不用复习。。常识
同样一段内存数据,我们可以有很多种方式去解读理解。各个不同的内存表示方法是完全等价的
图示-多种方式观察内存
041.div指令的第二种用法
笔记在前面的div指令处
042.用loop指令优化代码
复习题
无
复习指引
本节代码不用复习,主要就是用了FOR循环打印任意长度字符串的功能;代码很简单
本节代码
本节代码核心功能
优化前(24节) fmt.print('I Miss You') 优化后(优化输出,28节) str := 'I Miss You' fmt.print(str) str := '123+456= ' fmt.print(str) 本节优化(42节) 在28节的基础上引入for循环 for I,_ range str{ fmt.print(str[i]) } 28节只能固定打印10个字符而且是没有使用循环纯手动打印10次
本节代码
mov ax,0xB800 mov es,ax mov ax,0x07C0 mov ds,ax mov cx,code-string mov si,0 mov di,0 jmp 0x07C0:code string: db '123' code: mov al,[ds:string+si] mov byte [es:di],al inc di mov byte [es:di],0x07 inc si inc di loop code end: jmp 0x07C0:end times 510-($-$$) db 0x00 db 0x55,0xAA
鬼图代码解析
043.zf(看书,这里没笔记)
本部分看书为主,笔记没有记在这里
044.JB和JNB(化腐朽为神奇)(看书,这里没笔记)
045.JE和JNE
035.标志寄存器
复习题
标志寄存器FL和通用寄存器有什么区别?
功能不同,地理位置不同。前者在CPU,后者在内存中
标志寄存器的功能?联系小偷的比喻
复习指引
看这里 2
本节很简单 全是概念介绍
标志寄存器
标志寄存器图示(大小16位)
标志寄存器的功能
标志寄存器在计算机的作用,主要反映处理器的状态和ALU运算结果的某些特征。
小偷类比
一般快过年的时候,小偷都喜欢偷东西,因为你要过年,小偷也要过年筹钱。 还有一些没赚到钱,没领到工资的,为了着急回家,也会向熟人作案,所以每到过年,这类型案件都会增多。 专业一点的小偷至少都是两个人,偷东西之前也会踩点。 A小偷出去踩点,如果发现这户人家几天没人,就会在门旁边某个隐匿的地方,画个0,如果有的人话,就画个1。 B小偷晚上出来上班工作了,到A小偷白天踩点的地方去,看到0知道没人可以下手,看到1就知道有人。 如果他们也学过标志寄存器的话,或许他们会给自己设计一套行业交流编码协议。 其实我们的身份证,银行号里面的每一位数字,都有一些特殊的意义和代表。
Tips:各寄存器名称汇总
标志寄存器:EFL和FL
在16位的汇编语言中,这个寄存器叫做flag。 在32位的汇编语言中,这个寄存器叫做eflag。
回忆一下,EAX AX AH AL,因此我们知道E这个字母前缀的代表32位
记忆:FL是flag的前两字母
通用寄存器名称汇总
名称汇总
ES寄存器 Extra Segment
Segment n. 段;部分
DS段寄存器,(data segment)翻译过来就是数据段寄存器。 AX寄存器。(accumulator) 累加 CX寄存器 (count),翻译过来是计数的意思
CS寄存器,又叫做Code Segment,代码段寄存器。 IP(Instruction Pointer):指令指针寄存器
这些家伙都在内存中
图示
047.movsb(剩余代码)
048.movsw(剩余代码)
049.PF
050.SF
051.OF
052.有条件跳转指令大家族
053.栈
“三个”专门负责管理“栈”的寄存器
1.SS= Stack Segment 栈段寄存器 2.SP=StackPointer 栈顶指针寄存器 3.BP=BasePointer 栈底指针寄存器
复习指引
看这里 1
栈的功能
代表“数据临时存放的地方”
栈的本质
本质就是一块普普通通的内存,没有任何新颖的地方,只不过我们给这个内存实现封装了一些小函数:pop push 还给他ss sp bp的待遇
图示
注意图中的球既可以是dx也可以是axbxcx
注意图中的ss:sp和ss:bp
Tips
因为我们学习的16位汇编。 所以push和pop指令只能处理16位的操作数。 push 16位寄存器 push 16位内存 push 16位立即数 pop也是同上。
压榨操作不会删除数据的原文件
假设ds=0x1000 push ds mov ax ds 那么ax=0x1000 结论:push ds不会删除ds原来的值
054.三数求和并输出(不用复习)
055.从1加到100(不用复习)
056.寻址方式(寄存器寻址和立即寻址)(笔记在别处)
057.内存寻址(直接寻址-基址寻址-变址寻址)(笔记在别处)
046.两数求和并输出(剩余代码)
第6天(10.20)
059.准备告别主引导扇区
复习题
无
复习指引:我们告别MBR,去看看别的扇区
接力赛例子
加载器
功能:让BIOS跳到MBR再跳到别的扇区
例子
如果我们想要离开主引导扇区,就必须得把主引导扇区的指令设计成一个“加载器”。 举个例子,未来写的程序,我们存储到了第8个扇区。 那么BIOS自检完成之后,加载主引导扇区的代码,而主引导扇区的代码加载第8个扇区的代码
娶媳妇例子
把主引导扇区改造成一个加载器,并不是一件容易的事情,这需要很多知识点的铺垫才能开始设计加载器。 这个过程,有点像娶媳妇一样。 CPU醒来以后,初始化好自己,开始找到BIOS的位置,把BIOS娶回家。 BIOS娶回家后,BIOS又找到主引导扇区,把主引导扇区的512个字节搬运到内存地址0x07C00,BIOS开始娶0x07C00的代码。 0x07C00的代码执行完之后,开始娶其他扇区的代码。 0x07C00要想娶其他扇区的代码, 需要知道很多东西。
101.体验接口的妙处
本节讲稿看完了
061.jmp指令的各种写法(书本笔记未记录)
复习题
复习指引
近转移
直接
8位相对短转移
jmp short 取值范围 8位的有符号数 jmp short 立即数/标号
16位相对近转移
间接
16位间接绝对近转移
远转移
直接
16位直接绝对远转移
例
jmp 0x0000:0x7C00
间接
16位间接绝对远转移
例:
jmp far [内存地址] jmp far [ds:标号] jmp far [ds:立即数] jmp far [ds:bx] jmp far [ds:bx+si]
共性分析
近转移共性:段内转移,只修改IP寄存器
远转移共性:段间转移,即CS和IP寄存器
直接转移共性:通过立即数寻址
间接转移共性:通过内存寻址
相对转移共性:操作数是汇编地址
绝对转移共性:操作数(或寻址的结果)是绝对地址
16位转移共性:操作数是16位有符号数
转移空间:-32768d ~ +32767d
Tips:16位远转移指的是偏移地址限定在16位
8位转移共性:操作数是8位有符号数
转移空间:-128d ~ + 127d
(仅相对短转移是这种情况)
说明
相对代表操作数是汇编地址
绝对代表操作数是绝对地址(可以直接修改IP寄存器和CS寄存器的值)
062.子程序调用
复习题
复习指引
保护现场原则
(仅代码没看)
子程序别名:函数,调用子程序别名:调用函数
063.call指令和ret指令(讲稿看完了,就差做笔记了)
复习题
复习指引
079.简谈软件BUG(仅一部分没看,笔记全OK)
复习指引
不用复习
仅这段文字没看
解决完这个问题,我们再来思考一个问题: 我们使用的是LBA28模式定位硬盘扇区: LBA28模式寻址扇区的范围是:0x000 0000 ~0xFFF FFFF 如果被加载程序,不是位于第1个扇区,而是位于第70000个扇区。 而我们代码中,定位某个起始扇区的时候,都要进行压栈且只压入了一个可变参数。 这个参数是16位的,而16位最大只能保存0xFFFF个扇区,也就是65535,一旦起始扇区超过65535,就会出现无法定位起始扇区了。 在课程中的代码,我们LBA28的高12位是完全没有使用的,只使用了低16位。 不过现阶段,我们采用的虚拟机,虚拟硬盘也就十几MB,完全在0xFFFF的范围内,所以这个BUG就不考虑了,也就不解决了。 (让代码凑合能跑就行了,毕竟这代码,不是商业化需要,只是为了教学帮助大家构建编程思维。) 但大家应该知道: LBA28支持最大硬盘是0xFFF FFFF * 512 =当于2的28次方=268435456个扇区,每个扇区是512个字节。 所以使用LBA28可以管理128G的硬盘。
064.near和far的应用场景
复习题
复习指引
065.封装屏幕输出接口
复习题
复习指引
066.外围设备及其接口
复习题
复习指引
068.写硬盘其他扇区
复习题
复习指引
问题
(看完了,仅代码没读)
069.读硬盘其他扇区
复习题
复习指引
067.并行和串行
复习题
复习指引
070.shl和shr
复习题
复习指引
shr=shift right
ror=rotate right
shl=shift leftfas
071.封装读写硬盘接口
复习题
复习指引
072.光标
复习题
复习指引
073.回车和换行
复习题
复习指引
074.mul指令
复习题
复习指引
060.equ
复习题
复习指引
类比:C语言,会接触到一个#define的语法,跟equ本质没区别。
equ是伪指令
075.分段机制
复习题
请默写分段四大指令的语法?
复习指引
4
四大指令
section用于声明一个分段
align
语法
“align=16”就表示段是16个字节对齐的。 “align=32”就表示段是32个字节对齐的。
例
代码
section data1 align=16 db 0x11 section data2 align=16 db 0x22 section data3 align=16 db 0x33
相对起始汇编地址结果
data1 相对起始汇编地址0x00000处 data2的相对起始汇编地址0x00020 data3..................0x00030
绝对起始汇编地址结果
我们可以观察一下编译后的机器码。 这样子,若上述代码被加载到内存地址0x07C00的位置。 data1的绝对起始汇编地址就是:0x07C00+0x00000 data2的绝对起始汇编地址就是:0x07C00+0x00010 data3的绝对起始汇编地址就是:0x07C00+0x00020 若上述代码被加载到内存地址0xB8000的位置 data1的绝对起始汇编地址就是:0xB8000+0x00000 data2的绝对起始汇编地址就是:0xB8000+0x00010 data3的绝对起始汇编地址就是:0xB8000+0x00020
vsstart
如果不加vstart语句,在某个段内引用某个标号时,该标号处的汇编地址依然是从整个程序的开头计算,而不是从段的开头出计算。
如果分段内使用语句vsstart=0后,那么分段内的标号的汇编地址相当于局部汇编地址(hj)
section.段名称.start
例子
数据段“data1”相当于整个程序开头的汇编地址是section.data1.start。 数据段“data2”相当于整个程序开头的汇编地址是section.data2.start。 数据段“data3”相当于整个程序开头的汇编地址是section.data3.start。
Tips
代码规范:一个标准规范的8086程序,应该包含代码段、数据段、附加段和栈段等
全都是骗人的(伪指令)
在8086程序设计中,段与段之间的界限在程序加载到内存之前就已经准备好了。
(一说伪指令,你应该第一反应是:一旦转换成机器语言之后,这条指令是不存在的。伪指令是给编译器看的)
分段的意义
“分段为了设计程序的时候,可以更加方便定位内存地址。
段的大小和段的起始物理位置的硬性规定?
段的大小没有硬性规定:如果你就不想按照16的倍数分段也可以
段的起始位置有硬性规定
Inter处理器要求段在内存中的起始物理地址是16字节对齐,也就是20位的物理地址必须16的倍数。(0x****0)
实现方式:align
077.加载器理论
复习题
复习指引
本节存科普。。知道加载器头部和加载器的作用即可
加载器的头部
为了让加载器,知道被加载程序的一些详细情况。 就得把一些被加载程序的一些必要信息,放到某个地方,这样子加载器加载这个程序的时候,可以从这个地方,知道一些被加载程序的关键信息,确定如何去加载这个程序。 这些需要提供给加载器的必要信息,一般都放到“被加载程序”的头部。
加载器和编译器的关系
程序员,根本就不需要考虑,怎么样让自己的程序,可以被加载器识别运行。(编译器已经替你完成这个工作了)
加载器的作用
如果我们写了一个程序,这个程序在100扇区存放着,我们想让躺在第100扇区的这个程序指令起来,就得把主引导扇区改造成一个类似加载器工作机制的程序。 主引导扇区(加载器),把这个100个扇区的内容,放到某个空闲的内存,让CPU跳到那个程序的代码段,开始运行那个程序。
078.设计加载器和被加载程序
复习题
复习指引
080.磁盘文件碎片
复习题
复习指引
081.被加载程序的初始化和收尾工作
复习题
复习指引
082.升级屏幕输出接口之前的准备工作
复习题
复习指引
083.升级屏幕输出接口
复习题
复习指引
084.时钟周期
复习题
无
复习指引
无
我们也可以把振荡器叫做“时钟发生器”。
时钟周期,是CPU最小的振荡单位。 如果一秒钟产生50次脉冲信号,这个时钟周期就是50分之1秒。
总线周期和指令周期
总线周期:cpu从内存中读取指令,向内存中存取数据,对外设端口读写数据,执行总线周期,总线周期通常包含4个T状态:T1,T2,T3,T4。所谓一个T状态就是一个时钟周期。它是CPU执行操作的最小时间单位。<BR>机器周期:通常用从内存中读取一个指令字的最短时间来规定CPU周期(机器周期),也即CPU完成一个基本操作所需的时间。通常一个机器周期包含12个时钟周期,在8051系列单片机的一个机器周期由6个S周期(状态周期)组成。一个S周期=2个节拍(P),也就是一个状态周期包含2个时钟周期,所以8051单片机的一个机器周期=6个状态周期=12个时钟周期。又称CPU的工作周期或基本周期,总线周期。 指令周期:执行一条指令所需要的时间,是从取指令、分析指令到执行完指令所需的全部时间,计算机中,常把一条指令的执行过程划分为若干个阶段,每一个阶段完成一项工作。每一项工作称为一个基本操作,完成一个基本操作所需要的时间称为机器周期,所以一个指令周期一般由若干个机器周期组成。指令不同,所需的机器周期也不同,比如一个复杂指令可能需要很多个机器周期才能完成,而每个机器周期又由多个时钟周期完成。
085.中断
本节主要讲外部中断,内部中断在后面讲
086.中断处理
087.实时时钟
088.RTC中断代码
内部中断
BIOS中断
32位CPU
100.gcc编译器的安装
复习题
复习指引
076.进一步理解标号
复习题
无
复习指引
本节介绍了3种表示内存地址的方式,主要就是在告诉我们vsstart的作用
因此本节就是vsstart的一个例子而已
不用刻意复习
版本1
ds:0x07c0
0x11 0x22 0x33 = 3 4 5
代码
jmp near Code Data: db 0x11,0x22,0x33 Code: mov ax,0x07C0 mov ds,ax mov al,byte [ds:Data+0] mov al,byte [ds:Data+1] mov al,byte [ds:Data+2] jmp near $ times 510-($-$$) db 0x00 dw 0xAA55 每一次,我们写的程序,被加载到内存地址:0x07C00的时候。 段寄存器:ES,CS,SS,DS都被默认被初始化成:0x0000。 jmp near Code 在内存里面占3个字节。 0,1,2。 标号Data下的db 0x11,0x22,0x33相对地址就是:3,4,5 所以可以得知: 0x11的内存地址是:0x07C03 0x22的内存地址是:0x07C04 0x33的内存地址是:0x07C05
版本2
ds:0x0000
bx:0x07c0
0x11 0x22 0x33 = 3 4 5
代码
jmp near Code Data: db 0x11,0x22,0x33 Code: mov bx,0x7C00 mov al,byte [ds:bx+Data+0] mov al,byte [ds:bx+Data+1] mov al,byte [ds:bx+Data+2] jmp near $ times 510-($-$$) db 0x00 dw 0xAA55 最终组合出来的内存地址,还是:0x07C03,0x07C04,0x07C05。
版本3
ds:0x0000
0x11 0x22 0x33 =0x07c03 0x07c04 0x07c05
请看更多的例子以确定section Mbr vstart=0x7C00 的有效性;即我们可以人为的刻意指定段的起始汇编地址?
代码
section Mbr vstart=0x7C00 jmp near Code Data: db 0x11,0x22,0x33 Code: mov al,byte [ds:Data+0] mov al,byte [ds:Data+1] mov al,byte [ds:Data+2] jmp near $ times 510-($-$$) db 0x00 dw 0xAA55
第6章笔记(10.18)
本章代码
代码总览
本章代码功能
将任意5位数的每位数字打印到屏幕上
将字符串mytext直接传递(movsb)给es寄存器并打印到屏幕上
代码核心1:霸王硬上弓-字节把mytext字符串利用movsw传到es寄存器输出
代码核心2:jns+dec完美组合实现一个常规循环
代码核心3:jmp near $
意义:就是无限循环第53行,就是跳转到该行行首的意思。 这里本质上相当于在53行行首隐藏了一个$
5.5.1 显示标号的汇编地址
汇编地址定义
书本截图定义
复习
汇编地址和偏移地址的关系
超级精华图
图注释
1:交叉的,因为实际内存是从低地址向高地址的
2.汇编地址=偏移地址
标号语法
标号之后的冒号是可选的
标号可以独占一行
5.5.3 在程序中声明并初始化数据
复习指引
复习题
核心理解
“声明数据的代码 如db 0,0,0,0”这个动作完全是非指令的数据,编译器编译后会对该代码完全保留。因此我们要在程序程序时避免触碰到这些“非指令”数据(不然就程序崩溃)
DBDWDDDQ
分别用于声明1 2 4 8字节的数据
举例
db 0,0,0,0,0 这是占位,有点像TF的占位符。注意db如果想声明大于长度1的数据必须用逗号隔开
TIps
为什么 db '123' 和db 'I MISS U' 是合法的??
因为编译器直接把db '123'拆成 db '1','2','3'
代码规范
应该把所有的声明数据的代码写在同一个数据段中
6.4 段地址的初始化
害群之马
程序运行的开始不是在偏移地址为0的地方开始
解决方法
6.5 段之间的批量传送
movsb和movsw传输
正向传输和反向传输
正
SI DI +1或+2
反
SI DI -1或-2
源地址和目标地址
原始数据地址 DS:SI
段地址在DS,偏移地址在SI
传输目标地址 ES:DI
段地址在ES,偏移地址在DI
命名来源
movsw的意思是move string word
movsb的意思是 move string byte
相关寄存器
CX
决定传送的字节数或字数
相关标志寄存器
ZF
0代表证
名称:零标志
1代表假?
DF
名称:方向标志
功能:控制传输方向
命令
cld
让DF=0,正
std
让DF=1,逆
标志寄存器图示
rep+movsw或movsb
循环执行movsw或直到CX=0
6.8数位的显示
6.9.1~6.9.4 标志寄存器相关
标志寄存器精品图示
PF(视频49节)
PF规则
运算结果操作数的低8位为1的个数为偶数时,PF=1,否则PF= 0。
PF应用(计网里好像看到过)
利用PF可进行奇偶校验检查,或产生奇偶校验位。 在数据传送过程中,为了提供传送的可靠性,如果采用奇偶校验的方法,就可使用该标志位
SF
何时用SF?
如果我们把一个数,当作有符号数看待。 每次运算完之后,只需要看一下SF,就知道这个数是有符号正数,还是有符号负数。 如果你把这个数,当作无符号数看待,就没必要看SF。
SF规则
SF=Sign Flag 该标志为一个有符号数的符号位。
OF
OF规则
OF=Overflow flag 一个有符号数,运算结果超过当前运算位数所能表示的范围,OF的值被置为1,否则,OF的值被清为0。
如何看一个数是否溢出?CF和OF的区别
当我们把一个数字,当成无符号数运算,是否溢出看CF标志位。 当我们把一个数字,当成有符号数运算,是否溢出看OF标志位。
讲稿的寄存器名称笔记大全
DB=Declare Byte 一个字节 DW=DeclareWord 两个字节 DD=DeclareDouble Word 四个字节 DQ=Declare Quad Word 八个字节 伪指令:Pseudo Instruction AH&AL=AX(accumulator):累加寄存器 BH&BL=BX(base):基址寄存器 CH&CL=CX(count):计数寄存器 DH&DL=DX(data):数据寄存器 SP(Stack Pointer):堆栈指针寄存器 BP(Base Pointer):基址指针寄存器 SI(Source Index):源变址寄存器 DI(Destination Index):目的变址寄存器 IP(Instruction Pointer):指令指针寄存器 CS(Code Segment)代码段寄存器 DS(Data Segment):数据段寄存器 SS(Stack Segment):堆栈段寄存器 ES(Extra Segment):附加段寄存器 OF overflow flag 溢出标志 操作数超出机器能表示的范围表示溢出,溢出时为1. SF sign Flag 符号标志 记录运算结果的符号,结果负时为1. ZF zero flag 零标志 运算结果等于0时为1,否则为0. CF carry flag 进位标志 最高有效位产生进位时为1,否则为0. AF auxiliary carry flag 辅助进位标志 运算时,第3位向第4位产生进位时为1,否则为0. PF parity flag 奇偶标志 运算结果操作数位为1的个数为偶数个时为1,否则为0. DF direcion flag 方向标志用于串处理.DF=1时,每次操作后使SI和DI减小.DF=0时则增大. IF interrupt flag 中断标志 IF=1时,允许CPU响应可屏蔽中断,否则关闭中断. TF trap flag 陷阱标志 用于调试单步操作. 在8086这款16位处理器上,指令中的操作数可以是8位,或者16位的寄存器。 mov ax,.0x1111 mov ah,0x11 mov al,0x11 当然,操作数也可以是指向8位或者16位内存地址。 mov byte [内存地址],0x11 mov word[内存地址],0x1122 bx,bp,si,di,同时还可以加上一个8位或者16位的偏移量。
记住各个寄存器的应用场景,不要乱用(超重要)
根据上面的笔记大全来记住应用场景
比如DS常用于存放数据段
CS用于存放代码段
BX常用于存放数据段段内偏移地址
6.9.5 条件转移指令
cmp
判定相等和大小关系
立即观察CF标志位可以推导出,如果CF=0,则被减数大于等于减数。如果CF=1,则被减数小于减数。(CF是针对有符号数) 立即观察ZF标志位可以推导出,如果ZF=1,则被减数等于减数。如果ZF=0,则被减数和减数不相等。 (ZF是针对无符号数和有符号数。)
Tips
但cmp只影响标志寄存器而不改变操作数的值
JB和JNB(代码还没搞)
视频代码(代码来自44节)
有了这些指令,就可以让我们的程序具有一定的“智能和思考”。 比如我现在要求大家设计一个程序功能: 输入一个年龄,如果这个年龄是18岁以上(包括18)岁,就在屏幕上显示“Adult”,如果这个年龄小于18岁,在屏幕上显示“Minor” ;程序设计需求: ;输入一个年龄,如果这个年龄是18岁以上(包括18)岁,就在屏幕上显示“Adult”。 ;如果这个年龄小于18岁,在屏幕上显示“Minor” ;我们要往屏幕上显示数据,是不是得准备显示段呢,但我们不能直接给段寄存器赋值,得间接赋值。 mov ax,0xB800 mov es,ax; 初始化显示段寄存器 mov ax,0x07C0 mov ds,ax; 初始化数据段寄存器 mov si,0; 初始化数据段 偏移寄存器 mov di,0; 初始化显示段 偏移寄存器 jmp near code Age: db 17; 输入年龄的地方 Adult: db 'Adult' Minor: db 'Minor' code: mov al,byte[ds:Age] cmp al,18 ;CF=1,也就是输入的年龄比18岁小, ;CF=0 说明输入的年龄大于18岁,或者等于18岁。 把代码赋予了我们现实的意义(灵魂) JNB PrintAdult ;如果al小于18岁,则跳转。 PrintMinor: ;在屏幕上输出未成年人 mov cx,code-Minor ;确定要输出几个字节 mov si,Minor jmp near StartPrint PrintAdult: ;在屏幕上输出成年人 mov cx,Minor-Adult ;确定要输出几个字节 mov si,Adult StartPrint: mov al,[ds:si] mov byte [es:di],al inc di mov byte [es:di],0x07 inc si inc di loop StartPrint end: jmp 0x07C0:end times 510-($-$$) db 0x00 db 0x55,0xAA
规则阐明
JB, JNAE CF=1,跳转。 JB=jump when below JNAE---->jump when not above or equal JNB, JAE CF=0,跳转。 JNB---->jump when not below JAE---->jump when above or equal
和CMP结合使用
CMP运算之后,根据CF变化,再使用JB指令(两个无符号数相减,被减数若小于减数则跳转) CMP运算之后,根据CF变化,再使用JNB指令(两个无符号数相减,被减数若大于减数或者等于则跳转)
JE和JNE(代码还没搞)
语法规则
JE, JZ 结果为零则跳转(相等时跳转) ZF=1 JNE, JNZ 结果不为零则跳转(不相等时跳转) ZF=0
和CMP结合使用
CMP运算之后,影响ZF的值。 CMP运算之后,ZF=1,使用JE跳转。(相等于两数相等则跳转。) CMP运算之后,ZF=0,使用JNE跳转。(相当于两数不相等则跳转。)
视频代码(代码来自45节)
;程序设计需求: ;输入两个数,如果这两个数相同的话,则在屏幕上显示“Two numbers the same”。 ;如果这两个数不同的话,在屏幕上显示“Two different numbers” ;程序设计需求: ;输入两个数,如果这两个数相同的话,则在屏幕上显示“Two numbers the same”。 ;如果这两个数不同的话,在屏幕上显示“Two different numbers” mov ax,0xB800 mov es,ax mov ax,0x07C0 mov ds,ax mov si,0 mov di,0 jmp near code number1: dw 200;输入第一个数字。 number2: dw 200;输入第二个数字 string1: db 'Two numbers the same' string2: db 'Two different numbers' code: mov ax,word[ds:Number1] mov bx,word[ds:Number2] cmp ax,bx ;je printstring1 ;zf=1的时候,则跳转 jne printstring2 ;zf=0的时候,则跳转 printstring1: mov cx,string2-string1 mov si,string1 jmp near startprint printstring2: mov cx,code-string2 mov si,string2 startprint: mov al,byte [ds:si] mov byte[es:di],al inc di mov byte[es:di],0x07 inc di inc si loop startprint end: jmp 0x07C0:end times 510-($-$$) db 0x00 db 0x55,0xAA
条件跳转指令大全
第7章笔记(10.18)
7.4 计算1到100的累加和
代码
jle+cmp
for{ .... if x<100 continue}
@f ... ... cmp cx,100 jle @f
7.5
7.5 栈和栈段的初始化
定义栈需要两个步骤
第一步:嫁给一个段(比如cx)
第二部:初始化SP指针(作用类似偏移地址)
代码
如何定义栈的长度?
7.5.2 分解各个数位并压栈
PUSH指令
工作流程
先SP-2
再存
问题
为什么本节的div完全和idiv的规则一样?把DX:AX做被除数
7.5.3 出栈并显示各个数位
POP指令
工作流程
先取
再SP+2
Tips:POP指令和PUSH指令都不会影响任何标志位
7.5.4深度理解栈
SP并不是栈特有的属性,他不过是一个普通的指针而已(只不过系统规定这个指针只能由栈使用)
栈没有任何新颖的属性或定义。。。本质上就是一个超级平庸的内存而已,只不过系统帮你封装了几个方便的命令:pop push sp。。。
7.6 程序的编译和运行
7.7 Addressing Mode
中文:寻址方式
记忆:BP-(唱) 挣脱了枷锁 我自由拿参数
056.非内存的寻址方式(寄存器寻址和立即寻址)
寄存器寻址
mov ax,cx
需要操作的数据位于寄存器中,可以从寄存器里面取的。
立即寻址
add bx,0xf000
上述指令,目的操作数为寄存器寻址,用于提供被加数。 第二个操作数(源操作数)用于给出加数0xf000,这是一个立马给出的数据, 称为立即寻址
057.内存寻址(直接寻址-基址寻址-变址寻址)
直接寻址
定义:在8086里面,访问内存的时候,如果是段寄存器加一个固定偏移量(常量),就是直接寻址
通俗表达:相当于偏移地址是一个常量
例:mov ax,word [ds:0x5c0f] 要表示内存地址,必须使用中括号括起来。
非内存寻址
基址寻址(BXBP)
通俗表达:相当于偏移地址用变量BXBP表示
定义:用BXBP 作为偏移地址辅助,确定内存地址
应用场景:针对数据段操作的时候
例:inc word[ds:bx]
内存寻址
变址寻址(SIDI)
通俗表达:相当于偏移地址用变量SIDI表示
定义:用SIDI 作为偏移地址辅助,确定内存地址
应用场景:针对栈操作的时候
例:add ax,[es:di]
058.基址变址寻址(BXBP+SIDI)
定义
使用一个基址寄存器(bx或者bp),外加一个变址寄存器(si或者di) 即:同时使用(bx bp)和(si di)
内存寻址
例
mov ax,[ds:bx+si]
内存寻址
变址寄存器+基址寄存器组合限制
[bx+si]
内存寻址
[bx+di]
[bp+si]
[bp+di]
其他全是非法的,如[bp+bx]就是非法的
SI和DI是变址寄存器,而BX BP是基址寄存器
注意:仅仅以上组合的情况下适用以上规则,但是没有这个组合的话BXBPSIDI都能当做偏移地址
例:合法--[SS:BX]
内存寻址
图示
内存寻址
只有红色4小寄存器能够作为偏移地址 和其他段寄存器组合成内存定位地址
内存寻址的共性
共性1:四个寄存器都代表偏移地址
使用BXBPSIDI 4个寄存器,作为偏移寄存器辅助定位内存
bx bp si di存放的值都是偏移地址,不要以为bx和bp放段地址
共性2:偏移量均可跟一个参数
BXBPSIDI后面还可以增加一个常数(偏移量)
各个特殊用途寄存器介绍
AX CX DX SI DI的介绍看上图
第3天(10.17号)
把学习方法这节视频看掉
020.虚拟机
复习题
复习指引
本节不需要复习,可以瞄一眼这个基本命令
本节视频演示了按照Bochs以及用他模拟BIOS开机过程,复习的时候可以看看视频(如果忘记了)
使用虚拟机Bochs2.6.8模拟8086CPU
002.简谈编译细节
纯、伪汇编指令
介绍
1.纯汇编指令:机器指令的助记符,有对应的机器指令。 机器指令和纯汇编指令才是真正的一一对应,互相转换的关系,就像二进制和十六进制一样。 2.伪汇编指令:不能直接转换为机器指令,需要在转换之前,得先把伪汇编指令,转换成纯汇编指令。
机器指令和纯汇编指令才是真正的一一对应关系
Tips
我们实际中写的汇编代码往往是上述两种混杂在一起的。
例子
纯
假设现在有一条机器指令:1001001111001110。 上述机器指令对应的纯汇编指令为: mov ax,300D 。
伪
mov ax,(100+200)D
伪汇编指令的预处理过程
逆向工程
这个我肯定要深入学的
003.中央处理器和存储器
复习题
存储和运算的真实流程?
有哪3种总线?
复习指引
看这里
看这个例子就好,知道总线的作用
存储和运算的真实流程
文字描述(3步骤流程)
被加速和加数通过引脚送入处理器
寄存器RA和RB将分别锁存参与运算的被加数和加数
与寄存器RA和RB相连的算术逻辑单元(ALU)进行加法运算
如图
三大总线
两个例子说明:总线的功能
繁琐的例子:CPU从内存读写数据流程
3个步骤
CPU要从内存中读写数据,必须具备三种信号: 1.定位从内存的哪个地址开始读写。 2.确定读数据,还是写数据。 3.这些数据怎么样传送。
例
mov RA,[011B] (1)CPU通过地址总线将地址定位到到内存地址011。 (2)CPU通过控制线发给内存,我要读取对应地址总线存储单元的数据。 (3)把内存单元010里面的内容通过数据总线传入CPU。
通俗的例子:三大总线和人脑的类比
你的大脑让你的左手抬起来。 首先大脑需要确定至少三个信息: 1.身体哪个部分。 (左手)(地址信息) 2.做什么动作。(抬,用多快的速度抬,抬多高,抬的力量是多少)(控制信息) 3.然后把上述信息组编码生成一个“生物电信号”,通过“神经网络”发送出去。 4.手部的肌肉组织收到“生物电信号”,进行“解码”,解码之后,开始执行动作
三大总线图示和分类
总线可以分为内部总线和外部总线。 内部总线是CPU内部各个器件之间的联系。 外部总线是CPU和主板上其他器件的联系。
三大总线分类介绍
单向
地址总线 Address Bus
地址总线(Address Bus)是专门用来传送地址的
Tips
单向:地址只能从CPU传向外部存储器或I/O端口
16位微型机的地址总线为20位,其可寻址空间为220=1MB
双向
数据总线 Data Bus
数据总线(Data Bus)CPU与内存或其他器件之间的数据传送线路。数据总线的宽度决定了CPU和外界的数据传送速度。 8根数据总线一次可以传送8个比特位,16根数据总线一次可传送两个字节。
控制总线 Control Bus
控制总线(Control Bus)用来传送控制信号和时序信号
Tips
控制总线的位数要根据系统的实际控制需要而定。 控制总线是一些不同控制线的集合,有多少根控制总线,意味着CPU对外部器件有多少种控制。
字长控制也属于控制总线的一部分,决定要从内存里拿几个存储单元的数据。
CPU概述
CPU是由运算器和控制器组成。 控制器就是译码器,译码器就是把一定的输入转换成另一种输入。 而ALU就是加强版的运算器,它支持的运算功能更多,不仅仅是加减乘除。
简单地说,在CPU中: 运算器进行信息处理。 寄存器进行信息存储。 控制器控制各种器件进行工作。 内部总线连接各种器件,在它们之间进行数据的传送。
Tips
CPU的引脚
引脚的用途
供电、接收中断信号、与内存交流以及与其他硬件交流等
寄存器命名的来源
处理器总是很繁忙的,在它操作的过程中,所有数据在寄存器里面都只能是临时存在一会儿,然后再被送到别处,这就是为什么它被叫做“寄存器”的原因。
004.intel8086处理器
复习题
请在寄存器模拟器模拟这两条指令:mov eax,0xFFFFFFFFF mov ah,0x11
改变了ah的时候,AX也改变了,意味着EAX也改变了
请在脑子里画出 EAS AX AH AL寄存器的图
复习指引
看这里
CPU中的主要部件是寄存器。 程序员只改变各种寄存器中的值。
详细描述
CPU中的运算器控制器包括总线等工作状态,我们是无法直接控制,或者得知的。 都是通过寄存器间接控制CPU,或者根据寄存器里面的一些数值,得知CPU目前的一些工作状态
举例
比如我们想让CPU从内存的某个地址开始获取指令。 我们就得修改某个寄存器的值,这个寄存器的值改变了,会直接连接到地址总线上,地址总线也会发生改变,CPU获取下一条指令,就会从这个内存地址开始获取。
8086处理器介绍
8086处理器内部有8个16位的通用寄存器。 分别被命名为:AX、BX、CX、DX、SI、DI、BP、SP。 通用的意思是,它们之中的大部分可以根据一些目的,一定程度的灵活复用。
8086CPU一共4个段寄存器。(ES、DS、CS、SS)
他是16位处理器
兼容性(寄存器的知识点这里有)
寄存器兼容性模拟图
兼容性详细文字描述
比如说 a := 1,当你创建一个变量a并且给他赋值时。64位操作系统直接给你一个64字节的储存单元FAX,而8位和16位则给你分配AH和AX;
兼容性指的是:你在远古时代用的8位操作系统编写的软件A,里面分配的变量都是8位直接的存储单元。当你把软件A运行在win10(64位),win10会直接给你分配EAX例的AL寄存器,但是AH和AH前面的部分全部被浪费了 你用不到(但是你可以用特殊手段访问前面部分的寄存器)
兼容性表格图示
寄存器的合体
符号DX:AX,表示将AX和DX合体成为一个32位的寄存器
问题:es ip cf等段寄存器怎么没有画出来????
005.逻辑移位
复习题
X进制数左移1位规律代表什么?
乘以X
没有题
复习指引
看这里
无溢出情况
规律
在没有溢出的前提下: 左移N位等于乘以2的N次方,右移N位等于整除2的N次方
图例
溢出情况
0111 1111 = 127D 逻辑左移1位: 1111 1110 =254D 逻辑左移1位: 1111 1100 =252D
006.8086定位内存地址
复习题
8086处理器的工程师是如何使用两个16位的寄存器,来表示一个20位的内存地址呢?
8086寻址空间/寻址空间是多少?
复习指引
知道x086的内存地址是20位的,
知道CPU当下执行的命令的段地址都是存在CS寄存器,偏移地址则是IP;段地址和偏移地址都是16位的,但是我们通过公式:段地址 x 16 + 偏移地址 = 物理地址 合成后的物理地址只有20位
8086处理器的工程师是如何使用两个16位的寄存器,来表示一个20位的内存地址呢?
图示
核心原理:段地址 x 16 + 偏移地址 = 物理地址
Tips
8086除了地址总线是20根,其他又都是16位结构。 寄存器也是16位的,ALU也是16位的,数据总线等其他也是16位的。
段寄存器
段地址-->CS寄存器
偏移地址-->IP寄存器
段地址 x 16的计算规则
地址加法器如何完成段地址 x 16的运算,就是以二进制的形式存放的段地址左移4位
X进制数左移1位规律
一个十六进制的数字,左移1位,相当于乘以16。 一个十进制的数字,左移1位,相当于乘以10。 一个X进制的数字,左移1位,相当于乘以N。
在8086CPU中,物理地址一样不代表段地址和偏移地址一样
例子
这些物理地址都代表210F60H物理地址: 段地址 偏移地址 2000H 1F60H 2100H 0F60H 21F0H 0060H 21F6H 0000H 1F00H 2F60H
比喻
繁琐版
简洁版
8086寻址能力
8086寻址空间/寻址空间
所以8086最大的寻址能力就是1MB。
繁琐表达
如果你为8086配备了一根存储空间为10MB的内存条,多余出来的9MB,也没意义。 因为8086最大只能识别1MB的内存空间。
为什么不把寄存器位数和地址总线等都设计成16位?
最大只能表示: 64KB。 这个内存太小了
007.代码段和数据段(寄存器和内存的关系)
复习题
如果储存器是大楼,那么 地址总线和CPCS寄存器是什么?(比喻右边这幅图)
请问,段寄存器和内存的关系是什么?
段寄存器存放的是各个内存储存单元的地址;段寄存器不是内存的子集
段寄存器是电梯按钮,内存是高楼
内存和段寄存器的物理原理完全都一样,都是通过上升沿触发器构建的;内存也是寄存器;段寄存器是特殊的寄存器(用于实现各种不同的特殊功能,比如存放显存地址);
搜索“兼容性”笔记,你就能看到8086寄存器就那个几个。。
操作数和操作符写在内存里 而内存的地址写在各个不同的段寄存器里
复习指引
1
电梯和楼层比喻
高楼
存储器对于现在的我们可以很粗暴的抽象成一座高楼,这座高楼,每层能存放8个比特位(1个字节)
电梯
CPU的地址总线,就相当于电梯。决定了CPU最多可以上到这座高楼的多少层。
如果CPU只有8根地址总线,那么最多支持000~255层楼,即使存储器是1000层楼,多出的楼层也是浪费。
电梯的按钮
段寄存器 x 16 + 偏移地址就是电梯里面的按钮。
图示
代码段和数据段的定义
官方定义
要把这一堆指令放到内存中的某个地方,就形成了一个段,所以就有了指令段(代码段)。 CPU执行指令的时候,要使用到一些数据进行运算,这些数据也集中放在内存的某个地方,就又形成了一个段,叫做数据段。
这一切都是我们人脑自己抽象出来,计算机内部并没有什么狗屁代码段和数据段
图示
常识
008.文件拓展名
009.压缩文件
010.安装editplus
001.简谈汇编语言
复习题
什么是 二进制转化为八进制和十六进制 的 四位拆解转换?
复习指引
本节不用复习
内存和外存的区别
内存就是:内部存储器,CPU拿指令和数据的地方。 外存则是:当计算机断电后指令和数据保存在哪里。
二进制转化为八进制和十六进制
二进制转十六进制是四位拆解转换,不足四位,前面补0。 二进制转八进制三位拆解转换,不足三位,前面补0。
常识
012.ASCII和ANSI
复习指引
本节是常识,不用复习
gbk
英文字符 数字字符 1个字节
汉子2个字节
ANSI
所以ANSI压根就是一种不确定的编码,在不同国家语言版本的Windows操作系统上,会自动用不同的编码解码规则
在中国就变成gbk
在台湾就变成big5
013.注册表(配置信息)
复习题
注册表的功能是什么?
复习指引
本节不用复习,只要知道注册表的功能即可
注册表
介绍
注册表是我们Windows系统自带的一种编码文件
注册表功能
注册表可以理解是Windows操作系统自带的一个“数据库”或者可以理解成“记忆库”
举例
在我们的计算机中,你一旦安装了一些软件,或者更改了一些软件的信息,这些设置有可能就会保存到注册表中。 你购买了某个软件,输入了安装密匙之后,这个软件可能就会把这个密匙保存到注册表里面。 以后每次运行这个软件的时候,软件都会到注册表的某个位置找一下有没有密匙信息,如果有的话,再检查一下这个密匙正确不正确。 如果正确,软件就进入了正常工作界面。 如果不正确,软件就进入了提示你输入密匙。
Tips
注册表一般情况下位于:C:\Windows\System32\config
Windows系统为我们提供了注册表编辑工具。 比如:regedit.exe
配置注册表的方法
设置相关注册表的配置信息有很多种方式: 一种是Regedit注册表编辑器打开注册表进行设置。 一种是在某个程序中进行更改了设置之后,程序内部会直接修改对应位置的注册表信息。 还有一种是自己写注册表文件设置信息,新建一个txt,后缀名改成.reg,在记事本打开,写好之后运行就可以了。
014.命令行参数
复习指引
不需要复习
利用命令行参数捕获工具来捕获酷狗的命令行参数
视频25分钟开始讲
避免两个可能导致BUG的地方
路径不要有空格
关于d:\sh ow这种特殊情况的处理
带空格的路径输入到命令行会无法识别,但是加引号就可以 d:\"sh ow"
能加引号尽量加引号来避免错误
给命令行参数加上引号来避免歧义错误
不要用中文路径
关于中文目录的极端情况解释以及解决方案
讲稿原文
举个例子,某个老外开发了一个音乐播放器叫做mplayer.exe 你可能安装到了d:\音乐播放器\mplayer.exe 或者 d:\音乐 播放器\mplayer.exe 只要加上引号,在现代的Windows操作系统中,cmd肯定可以启动这个程序。 但是,如果这个播放器只支持英文编码,而不支持其他编码。 那么当传递参数的时候,如果出现非ansi编码的字符,就会导致异常失败。 如下列这种情况。 d:\音乐播放器\mplayer.exe d:\遇到.exe 这种情况传入的参数是中文,mplayer程序无法处理。 就得把文件名改成拼音或者英文才能被音乐播放器内部的接口识别处理。 d:\音乐播放器\mplayer.exe d:\yudao.exe 在中国计算机发展历史上,中文编码兼容性是一直存在的一个问题,直到现在,每个程序员都遇到过这个问题。
015.拓展名管理(不用复习)
复习指引
本节简绍了一个软件来改变默认打开方式。。不需要复习
利用文件扩展名管理工具可以设置特定文件的默认打开方式
016.全角和半角(常识)
复习指引
本节不用复习
全角和半角的区别
半角
半角标点符号使用的编码是ascii编码
定义
半角就是指 ASCII 编码表以内的标点符号
全角
全角标点符号使用的编码是gbk编码
定义
ASCII编码表以外,如GBK,BIG5, Unicode等编码规则下的,多字节的标点符号
017.硬盘和MBR
复习题
MBR和普通扇区的区别?
复习指引
本节就是简单科普一些概念,不需要刻意复习
固态硬盘和机械硬盘
固态硬盘传输速度快,但是数据相对机械硬盘来说易丢失
Tips
扇区这个概念来源于机械硬盘的工作原理,而固态硬盘是没有扇区这个概念的。 但是为了兼容一些文件管理系统,固态硬盘也模拟抽象出了扇区的概念。
操作系统简介
讲稿原文
Tips
文件管理系统的本质
文件管理系统的本质就是一种存储编码规则,指的是一个文件(一堆二进制数据)是怎么样存放到硬盘中。 所以文件管理系统会把硬盘进行封装,最后给我们抽象出了文件和文件夹等概念
扇区
鬼影病毒
鬼影”系列病毒的共同特点是感染电脑硬盘的主引导记录(MBR)
主引导扇区 Master Boot Record
主引导扇区是硬盘上比较特殊的一个位置,这里存储的一些重要的指令,负责引导加载其他扇区的操作系统启动。
功能:主引导扇区的功能是继续从硬盘的其他部分读取更多的内容加以执行,像Windows系统,就是采用这种接力的方法一步一步把自己运行起来的。
Tips
为了接下来的课程简单一些,大家就把硬盘从逻辑上分割成512个字节为一个存储单位,每个存储单位对应着一个扇区编号
图示(和之前的高楼图很像)
唯一的不同是每个存储单元的大小为512字节
018.8086内存布局
复习题
如果给你一台没有操作系统的8086CPU计算机,你写了一段汇编语言程序,并且使用汇编器转换成了机器指令。 你想让计算机执行你的机器指令,有什么办法呢?
那就是想办法把这段机器指令存放到硬盘主引导扇区,这样子当CPU自检完成之后,就会开始加载主引导扇区,执行我们写好的指令。
BIOS指令写在哪?
BIOS的功能?
复习指引
看这里 大致知道如何依靠BIOS开机即可
基本输入输出系统 BIOS
功能:让硬件处于一个正常的、默认的工作状态,也是能够让计算机运行起来最基本,最常规的功能。
Tips
兼容性
直到今天,虽然有很多计算机CPU已经是64位了,但在开机启动的过程中,CPU还是以16位的兼容模式启动,也就是在启动的时候,内存只能访问:0x00000- 0xFFFFF即1MB的大小
ROM
ROM(Read Only Memory)ROM在系统停止供电的时候仍然可以保持数据。
BIOS相关指令就写在ROM里
特点:必要的程序指令固化,加电时都自动执行。
BIOS开机自动启动流程
开机时的寻址图
指令执行顺序图
文字版描述开机流程
第一步
剑指ROM
繁琐表述
8086CPU收到复位信号,把CS置为:0xFFFF,其余的寄存器全部置位:0x0000。
CS:IP合成一个20位的内存地址:0xFFFF0,这个内存地址位于BIOS-ROM中
第二步
人类历史上第一个道电磁波:jmp 0xF000:0xE05B
第三步
自检
繁琐表述
8086cpu接下来就会跳转到0xFE05B开始执行BIOS程序,完全计算机的自检功能
第四步
请求MBR出山 指令:jmp 0x0000:0x7c00
繁琐表述
通知硬盘,把主引导扇区的512个字节,加载到内存地址:0x0000:0x7c00处
第五步
剩下的事情全靠MBR
开机代码
b 0x07c00
c
n
n
n
一直n
x086内存分区图
文字版
起始地址 结束地址 大小 作用 0x00000 0x003FF 1KB 中断向量表 0x00400 0x004FF 256B BIOS数据区 0x00500 0x07BFF 30464B约30KB 可用区域 0x07C00 0x07DFF 512B MBR被BIOS加载到此处,共512个字节 0x07E00 0x9FBFF 622080B约608KB 可用区域 0x9FC00 0x9FFFF 1KB 拓展BIOS数据区 0xA0000 0xAFFFF 64KB 用于彩色显示适配器 0xB0000 0xB7FFF 32KB 用于黑白显示适配器 0xB8000 0xBFFFF 32KB 用于文本模式显示适配器 0xC0000 0xC7FFF 32KB 显示适配器BIOS 0xC8000 0xEFFFF 160KB 映射硬件适配器的ROM或内存映射式I/O 0xF0000 0xFFFEF 64KB-16B 系统BIOS范围是0xF0000~0xFFFFF共64KB,为了说明入口地址,将最上面的16个字节从此处去掉了,所以此处终止地址为0xFFFEF 0xFFFF0 0xFFFFF 16B BIOS入口地址。 此处16个字节的内容是跳转指令:jmp 0xF000:E05B
019.Nasm汇编器
复习指引
本节不用复习,当做检索资料
启动Nasm基本命令
"...\nasm.exe" "-f" "bin" "原始汇编文件" "-o" "生成的机器文件"
配置快捷EditPlus快速启动编译器:
我们通过editplus留给我们的指令接口,让ET学会了自动补全命令从而我们省力了
子主题
011.内存分段机制
复习题
请写出分分成65536个段的第一个段地址和第二个段地址和最后一个段地址,以及每个段地址对应的偏移地址取值范围
复习指引
看这个即可
本节简单 不容易忘,不需要刻意复习
如果忘记了本节内容,用老师的内存分段模拟器一下便能回忆起来
16位段寄存器分段方法
两种常用分段方法
法1max:分成65536个段
第一个段的地址是:0x0000。 第二个段的地址是:0x0001。 第三个段的地址是:0x0002。 最后一个段的地址是:0xFFFF。
每个段地址对应的偏移地址取值范围是从0x0000-0x000F
法2min:分成16个段
第一个段地址是:0x0000 第二个段地址是:0x1000 第三个段地址是:0x3000 最后一个段地址是:0xF000
每个段地址对应的偏移地址取值范围是从0x0000-0xFFFF
Tips
行业约定1:任何分段方法,分出来的每个段应该是16的倍数;
行业规定2:程序的第一条指令,它的偏移地址应该是:0x0000
分段的意义
不管是内存分段机制,还是程序分段机制,目的都是一个,为了方便管理,降低程序开发难度,为设计功能更可靠,规模更大的程序奠定基础。
问题
栈到底存在哪里?
待办任务
完成王爽教材所有的检测点
把低1天和第2天的讲稿拷贝到onenote
https://study.163.com/course/introduction/1641008.htm 网易云-汇编贪吃蛇实战斗
网易云有一个5万人学习的王爽的课,每节完全对应书本的内容,甚至书本的每个检测点都讲了
王爽的网站:做检测题 http://www.asmedu.net/actions/guihua.jsp
其他教材
本课程参考技术书籍: 《穿越计算机的迷雾》 《编码的奥秘》 《计算机系统概论》 《计算机系统要素》 本课程参考相关信仰哲学书籍: 《游子吟》 《冲破灵界的黑暗》 《和合本圣经》
电影《超时空接触》《星际穿越》《最远的地方》《黑客帝国》《月球》等艺术作品也拓展了我们想象的边缘。 如果你喜欢看一些网络小说和电影,那《无限恐怖》
https://book.douban.com/subject/3735649/ 一个操作系统的实现
建议想学操作系统的按这个顺序学习:王爽《汇编语言》,李忠《x86》(本书),于渊《一个操作系统的实现》
文章-谈骄傲
骄傲是人经常容易产生的一种情绪,有的时候骄傲是一个褒义词,同义词为自豪,而有的时候骄傲是一个贬义词,是自满,傲慢的意思。 都是因为具有某种自己认为可贵的东西而自然而然产生的一种情绪,这其中的意义差别很大,导致的结果也是天壤之别。 人之所以会骄傲,是因为自己拥有了自己认为宝贵的东西。当你有一件自己认为特别珍贵的东西的时候,你就会不自觉的产生骄傲的情绪。而这种情绪是用褒义或是贬义来解释?这取决与什么东西才是你所认为珍贵的,这也直接映射了你的价值取向。 一个幼儿园的小朋友,他会因为自己有一支甜甜的棒棒糖或是一个很好玩的玩具,而在其他小朋友面前展示一番,这就是一种骄傲的情绪,是因为他认为这些是珍贵的东西。 一个中学生,他会因为自己考了更好的成绩,而在别人面前炫耀,这也是骄傲,因为他认为高的分数代表了荣誉,而荣誉是很珍贵的。 上述两种骄傲行为,应该是贬义的,或者说是低层次的(这里只是为了说明事件本身,而不是去批评少年儿童,因为他们的价值观还远未成熟,所以遇到这样的情况是自然而然的,这是需要我们去教育和引导的),第一种行为是因为拥有丰富的物质而沾沾自喜,另一种看似高级,其实本质上是一样的,为了荣誉而滋生的虚荣心,也许你会纳闷,考了高的分数难道不应该为自己高兴吗?仔细想想,其实上面的例子并不是这样的,如果你考了高的成绩想到的是自己辛苦的努力终于通过成绩得到了证明,那么这真是一件非常令人高兴的事情,而如果你考了高的成绩只是为了证明你比别人聪明,你在别人面前有了炫耀的资本,那么这就是虚荣,同样令人作呕。 那么什么样的东西才是真正珍贵的呢?是高尚的道德,当你认为道德是最珍贵的东西的时候,你就会因为自己拥有了道德而从骨子里发出骄傲的气息,而因为自己违背了道德而反复的捶胸反省,这样的骄傲不是展示给别人看的,不是一次炫耀或者说是一次作秀。 什么是高尚的道德,我也不能做出精确的定义,拾金不昧、除暴安良、诚实守信、爱岗敬业,这些行为都是,可能共同点就是不自私吧,而只有做这些的时候是真的在做,是发自内心的才行,并不是只有当别人会知道你拾金不昧的时候你才拾金不昧,当别人知道你除暴安良称你为英雄的时候你才会打抱不平,当别人可能会发觉你坑蒙拐骗的时候你才会诚实守信,当组织要评职称的时候你才爱岗敬业,如果是这样的话,那么你是自欺欺人,你内心不会认为自己拥有了道德,相反,你会觉得自己怎么这么龌龊。 假设因为物质而骄傲的人是第一种人,因为虚荣而骄傲的人是第二种人,因为道德而骄傲的人是第三种人。下面列几种情况。 当第一种人碰上了第一种人,那么一个人会充满羡慕,另一个人则洋洋得意。 当第一种人碰上了第二种人,那么第一种人仍然洋洋得意,而得到的却是第二种人的嗤之以鼻,因为第二种人会觉得自己追求荣誉比追求物质要高尚些,却不知追求虚荣同样是低级趣味。 当第一、第二种人碰上了第三种人,前两种人的盲目自信,只能使第三种人发出一声默默地叹息:教育还是如此的落后。 我们在生活中要看到自己属于哪一种人,看到自己的缺陷才有改正的机会,而改正了就是超越。 可能第一种人会问,为什么我有缺陷,是否因为我拥有物质而你没有,所以你会说道德比物质重要?第二种人会同样用此逻辑来解释,那么在他们眼里,追求道德的人反而成了骗子,有一种吃不着葡萄就说葡萄酸的感觉。 显然这是错误的逻辑,而这逻辑会随着时光的流逝而越来越显示出其巨大的错误,并导至以此逻辑生活的人会越来越追忆往昔的岁月,因为当物质充裕的时候,当青春年华不在的时候,他们发现后悔了,他们发现自己一生都在追求没用的东西。 那么用我自认为严谨的逻辑推理来驳倒上面的错误逻辑,也就是证明为什么以道德而骄傲才是正确的。 人活着是因为有追求,有追求才能活着,我说的活着不是肉体,而是精神。如果一个人没有了追求,那么即便你拥有什么,你都会找不到继续充满精力拼搏下去的理由,那如果这样,人生就已经失去了意义,剩下的只能是浑浑噩噩,养老至终了,一句话,没劲透了,那种感觉就像是你看完了一部精彩的电视剧,然后电视屏幕上就一直滚着字幕,而你还不得不看下去,直到你再也睁不开双眼去看了,谁能说这样还是很有劲呢。 如果同意这一点那么就接着说,如果想要持续不断精彩的人生,那么就需要永恒的追求,那么这部精彩的电视剧就会一直上演,同样直到你再也睁不开双眼去看了,那么什么能支撑起永恒的追求呢? 物质?幼稚!如果只是这样,你的追求可能因为某天不幸中了1000万的彩票而灰飞烟灭,直接奔电视剧结尾了,一辈子就这么完了。 虚荣?还是幼稚!想虚荣还不简单,管你在国内混成什么样,去外国呆两年,回来吹吹牛不就行了。吹吹牛,高兴一会,完了还能怎样呢?比上者好不到哪里去。仍然面对着浑浑噩噩,极度迷茫过完下半生的悲惨生活。 真正能托起永恒追求的是道德,因为有道德,你不再自私,当你不再自私,你会拥有解决不完的问题,你会永远活在追求理想的过程中,因为你希望世界一天天变的更美好。 “哈哈,总算被我猜到了吧,原来你所谓的追求道德,不也只是为了获得更大的好处吗?还说什么不自私。” 这的确能够得到更大的好处,但是这是以道德为前提的。莫非在你的逻辑里,只有天生喜欢遭罪的人才叫有道德吗?当每个人都有了不自私的追求,这样世界才会更美好。 那么可能会产生这样的想法,我为了追求这所谓的美好,然后去做一些符合道德的事情,做这些事情仅仅是为了得到美好的追求,如果是这样的话,就本末倒置了,因为你发自内心追求的仍然是自己的私利,而做一些形式上符合道德的事情,这样做事情是不会愉快的,这样的追求也是扭曲的,不自然的。 举个例子,就拿爱岗敬业来说吧,如果是一个真正具有道德的人,那么他会认为做好这件工作是自己的本分,可以对社会的进步起到力所能及的作用,所以这工作变成了一个积极的追求,每天很有激情的干着工作,并体会着工作带来的乐趣,很充实。 另一个干同样工作的人,只想着升官发财,并不爱岗敬业,所以每天工作懒散,工作对他没有任何乐趣,很颓废,看着上面那个人每天很充实很快乐,为了像他一样能够有些乐趣,所以他选择同样忙碌的工作,但是他却发现,他仍然不是很快乐,因为做这些事情和他升官发财没有任何关系。 所以是否做一个有道德,有骄傲感的人是自己内心所决定的,形式上是学不来的。如果想真正的拥有道德、骄傲继而拥有快乐,那么先虔诚的学会什么是道德——“不自私”,那么你就拥有足以让自己振奋一生的骄傲感。
Bochs基本命令
下断点:b 内存地址 如:b 0x07c00 就是设置一个断点 执行到断点:c 就是让CPU直接爽快点一次性执行到设置好的b断点(如0x07c00) 单步步过:n 查看寄存器:reg 这个的命令是r 查看段寄存器:sreg 这个只查看段寄存器,因此看不到ip寄存器 查看栈:print-stack
NASM命令
\续行符
第二天(10.16号)
41控制器
复习指引
这节就是 移动了几根电线,加了几个上升沿触发器(形成循环移位寄存器),从而实现了控制器的功能。。整个机器的作用和连续加法器的作用相同;本节的控制器使得我们操作起来比上节的连续相加器简单很多
你不需要知道内部的电路细节也不需要懂控制器的原理,你只需要知道什么是控制器,控制的百度百科的原理是什么,控制器的百度百科的作用是什么,循环移位寄存器是什么,循环移位的作用是什么;
控制器真值表不需要复习
如果很久以后你想彻底弄懂本节内容:你只要按照顺序一步步用模拟软件操作,并参考真值表。本节就很好懂
TIps
控制器的别名:译码器
本节主要内容
控制器原理
利用循环移位寄存器 传输门 还有一些开关来 实现我们的想要的功能
这仅仅是本节控制器的原理
瞄一眼
控制器作用
按照预定改变主电路或控制电路
本节的作用:本节的控制器使得我们操作起来比上节的连续相加器简单很多
控制器定义
官方版
控制器(英文名称:controller)是指按照预定顺序改变主电路或控制电路的接线和改变电路中电阻值来控制电动机的启动、调速、制动和反向的主令装置。由程序计数器、指令寄存器、指令译码器、时序产生器和操作控制器组成,它是发布命令的“决策机构”,即完成协调和指挥整个计算机系统的操作。
瞄一眼
通俗版
控制器通俗定义:把连续加法器的电路加入一个循环移位寄存器,然后几根电线稍微改一下,就叫控制器了
瞄一眼
循环移位寄存器
实现了一个比特位依次在多个上升沿D触发器中传递的效果
图示
瞄一眼
控制器图示
改装前图的控制器
瞄一眼
改装后图的控制器
瞄一眼
就是将循环移位寄存器(2个串联上升沿触发器)应用于连续加法器,从而起到优化的作用
需要改装的原因
电路实际上是有缺陷的。 比如,它总是让IGB和IRA同时为“1”,而后者必须必前者晚一点为“1”才能保证可靠性。 (否则RA的上升沿脉冲信号一旦过去,信号还没有传过来,这样子就无法成功保存到RA寄存器里面了。) 所以,还得再次改进电路以便能够实现“延迟一点变为1”。
瞄一眼
加法器的主要流程
装载
装载的过程就是把一个数导入到RA寄存器中
相加
相加的过程是,把一个数导入到加法器的加数输入端,并把计算结果最终再导入到RA寄存器中
具体操作
合上“K装载”就代表要装载一个数到寄存器RA中。 断开“K装载”,合上“K相加”,就表示要做加法了
(连续加法器的)控制器的真值表
真值表对应七大情况
以上只有2 4 5是真实操作步骤,分别对应第一步第二步第三步。其他的1 3 6 7全是Tips
57操作系统
复习题
复习指引
43连续读取存储器
复习题
连续读取存储器有哪些组件构成?各个组件的功能是什么?
升级版连续读取存储器有哪些组件构成?各个组件的功能是什么?
玩一下普通版和升级版连续读取存储器的模拟软件
复习指引
不用复习连续读取存储器的操作流程
复习这里即可
然后看一下图即可
普通版连续读取存储器
连续读取存储器图示
图示
图说明
图说明讲下图黄色字体 AC AR KRD DP部分
AC地址计数器
AR地址寄存器
DR数据寄存器
连续读取存储器原理
计数器+寄存器+存储器结合起来就做出来一个连续读取存储器了,很简单的
连续读取存储器操作流程
完整版描述
绝对绝对不用复习这个。。。这个不难 但是复习没意义
简单版描述
(1)按一下KAR,地址计数器AC当前的值0000被AR锁存,并提供给存储器。 (2)先按住KRD,不要松开,再按一下KDR,这时,数据输出,并被DR保存,最后,松开KRD。 (3)按一下KAC,地址计数器加一以指向下一个地址,为再次从存储器里读数据做准备。
升级版连续读取存储器(含控制器)
还记得 加法器,存储器我们都用控制器来优化电路吗? 这里也一样可以引进控制器
图示
本节控制器原理:循环移位存储器+取数译码器+普通连续读取存储器
本节控制器功能
把原来的电路图开关简化为一个。。。
流程原理
绝对绝对不用复习这个。。。这个不难 但是复习没意义
44半自动操作
复习指引
复习题
请描述一下半自动加法器的功能
人们如何操作半自动加法器?
右边这幅图对应的汇编代码是?
请描述右边这幅模拟器如何进行操作,以及他的效果?
复习指引
复习这些
半自动加法器工作原理不用复习
操作码不太容易忘记,不用复习
模拟指令计算机
K按一次执行一次,读一次,加一次,然后自动把指针移动到下一个存储单元。。
模拟软件图示
注意:图中的AC计数器指的是地址计数器,每次点击K AC计数器都会自动增加
这个模拟软件模拟如下流程
图
注意:2个存储内容代表一个指令,上面一条指令是操作符 下面一条指令是操作数
半自动加法器
半自动加法器功能
本机器大概能够实现这样代码的功能
本机器是半自动的,在for循环执行加法操作的时候要不停的按动开关K才行
这台机器的工作过程:你可以持续按动开关K,就可以实现从存储器里不断取数、然后相加的功能,直到所有的指令都执行完毕。
和以前的加法器的区别
本机器比之前的加法器先进很多,因为不需要算一次加法然后再输入一次被加数然后再算一次加法(而是实现一次性输入进去所有的操作符和操作数,然后躺在床上不停的按开关K即可)
冯.诺依曼重要的突破:我们实现存入RW存储器的即有操作符也有操作数
半自动加法器工作原理
操作码
操作码10010
操作码10010意味着,要相加的数位于下一个存储单元,并且把相加的结果再次保存到RA寄存器里。 ADD RA,5 = 10010 00101
操作码10001
操作码10001还意味着,被装载的数位于下一个存储单元里,目标是寄存器RA。 MOV RA,10 = 10001 01010
装载操作码默认对下一个存储单元操作
合体流程
有控制器组件的加法器
有控制器组件的连续读取存储器
将上面两张图合体,获得半自动加法器
45全自动计算
复习指引
看这张图就好了
知道全自动计算加法机=半自动加法机+振荡器+停机指令 就好
复习题
全自动计算加法机和半自动加法机的电路结构上的区别是什么?(两点)
1.振荡器
2译码器电路EC还能翻译出“停机指令”
全自动计算加法机为什么需要停机指令?
为了不让振荡器一直颠下去
振荡器和停机指令
停机指令 11111
振荡器的功能
使得半自动加法机进化为全自动,不需要人为按开关
停机指令的功能
停机指令工作原理
全自动计算加法机
全自动计算加法机的功能
就是这个
全自动计算加法机的原理
就是多了一个振荡器。。。
全自动的图示
46拓展MOC和ADD指令
复习题
立即数和非立即数的定义?
ADD [内存地址],立即数 是什么意思?
两个操作数的机器语言指令如何写?
请使用模拟软件 利用机器语言 连续运算 10+5+2+7+6
复习指引
本节复习只要做这个即可
关键是你要知道机器语言的执行顺序,他是逐个向下执行指令的
立即数和非立即数
立即数
第一条指令的操作码为10001,操作数是00110,表示要把数字00110装载到寄存器RA中。 一旦执行这条指令,寄存器RA里的数字就是00110,也就是十进制6。 换句话说,当该指令执行的时候,装载到寄存器RA中的数字直接来至于指令本身。 是该指令的的组成部分,可以从指令中立即得到,所以称为:立即数。
非立即数
MOV RA,01100
这条指令的操作数是01100,所以它指向存储器的另一个地址1100[12D],而这二个地址里面存放的数字是00101[5D]。 所以,当这条指令执行完毕之后,寄存器RA中的数字就是00101[5D]。
MOC和ADD具体指令
0x00=MOV RA,立即数 0x01=MOV RA,[内存地址] 0x02=MOV [内存地址],RA 0x03=MOV [内存地址],立即数 0x04=ADD RA,立即数 0x05=ADD RA,[内存地址] 0x06=ADD [内存地址],RA 0x07=ADD [内存地址],立即数
上面最前端的机器语言可能是错的(可能老师瞎编的)
具体解释
机器语言实战
机器语言实战1:基本MOC ADD指令的机器语言运算
放大一些就看清了
机器语言实战2:连续运算 10+5+2+7+6
47JMP指令
复习题
JMP 立即数 什么意思?
JMP [内存地址] 什么意思?
复习指引
本节不用复习 做这个复习题即可
JMP指令原理
当“译码器”发现JMP指令的时候,就把一个内存地址,直接传送给地址寄存器,从而改变了下一条指令的获取地址
指令集
0x08=JMP 立即数 修改地址寄存器 0x09=JMP RA 将RA的值赋值给IP地址寄存器 0x0A=JMP [内存地址] 将 [内存地址]的值赋值给IP地址寄存器
机器语言实战JMP指令
实战1:基本操作
实战2:死循环
48进制标志位
复习题
执行操作MOV [0x12345678],0x11223344会发生什么?为什么?
现代计算机中,存储单元为1个字节,也就是8个比特位。 一个内存地址中,只能存放1个字节,也就是8个比特位。
假设RA寄存器是一个8位寄存器,里面存放着一个1111 1111b 也就是0xFF。 这个时候,如果再让RA增加一个1会怎么样呢?
谁能影响标志寄存器CF字段?
ADD指令产生的进位(也就是最后一个全加器的进位在硬件电路中引入到图中CF的位置
MOV指令不行
INC和DEC指令也不行(记住就行)
请你在脑子里意淫一下标志寄存器的样子
JMP JB JNB的区别?
什么是数值溢出问题?
复习指引
复习箭头
复习箭头
寄存器RA的大小规则
一般情况下,一个操作码的其他操作数部分比特位数是一致的
繁琐的示例
特殊:MOV [0x12345678],0x11223344
系统会默认将此代码转为
MOV Byte [0x12345678],0x11 MOV Byte [0x12345679],0x22 MOV Byte [0x1234567A],0x33 MOV Byte [0x1234567B],0x44 或者也可以是 MOV Byte [0x12345678],0x44 MOV Byte [0x12345679],0x33 MOV Byte [0x1234567A],0x22 MOV Byte [0x1234567B],0x11
严格的写法应该是:MOV Dword [0x12345678],0x11223344
数值溢出问题(标志寄存器的CF字段)
回忆:在我学习深度学习的时候,深度学习圣经P52页数值上溢和下溢问题
在神经网络最后一层,为了防止数值溢出,同构softmax函数来稳定输出
图示
原理总结
8位加法器,如果被加数是1111 1111,加数是0000 0001 ,那么结果是:0000 0000
溢出的数据会被记录在标志寄存器的CF字段
数值下溢
代码
mov ax,0x0002 sub ax,1 sub ax,1 sub ax,1 输出结果:ax=0xFFFF (也就是0x0000-1=FFFF)
和数值上溢同理,发生借位也会让CF=1;
机器语言实战:进位标志位
标志寄存器
图示
CF字段
若存在进位则:CF=1。 若没有进位则:CF=0。
Tisp
他是16位的(别问为什么)
JB和JNB
JB机器语言实战演练
JNB的实战代码和JB相反,不再赘述
JMP JB JNB的区别
计算机只要执行JMP指令,就一定会发生跳转。所以,JMP指令也叫做(无条件跳转指令) 而JB则是检测到CF=1才会发生跳转,否则就会继续执行后面的指令。 JNB则是检测到CF=0才会发生跳转,否则就会继续执行后面的指令。
0x0B=JB 立即数 0x0C=JB RA 0x0D=JB [内存地址] 0x0E=JNB 立即数 0x0F=JNB RA 0x10=JNB [内存地址]
42存储器
复习题
32根地址引线 储存单元8bit的RAM容量有多大?
64根地址引线 储存单元8bit的RAM容量有多大?
请 看着单比特储存器的电路图,然后进行原理说明
如何做出一个地址译码器?
地址译码器功能?
玩模拟软件
复习指引
不要看这个
RAM:对于RAM,你只需要明白,这个东西工作的时候需要电,并且知道这个存储器有多少个地址,每个地址(存储单元)能保存几个比特位。 还能读入或者写出,就OK了,没必要再深究了。
地址译码器:你只要知道地址译码器就是一个控制器,他的功能和控制器类似
单比特储存器
电路图
图说明
G是传输门,R的输入控制G的开关;将R设置为1才能将Q的内容读入至DB
将W设置为1才能将DB的内容输入至Q(W控制着CP端)
图中的触发器是上升沿触发器
模拟软件图
抽象图
图说明
W=1 可以写入数据到DB
R=1 可以将DB的数据读出
W和R不能同时为1
存储器就像一个箱子一样,这个箱子有一个口,一次只能存入(写)或者取出(读)一个比特位。
为了讲解方便而诞生的储存器例子
多比特存储器(不适用地址译码器)
5比特单层图示
5比特多层图示
RAM
RAM通俗表达
RAM就是有地址译码器,然后叠加的很多层的储存器
地址译码器
地址译码器功能
通过指定一个地址,就可以从存储器的某个位置取出一个二进制数,或者写入一个二进制数
他的大大简化了电路 节约成本 提高效率
地址译码器就是一个控制器(还记得上节课说的控制器的别名吗?)
地址译码器介绍
新的逻辑电路图叫做“地址译码器”,我们通过A0和A1共同来指定一个楼层。 如果A1A0=00,表示当前准备读写第0层。 如果A1A0=11,表示当前准备读写第3层。 该逻辑电路还有一个R和W,表示指明对所选择的楼层进行何种操作,是读还是写
如何做出一个地址译码器?
一旦通过A0和A1给出一个存储单元的地址,那么,结合R和W的输入情况,就能得到另外一种形式的输出,使相应的单元开始读或者写。 这实际上就是一个转换或者翻译的过程,这就是为什么我们称之为“地址译码器”的原因。 构造地址译码器需要详细的定义一张符合其工作状态的表,并根据该表写出各项输出的逻辑表达式。 在本课程中,这个工作已经不止做了一次,再做一次已经没有必要。
举例类型1:4地址引线5BIT存器单元
电路图
图说明
上图中,楼层的顺序是0,1,2,3. 每个楼层都有自己的读线和写线,比如0层的读线是R0,写线是W0。 一层的读线是R1,写线是W1,其他各层以此类推。
地址仅仅是一个编号,一个门牌号码,它指向了存储器内部的一个小空间
多层结构的功能:允许指明把一个二进制数保存到第几层,或者从第几层读出来
整个操作过程 非常像电梯
16层楼,每层5个比特位
本图的存储器单元就是:5BIT。(相当于每层楼,住了几户比特位)
非常重要的一段话
直观上来说,这5个比特单元并排在一起,很像一层楼,而这一层楼可以保存一个5BIT的二进制数。 那么,如果我们盖两层楼,就可以保存两个5BIT的二进制数。 那如果是四层楼的话,同理得出,可以保存四个5BIT的二进制数。 这段话非常重要,在汇编语言和C/C++甚至以后很多知识中,我们还会提到上面这种抽象思维。 用楼层来想象计算机中的内存和硬盘结构。
抽象图
举例类型2:8bit储存单元
看图中棕色小格子为8个,说明储存单元为8bit(即每层楼8户人家)
64位和32位
图示
分析
32和64位差的是地址引线的数量,因此直接导致内存最大容量差距一倍
RAM特点分析
不管你访问哪个存储单元,所花的时间都是一样,和地址没有关系
正是因为这样,我们通常称之为“随机访问存储器”,或者“自由存储存储器
只要一断电,就全没了,因为属于易失性存储器
50集成电路
复习题
复习指引
51流水线和高速缓存
复习题
请描述一下,什么是CPU店长的故事?
请描述一下,什么是CPU策略-以空间换取时间?
什么是SRAM?
复习指引
复习这里
主板
通俗表达:主板就像是一个国家的铁路,公路,光缆等 CPU是插在主板上,就可以通过主板控制所有插到主板或者出厂的时候就和主板成为一体的元器件通信了。
CPU
CPU工作流程(非流水线)
CPU工作三个步骤
繁琐笔记PPT
繁琐的例子
假设取指令使用50皮秒,翻译指令使用50皮秒,执行指令使用50皮秒。 如果完整上述步骤一共需要振荡器发出10次脉冲信号即可,但振荡器速度太快,150皮秒振荡了100次脉冲信号。 对于CPU来说,除了10次脉冲信号,它确实做了一些事情,其他90次脉冲信号,都是没意义的,也就是说,你CPU速度再快,其他硬件的速度上不来。(还记得我们说过的木桶效应吧) 整体执行指令的性能还是无法提高上来。
CPU面临的问题:苦苦等待
CPU之被拖后腿定理
CPU的速度很快,尽管振荡器(时钟)的频率不能完全代表处理器的速度和性能
举例:每次你用U盘复制文件的时候,总能在屏幕上得到一个进度条,这不能怪处理器太慢,是你的U盘不够快
店长的故事
CPU就是店长
振荡器就是客人,一直在催
别的机器组件就像 厨师。。刀工。。端菜的人。。擦桌子的人
店长速度很快,但是厨师做饭很慢,店长要等厨师做好饭后才能让端菜的人端菜
等待的抽象图
解决策略之一:以空间换取时间
本来你打算申请1个字节的内存,但是操作系统分配给你一块大于1字节很多倍的内存,免得你不够用了,频繁申请,浪费时间
解决策略之二:高并发
把上面这三个步骤,隔离开,各自干各自的活
这个就是高并发技术啦。。我写过的分布式高并发爬虫就是这样的
超表量体系结构
允许在一个时钟周期内运行多条指令的结构
分支预测功能
SRAM
通俗表达:RAM内存可以理解是硬盘的缓存,SRAM又可以理解成RAM的缓存,缓存的目的都是为了能够尽量的提升和CPU交换数据的速度
通俗例子:SRAM一秒说80句话,CPU一秒说100句,RAM一秒说10句。。想象一下
52手机也是计算机
复习题
复习指引
54中断
复习题
复习指引
55键盘
复习题
复习指引
56显示器
复习题
复习指引
49计算机中的字节长
复习题
什么是计算机的字长?
复习指引
本节不用复习
如果你非要复习
小知识点
一般来说,存储器、寄存器和加法器具有相同的数据宽度。
例
比如数据线有8根,则存储器的每个存储单元包含8个比特,寄存器RA需要用8个上升沿D触发器来制造,而加法器,则必定是8个全加器组成。
现代的计算机都只有少量的寄存器可提供使用。
寄存器多了虽好,但这是增加计算机内部电路的复杂度为代价的
什么是计算机的字长?
通俗表达
32位 64位 这个叫字长
官方表达
字长表示一台计算机在一次操作中可以处理的二进制比特数。 换句话说,就是每个寄存器可以保存的二进制数是几个比特,或者加法器每次计算的二进制数是几个比特。
字长大的好处
一个字:快
例子
通俗例子
这就好比你每次只能扛50斤的东西,150斤的东西就得分三次扛走。 相反,要是你能扛150斤的东西,只要扛一次就够了
繁琐的例子
你想想,对于一个8位的计算机来说,它的加数和被加数都不能超过二进制1111 1111,也就是255D,这还没有考虑相加之后的结果可能超过8位,寄存器就放不下了。 当然,这也并不意味着8位的计算机就不能计算像1050 + 7000这样的数学题,只是有些麻烦。 但是,如果用一台字长为16位的计算机来做这道题,则只需要一次就可以完成。 重要的还不是计算过程,因为涉及访问存储器,两次访问存储器比只访问一次要花费成倍的时间。
触发器的变革
RS触发器
保存的过程很愚蠢
D触发器
他们都是保存一个比特位
第8章笔记
8.2.1 分段-段的汇编地址-段内汇编地址
复习题
如何在用户程序中分段?
分段的汇编地址和HJ局部标号是什么意思?
1千字节(kb)=1024字节(b)
1字节(b)=8比特(bit)
硬盘读取
从端口读用 in
写入端口用 out
8/3/5第一步和第二步没懂
Produce Return
过程返回
8.3.8
adc
例
比如:adc ax, bx ,实现的功能:(ax) =(ax) +(bx) +CF 例: mov ax, 2 mov bx, 1 sub bx, ax adc ax, 1 执行后,(ax) =4。adc执行时,相关于计算:(ax) +1 +CF =2 +1 +1 =4。 mov ax, 1 add ax, ax adc ax, 3 执行后,(ax) =5。adc执行时,相当于计算:(ax) +3 +CF =2 +3 +0 =5。
功能和语法
指令格式:adc 操作对象1, 操作对象2 功能:操作对象1 =操作对象1 +操作对象2 +CF