笔者为了更好了解计算机的架构,深入学习linux,操作系统,选择学习汇编语言第三版(王爽),故记录一些笔记。
目录
一、基础知识
1.存储单元
存储器被划分成若干个存储单元,每个存储单元从0开始顺序编号,例如一个存储器有128个存储单元,编号从0~127。
电子计算机的最小信息单位是 bit,也就是一个二进制位。8个bit组成一个Byte,也就是一个字节。微型机存储器的存储单元可以存储一个 Byte,即8个二进制位。一个存储器有128个存储单元,它可以存储128个 Byte。
2.CPU 对存储器的读写
CPU 要从内存中读数据,首先要指定存储单元的地址。另外,在一台微机中,不只有存储器这一种器件。CPU 在读写数据时还要指明要对哪一个器件进行哪种操作,是从中读出数据,还是向里面写入数据。
所以CPU 要想进行数据的读写,必须和外部器件(标准的说法是芯片)进行3类信息的交互:
1.存储单元的地址(地址信息);
2.器件的选择,读或写的命令(控制信息);
3.读或写的数据(数据信息)。
CPU 和其他芯片的导线,通常称为总线。总线从物理上来讲,就是一根根导线的集合。根据传送信息的不同,总线从逻辑上又分为3类,地址总线、控制总线和数据总线。
3.地址总线
一个CPU有N根地址线,则可以说这个CPU的地址总线的宽度为N。这样的CPU最多可以寻找2的N次方个内存单元。 最多可以寻找2的N次方个内存单元.
4.数据总线
数据总线的宽度决定了CPU和外界的数据传送速度。8根数据总线一次可传送一个8位二进制数据(即一个字节)。
5.控制总线
控制总线是个总称,控制总线是一些不同控制线的集合。有多少根控制总线,就意味着CPU 提供了对外部器件的多少种控制。所以,控制总线的宽度决定了CPU对外部器件的控制能力。其中有一根称为“读信号输出”的控制线负责由CPU向外传送读信号,CPU向该控制线上输出低电平表示将要读取数据;有一根称为“写信号输出”的控制线则负责传送写信号。
6.内存地址空间
一台PC机中,装有多个存储器芯片,这些存储器芯片从物理连接上看是独立的、不同的器件。从读写属性上看分为两类:随机存储器(RAM)和只读存储器(ROM)。随机存储器可读可写,但必须带电存储,关机后存储的内容丢失;只读存储器只能读取不能写入,关机后其中的内容不丢失。
小结
(1)汇编指令是机器指令的助记符,同机器指令一一对应。
(2)每一种 CPU都有自己的汇编指令集。
(3) CPU可以直接使用的信息在存储器中存放。
(4)在存储器中指令和数据没有任何区别,都是二进制信息。
(5)存储单元从零开始顺序编号。
(6)一个存储单元可以存储8个 bit,即8位二进制数。
(7) 1Byte=8bit 1KB=1024B 1MB=1024KB 1GB=1024MB.
(8)每一个CPU芯片都有许多管脚,这些管脚和总线相连。也可以说,这些管脚引出总线。一个CPU可以引出3种总线的宽度标志了这个CPU的不同方面的性能。
检测点
(1)log2(8*1024)=13 (2)1024 0 1023 (3)1024*8 1024
(4)1073741824 1048576 1024 (5)64KB 1MB 16MB 4GB
(6)1 1 2 2 4 (7)512 256 (8)二进制
二、寄存器
一个典型的CPU(此处讨论的不是某一具体的 CPU)由运算器、控制器、寄存器(CPU工作原理)等器件构成,这些器件靠内部总线相连。前一章所说的总线,相对于CPU内部来说是外部总线。内部总线实现CPU内部各个器件之间的联系,外部总线实现CPU和主板上其他器件的联系。简单地说,在CPU 中:运算器进行信息处理;寄存器进行信息存储;控制器控制各种器件进行工作。
CPU 中的主要部件是寄存器。寄存器是CPU 中可以用指令读写的部件。改变各种寄存器中的内容实现对CPU的控制。
1.汇编指令
汇编指令 控制CPU完成的操作 用高级语言描述
mov ax,18 将18送入寄存器AX AX=18
mov ah,78 将78送入寄存器AH AH=78
add ax,8 寄存器AX中的数值加8 AX=AX+8
mov ax,bx 寄存器BX中的数据送入AX AX=BX
add ax,bx AX和BX中的数值相加,结果存在AX AX=AX+BX
注:汇编指令和寄存器名称不区分大小写,在进行数据传送或运算时,要注意指令的两个操作对象的位数应当是一致的。
练习
只能使用目前学过的汇编指令,最多使用4条指令,编程计算2的4次方。
mov ax,2
add ax,ax
add ax,ax
add ax,ax
2.8086CPU给出物理地址的方法
8086CPU有20位地址总线,可以传送20位地址,达到1MB寻址能力,8086CPU又是16位结构,在内部一次性处理、传输、暂时存储的地址为16位。从8086CPU 的内部结构来看,如果将地址从内部简单地发出,那么它只能送出16 位的地址,表现出的寻址能力只有64KB。8086CPU 采用一种在内部用两个16位地址合成的方法来形成一个20位的物理地址。
段地址x16其实就是将段地址左移四位。
3.段的概念
段的划分来自于CPU,8086CPU用“基础地址(段地址x16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。我们可以认为:地址10000H~100FFH 的内存单元组成一个段,该段的起始地址(基础地址)为10000H,段地址为1000H,大小为100H;我们也可以认为地址10000H~1007FH、10080H~100FFH 的内存单元组成两个段,它们的起始地址(基础地址)为:10000H和10080H,段地址为:1000H和1008H,大小都为80H.
编程时可以根据需要,将若干地址连续的内存单元看作一个段,用段地址x16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。有两点需要注意:段地址x16必然是16的倍数,所以一个段的起始地址也一定是16的倍数;偏移地址为16位,16位地址的寻址能力为64KB,所以一个段的长度最大为64KB。
“数据在21F60H 内存单元中。”这句话对于8086PC机一般不这样讲,取而代之的是两种类似的说法:①数据存在内存 2000:1F60单元中;②数据存在内存的2000H 段中的1F60H单元中。这两种描述都表示“数据在内存21F60H单元中”。
4.CS和IP
CS 和 IP是8086CPU 中两个最关键的寄存器,它们指示了CPU当前要读取指令的地址。CS为代码段寄存器,IP为指令指针寄存器。
在8086PC机中,任意时刻,设CS 中的内容为M,IP 中的内容为N,8086CPU将从内存Mx16+N单元开始,读取一条指令并执行。
8086CPU的工作过程可以简要描述如下,(1)从 CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;(2)IP=IP+所读取指令的长度,从而指向下一条指令;(3)执行指令。转到步骤(1),重复这个过程。
在8086CPU上电启动或复位后(即CPU刚开始工作时)CS和 IP被设置为CS=FFFFH,IP=0000H,即在8086PC机刚启动时,CPU从内存 FFFFOH单元中读取指令执行,FFFFOH单元中的指令是8086PC机开机后执行的第一条指令。
修改AX中的值可以用mov指令,8086CPU 大部分寄存器的值,都可以用mov指令来改变,mov指令被称为传送指令。
但mov指令不能用于设置CS、IP的值,因为8086CPU没有提供这样的功能。8086CPU为CS、IP 提供了另外的指令来改变它们的值。能够改变CS、IP的内容的指令被统称为转移指令。
若想同时修改CS、IP的内容,可用形如“jmp段地址:偏移地址”的指令完成,如jmp 2AE3:3,执行后:CS=2AE3H,IP=0003H,CPU将从2AE33H处读取指令。jmp 3:0B16,执行后:CS=0003H,IP=0B16H,CPU将从00B46H 处读取指令。“jmp段地址:偏移地址”指令的功能为:用指令中给出的段地址修改CS,偏移地址修改IP。
若想仅修改IP的内容,可用形如“jmp 某一合法寄存器”的指令完成,jmp ax,指令执行前:ax=1000H,CS=2000H,IP=0003H,指令执行后: ax=1000H,CS=2000H,IP=1000H,“jmp 某一合法寄存器”指令的功能为:用寄存器中的值修改IP。jmp ax,在含义上好似: mov IP,ax。
小结
(1)段地址在 8086CPU 的段寄存器中存放。当8086CPU 要访问内存时,由段寄存器提供内存单元的段地址。8086CPU有4个段寄存器,其中CS用来存放指令的段地址。
(2) CS存放指令的段地址,IP存放指令的偏移地址。8086机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。
(3) 8086CPU 的工作过程:1.从CS:IP指向的内存单元读取指令,读取的指令进入指令缓冲器;2.IP指向下一条指令;3.执行指令。(转到步骤①,重复这个过程。)
(4) 8086CPU提供转移指令修改CS、IP的内容。
检测点
(1)00010H 1000FH (2)1001H 2000H <1001H || >2000H
(3) mov ax,6622H (4)一次
jmp 1000:3 jmp ax
mov ax,0000 0
mov bx,ax
jmp bx
mov ax,0123H
......
实践
用Debug 的R命令查看、改变CPU寄存器的内容;用Debug的D命令查看内存中的内容;用Debug 的E命令改写内存中的内容;用Debug 的U命令将内存中的机器指令翻译成汇编指令;用Debug 的T命令执行一条机器指令;用Debug 的A命令以汇编指令的格式在内存中写入一条机器指令。
进入 Debug
Debug是在 DOS方式下使用的程序。我们在进入 Debug前,应先进入到DOS方式。用以下方式可以进入 DOS。
1.重新启动计算机,进入DOS方式,此时进入的是实模式的DOS。
2.在 Windows中进入DOS方式,此时进入的是虚拟8086模式的 DOS下面说明在 Windows 2000中进入 Debug 的一种方法,在其它Windows系统中进入方法类似。
注意64位的 Windows 11 系统无法直接使用 16 位的 Debug 工具。所以我们需要下载debug和下载DOSBox。下载完成后,进入以下界面。
我们可以用r命令查看改变cpu寄存器的内容。
其中CS=073F,IP=0100,说明内存0CA2:0100处的指令为CPU当前读取执行的指令。
若要修改一个寄存器中的值,比如AX中的值,可用R命令后加寄存器名来进行,输入“r ax”后按 Enter 键,将出现“:”作为输入提示,在后面输入要写入的数据后按Enter 键,即完成了对AX 中内容的修改。若想看一下修改的结果,可再用R命令查看。