EverydayOneCat
「筋トレ !!!!!!!!」——“宿舍里的宠物吃了我留下的蛋白粉”
一、基础知识
1.机器语言
机器语言是机器指令的集合。 机器指令展开来讲就是一台机器可以正确执行的命令。 电子计算机的机器指令是一列二进制数字。 计算机将之转变为一列高低电平, 以使计算机的电子器件受到驱动, 进行运算。
现在, 在我们常用的 PC机中,有一个芯片来完成上面所说的计算机的功能。 这个芯片就是我们常说的CPU(Central Processing Unit, 中央处理单元),CPU是一种微处理器。每一种微处理器都有自己的机器指令集, 也就是机器语言。
2.汇编语言
汇编语言的主体是汇编指令。汇编指令和机器指令的差别在千指令的表示方法上。汇编指令是机器指令便千记忆的书写格式。
汇编语言发展至今, 有以下3类指令组成:
(1)汇编指令:机器码的助记符, 有对应的机器码。
(2)伪指令:没有对应的机器码, 由编译器执行, 计算机并不执行。
(3)其他符号:如+、 -、 *、/等, 由编译器识别, 没有对应的机器码。
汇编语言的核心是汇编指令, 它决定了汇编语言的特性。
3.存储器
CPU是计算机的核心部件,它控制整个计算机的运作并进行运算。要想让个CPU工作,就必须向它提供指令和数据。指令和数据在存储器中存放,也就是我们平时所说的内存。在台PC机中内存的作用仅次千CPU。离开了内存,性能再好的CPU也无法工作。
4.指令和数据
指令和数据是应用上的概念。在内存或磁盘上,指令和数据没有任何区别,都是二进制信息。CPU在工作的时候把有的信息看作指令,有的信息看作数据,为同样的信息赋予了不同的意义。
例如,内存中的二进制信息I000100111011000,计算机可以把它看作大小为8908H的数据来处理,也可以将其看作指令movax,bx来执行。
1000100111011000 -> 89D8H (数据)
1000100111011000 -> mov ax, bx (程序)
5.存储单元
存储器被划分成若干个存储单元,每个存储单元从0开始顺序编号,例如个存储器有128个存储单元,编号从0~127。
那么一个存储单元能存储多少信息呢?我们知道电子计算机的最小信息单位是bit(音译为比特), 也就是一个二进制位。8 个bit 组成一个Byte, 也就是通常讲的一个字节。微型机存储器的存储单元可以存储一个Byte, 即8 个二进制位。一个存储器有128 个存储单元, 它可以存储128 个Byte。
微机存储器的容量是以字节为最小单位来计算的。对千拥有128个存储单元的存储器,我们可以说,它的容量是128个字节。
6.CPU对存储器的读写
CPU要想进行数据的读写, 必须和外部器件(标准的说法是芯片)进行下面3类信息的交互。
- 存储单元的地址(地址信息);
- 器件的选择, 读或写的命令(控制信息);
- 读或写的数据(数据信息)。
那么CPU是通过什么将地址、数据和控制信息传到存储器芯片中的呢?电子计算机能处理、传输的信息都是电信号, 电信号当然要用导线传送。在计算机中专门有连接CPU 和其他芯片的导线, 通常称为总线。总线从物理上来讲, 就是一根根导线的集合。根据传送信息的不同, 总线从逻辑上又分为3类, 地址总线、控制总线和数据总线。
7.地址总线
CPU是通过地址总线来指定存储器单元的。 可见地址总线上能传送多少个不同的信息, CPU就 可以对多少个存储单元进行寻址。
现假设, 一个CPU有10根地址总线, 让我们来看 下它的寻址情况。 我们知道, 在电子计算机中, 一根导线可以传送的稳定状态只有两种, 高电平或是低电平。 用二进制表 示就是1 或 0, 10根导线可以传送10位二进制数据。 而10位二进制数可以表示多少个不同的数呢? 2的10次方个。 最小数为0, 最大数为1023。
一个CPU有N根地址线, 则可以说这个CPU 的地址总线的宽度为N 。这样的CPU最多可以寻找2的N次方个内存单元。
8.数据总线
CPU 与内存或其他器件之间的数据传送是通过数据总线来进行的。数据总线的宽度决定了CPU 和外界的数据传送速度。8 根数据总线一次可传送一个8 位二进制数据(即一个字节)。16 根数据总线一次可传送两个字节。
9.控制总线
CPU 对外部器件的控制是通过控制总线来进行的。在这里控制总线是个总称, 控制总线是一些不同控制线的集合。有多少根控制总线, 就意味着CPU 提供了对外部器件的多少种控制。所以, 控制总线的宽度决定了CPU 对外部器件的控制能力。
10.主板和接口卡
在每一台PC机中,都有一个主板, 主板上有核心器件和一些主要器件, 这些器件通过总线(地址总线、数据总线、控制总线)相连。这些器件有CPU、存储器、外围芯片组、扩展插槽等。扩展插槽上一般插有RAM 内存条和各类接口卡。
计算机系统中, 所有可用程序控制其工作的设备, 必须受到CPU的控制。CPU对外部设备都不能直接控制, 如显示器、音箱、打印机等。直接控制这些设备进行工作的是插在扩展插槽上的接口卡。扩展插槽通过总线和CPU相连,所以接口卡也通过总线同CPU相连。CPU可以直接控制这些接口卡, 从而实现CPU对外设的间接控制。简单地讲, 就是CPU通过总线向接口卡发送命令, 接口卡根据CPU的命令控制外设进行工作。
11.内存地址空间
一台PC机中, 装有多个存储器芯片, 这些存储器芯片从物理连接上看是独立的、不同的器件。从读写属性上看分为两类: 随机存储器(RAM)和只读存储器(ROM)。随机存储器可读可写, 但必须带电存储, 关机后存储的内容丢失; 只读存储器只能读取不能写入,关机后其中的内容不丢失。
上述的那些存储器, 在物理上是独立的器件, 但是在以下两点上相同。
• 都和CPU的总线相连。
• CPU对它们进行读或写的时候都通过控制线发出内存读写命令。
这也就是说, CPU在操控它们的时候, 把它们都当作内存来对待, 把它们总的看作一个由若干存储单元组成的逻辑存储器, 这个逻辑存储器就是我们所说的内存地址空间。在汇编这门课中, 我们所面对的是内存地址空间。
12.小结
(1)汇编指令是机器指令的助记符, 同机器指令一一对应。
(2)每一种CPU都有自己的汇编指令集。
(3)CPU可以直接使用的信息在存储器中存放。
(4)在存储器中指令和数据没有任何区别, 都是二进制信息。
(5)存储单元从零开始顺序编号。
(6)一个存储单元可以存储8个bit, 即8位二进制数。
(7) 1Byte=8bit 1KB=l024B 1MB= 1024KB. 1GB= 1024MB。
(8)每一个CPU芯片都有许多管脚,这些管脚和总线相连。也可以说,这些管脚引出总线。一个CPU可以引出3种总线的宽度标志了这个CPU的不同方面的性能:
地址总线的宽度决定了CPU的寻址能力;
数据总线的宽度决定了CPU与其他器件进行数据传送时的一次数据传送量;
控制总线的宽度决定了CPU对系统中其他器件的控制能力。
13.习题
(1)1个CPU的寻址能力为8KB,那么它的地址总线的宽度为 13位。
2^13=8000
(2)1KB的存储器有 1024 个存储单元,存储单元的编号从 0 到 1023 。
一个存储单元就是1byte=8bit
(3)1KB的存储器可以存储 8192(2^13) 个bit, 1024个Byte。
(4)1GB是 1073741824 (2^30) 个Byte、1MB是 1048576(2^20) 个Byte、1KB是 1024(2^10)个Byte。
(5)8080、8088、80296、80386的地址总线宽度分别为16根、20根、24根、32根,则它们的寻址能力分别为: 64 (KB)、 1 (MB)、 16 (MB)、 4 (GB)。
一根就代表可以传一位二进制数据,16根就是16位,2^16=64*1024及64kb
(6)8080、8088、8086、80286、80386的数据总线宽度分别为8根、8根、16根、16根、32根。则它们一次可以传送的数据为: 1 (B)、 1 (B)、 2 (B)、 2 (B)、 4 (B)。
8 根数据总线一次可传送一个8 位二进制数据,(即一个字节1b)
(7)从内存中读取1024字节的数据,8086至少要读 512 次,80386至少要读 256 次。
(8)在存储器中,数据和程序以 二进制 形式存放。
二、寄存器(CPU工作原理)
一个典型的CPU由运算器、控制器、寄存器(CPU工作原理)等器件构成, 这些器件靠内部总线相连。在CPU中:
- 运算器进行信息处理;
- 寄存器进行信息存储;
- 控制器控制各种器件进行工作;
- 内部总线连接各种器件, 在它们之间进行数据的传送。
不同的CPU,寄存器的个数、结构是不相同的。8086CPU有14个寄存器, 每个寄存器有一个名称。这些寄存器是: AX、BX、EX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。
1.通用寄存器
8086CPU 的所有寄存器都是16 位的, 可以存放两个字节。AX、BX、EX、DX这4个寄存器通常用来存放一般性的数据, 被称为通用寄存器。
8086CPU 的上一代CPU中的寄存器都是8位的, 为了保证兼容, 使原来基于上代CPU编写的程序稍加修改就可以运行在8086 之上, 8086CPU的AX、BX、EX、DX这4个寄存器都可分为两个可独立使用的8位寄存器来用:
AX 可分为AH 和AL;BX 可分为BH 和BL;EX 可分为CH 和CL;DX 可分为DH 和DL。
AX 的低8 位(0 位~7 位)构成了AL 寄存器, 高8 位(8 位~15 位)构成了AH 寄存器。AH 和AL 寄存器是可以独立使用的8 位寄存器。
一个16位寄存器所能存储的数据的最大值为多少?——2^16-1
一个8位寄存器所能存储的数据的最大值为多少?——2^8-1
2.字在寄存器中的存储
出千对兼容性的考虑, 8086CPU 可以一次性处理以下两种尺寸的数据。
字节: 记为byte, 一个字节由8个bit组成, 可以存在8位寄存器中。
字: 记为word, 一个字由两个字节组成, 这两个字节分别称为这个字的高位字节和低位字节。
一个字型数据20000, 存在AX寄存器中, 在AH中存储了它的高8位, 在AL中存储了它的低8位。AH和AL中的数据, 既可以看成是一个字型数据的高8 位和低8 位, 这个字型数据的大小是20000; 又可以看成是两个独立的字节型数据, 它们的大小分别是78 和32。
3.几条汇编指令
汇编语言不区分大小写
解题1:
程序段中的最后一条指令add ax,bx, 在执行前ax和bx中的数据都为8226H, 相加后所得的值为: 1 044CH, 但是ax为16位寄存器,只能存放4位十六进制的数据, 所以最高位的1不能在ax中保存,ax中的数据为:044CH。
解题2:
其中al就是低位(后两位),ah就是高位(前两位)
程序段中的最后一条指令add al,93H, 在执行前,al中的数据为C5H, 相加后所得的值为:158H, 但是al为8位寄存器,只能存放两位十六进制的数据, 所以最高位的l丢失, ax中的数据为:0058H。
注:这里的丢失,指的是进位值不能在8位寄存器中保存,但是CPU并不真的丢弃这个进位值,我们以后会详细讨论
在进行数据传送或运算时, 要注意指令的两个操作对象的位数应当是一致的,反面教材:
错误的原因都是指令的两个操作对象的位数不一致
4.习题1~3
写出每条汇编指令执行后相关寄存器中的值。
1 | mov ax,62627 AX=F4A3H |
只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。
1 | mov ax,2 AX=2 |
5.物理地址和16位CPU
我们知道,CPU访问内存单元时,要给出内存单元的地址,所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有唯一的地址,我们见这个唯一的地址成为物理地址。
CPU通过地址总线送入存储器的,必须是一个内存单元的物理地址。先要在内部生成这个物理地址。
6.8086CPU给出物理地址的方法
8086CPU 相关部件的逻辑结构图:
当8086CPU 要读写内存时:
(l) CPU 中的相关部件提供两个16 位的地址, 一个称为段地址, 另一个称为偏移地址;
(2)段地址和偏移地址通过内部总线送入一个称为地址加法器的部件;
(3) 地址加法器将两个16 位地址合成为一个20 位的物理地址;
(4) 地址加法器通过内部总线将20 位物理地址送入输入输出控制电路;
(5) 输入输出控制电路将20 位物理地址送上地址总线;
(6) 20 位物理地址被地址总线传送到存储器。
地址加法器采用 物理地址=段地址x16+偏移地址 的方法用段地址和偏移地址合成物理地址。
“段地址xl6” 有一个更为常用的说法是左移4 位。计算机中的所有信息都是以二进制的形式存储的, 段地址当然也不例外。机器只能处理二进制信息, “左移4位” 中的位, 指的是二进制位。
(1) 一个数据的二进制形式左移1 位, 相当千该数据乘以2:
(2) 一个数据的二进制形式左移N 位, 相当于该数据乘以2 的N 次方;
(3) 地址加法器如何完成段地址xl6 的运算?就是将以二进制形式存放的段地址左移4 位。
一个数据的十六进制形式左移1 位, 相当于乘以16; 一个数据的十进制形式左移1 位, 相当千于乘以10; 一个x 进制的数据左移1位, 相当于乘以X 。
"段地址xl6+偏移地址=物理地址” 的本质含义是: CPU 在访问内存时, 用一个基础地址(段地址xl6)和一个相对千基础地址的偏移地址相加, 给出内存单元的物理地址。
7.段的概念
在编程时可以根据需要,将若干地址连续的内存单元看作一个段,用段地 址xl6定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。有两点需要注意:段地址*16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;偏移地址 为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB
CPU访问内存单元时,必须向内存提供内存单元的物理地址。8086CPU在内部用段地址和偏移地移位相加的方法形成最终的物理地址。
结论:CPU可以用不同的段地址和偏移地址形成同一个物理地址
+++
如果给定一个段地址,仅通过变化偏移地址来进行寻址, 最多可定位多少个内存单元?
结论:偏移地址16位, 变化范围为0-FFFFH, 仅用偏移地址来寻址最多可寻64KB个内存单元。比如给定段地址1000H, 用偏移地址寻址,CPU的寻址范围为:lOOOOH-lFFFFH。
“ 数据在21F60H内存单元中。” 这句话对于8086PC机一般不这样讲,取而代之的是两种类似的说法: 1、数据存在内存2000:1F60单元中;2、数据存在内存的2000H段中的1F60H单元中。这两种描述都表示“ 数据在内存21F60H单元中” 。
8.习题5~7
给定段地址为0001H,仅通过变化偏移地址寻址,CPU的寻址范围为 0010H 到 1000FH 。
解题过程:
物理地址=SA*16+EA
EA的变化范围为0h~ffffh 物理地址范围为(SA16+0h)~(SA16+ffffh)
现在SA=0001h,那么寻址范围为 (0001h16+0h)~(0001h16+ffffh) =0010h~1000fh
有一数据存放在内存20000H单元中,现给定段地址为SA,若想用偏移地址寻到此单元。则SA应满足的条件是:
最小为 1001H ,最大为 2000H 。
物理地址=SA*16+EA
20000h=SA*16+EA SA=(20000h-EA)/16=2000h-EA/16
EA取最大值时,SA=2000h-ffffh/16=1001h,SA为最小值
EA取最小值时,SA=2000h-0h/16=2000h,SA为最大值
9.段寄存器
我们前面讲到, 8086CPU 在访问内存时要由相关部件提供内存单元的段地址和偏移地址, 送入地址加法器合成物理地址。这里, 需要看一下,是什么部件提供段地址。段地址在8086CPU 的段寄存器中存放。8086CPU有4 个段寄存器: CS、DS、SS、ES。当8086CPU要访问内存时由这4个段寄存器提供内存单元的段地址。
10.CS和IP
CS 和IP是8086CPU中两个最关键的寄存器, 它们指示了CPU当前要读取指令的地址。CS 为代码段寄存器,IP为指令指针寄存器。
在8086PC 机中, 任意时刻, 设CS 中的内容为M, IP中的内容为N, 8086CPU将从内存Mx16+N单元开始,读取一条指令并执行。也可以这样表述:8086机中, 任意时刻, CPU将CS:IP指向的内容当作指令执行。
8086CPU 的工作过程可以简要描述如下:
(1) 从CS:IP 指向的内存单元读取指令, 读取的指令进入指令缓冲器;
(2) IP=IP+所读取指令的长度, 从而指向下一条指令;
(3) 执行指令。转到步骤(1), 重复这个过程。
在8086CPU 加电启动或复位后(即CPU 刚开始工作时)CS 和lP 被设置为CS=FFFFH, IP= OOOOH, 即在8086PC 机刚启动时, CPU 从内存FFFFOH 单元中读取指令执行, FFFFOH 单元中的指令是8086PC 机开机后执行的第一条指令。
问:CPU根据什么将内存中的信息看作指令?
答:CPU 将CS:IP 指向的内存单元中的内容看作指令, 因为, 在任何时候, CPU 将CS 、IP 中的内容当作指令的段地址和偏移地址, 用它们合成指令的物理地址, 到内存中读取指令码, 执行。如果说, 内存中的一段信息曾被CPU 执行过的话, 那么, 它所在的内存单元必然被CS:IP 指向过。
11.修改CS、IP的指令
在CPU 中, 程序员能够用指令读写的部件只有寄存器, 程序员可以通过改变寄存器中的内容实现对CPU 的控制。CPU 从何处执行指令是由CS 、IP 中的内容决定的, 程序员可以通过改变CS 、IP 中的内容来控制CPU 执行目标指令。
8086CPU 为CS 、IP 提供了另外的指令来改变它们的值。能够改变CS 、IP 的内容的指令被统称为转移指令。我们现在介绍一个最简单的可以修改CS 、IP 的指令: jmp指令。
(1)若想同时修改CS 、IP 的内容, 可用形如“jmp段地址: 偏移地址” 的指令完成, 如
jmp 2AE3:3, 执行后: CS=2AE3H, IP =0003H, CPU 将从2AE33H 处读取指令。
jmp 3:0B16, 执行后: CS=0003H, lP=OB16H, CPU 将从00B46H 处读取指令。
“jmp 段地址: 偏移地址” 指令的功能为: 用指令中给出的段地址修改cs, 偏移地址修改IP。
jmp 3:0186 在含义上好似mov CS,3 mov IP,O1B6。
(2)若想仅修改1P 的内容, 可用形如“jmp 某一合法寄存器” 的指令完成, 如
jmp ax, 指令执行前: ax=1OOOH, CS=2000H, IP=0003H 指令执行后: ax=1OOOH, CS=2000H, IP=1OOOH
“jmp 某一合法寄存器” 指令的功能为: 用寄存器中的值修改IP。jmp ax, 在含义上好似: mov IP,ax。
12.代码段
前面讲过, 对于8086PC 机, 在编程时, 可以根据需要, 将一组内存单元定义为一个段。我们可以将长度为N(N64KB)的一组代码, 存在一组地址连续、起始地址为16 的倍数的内存单元中, 我们可以认为, 这段内存是用来存放代码的, 从而定义了一个代码段。
长度为10 个字节的指令, 存放在123BOH~123B9H 的一组内存单元中, 我们就可以认为, 123BOH~123B9H 这段内存是用来存放代码的, 是一个代码段, 它的段地址为123BH, 长度为10 个字节。
将一段内存当作代码段, 仅仅是我们在编程时的一种安排, CPU 并不会由于这种安排, 就自动地将我们定义的代码段中的指令当作指令来执行。CPU 只认被CS:IP 指向的内存单元中的内容为指令。所以, 要让CPU 执行我们放在代码段中的指令, 必须要将CS:IP 指向所定义的代码段中的第一条指令的首地址。我们将一段代码存放在123BOH~123B9H 内存单元中, 将其定义为代码段, 如果要让这段代码得到执行, 可设CS=123BH、IP=OOOOH。
13.习题9~12
下面的3条指令执行后,cpu几次修改IP?都是在什么时候?最后IP中的值是多少?
1 | mov ax,bx |
答:一共修改四次
第一次:读取mov ax,bx之后
第二次:读取sub ax,ax之后
第三次:读取jmp ax之后
第四次:执行jmp ax修改IP
最后IP的值为0000H,因为最后ax中的值为0000H,所以IP中的值也为0000H
三、实验——Debug的使用
1.win10环境下如何运行debug
这里需要注意:debug.exe是可执行文件,直接下载不需要安装的,但是需要注意保存路径,因为等下配置的时候需要用到。为了方便一点可以直接在D盘根目录下新建一个Debug文件夹(文件夹名字随意),然后把刚下载的debug.exe放置到此目录D:\Debug。
挂载debug:
打开提示的文件,拉到最下面,加入如下语句(MOUNT是挂载,C是参数,D:\Debug是debug.exe存放的文件夹路径):
MOUNT C D:\Debug
C:
debug
2.常用命令
查看、修改CPU中寄存器的内容: R命令
查看内存中的内容: D命令
修改内存中的内容: E命令(可以写入数据、指令, 在内存中, 它们实际上没有区别)
将内存中的内容解释为机器指令和对应的汇编指令: U命令
执行CS:IP指向的内存单元处的指令: T命令
以汇编指令的形式向内存中写入指令: A命令
结语
就这样草率收场吧。玩好了游戏啥都不想干,哎!不过LOL炸鱼塘真滴好玩😁