文章目录
汇编语言前置知识
汇编语言(英語:assembly language)是任何一种用于电子计算机、微处理器、微控制器,或其他可编程器件的低级语言。 在不同的设备中,汇编语言对应着不同的机器语言指令集。 一种汇编语言专用于某种计算机系统结构,而不像许多高级语言,可以在不同系统平台之间移植。
进制的运算
有符号数和无符号数
总位数一定是八位
有符号数规则:
最高位是符号位:1(负数),0(正数)
原码、反码和补码
原码:最高位符号位,对其他的位进行本身绝对值即可。
反码
- 正数:反码和原码相同
- 负数:符号位一定是1,其余位对原码取反
补码
- 正数:原码补码相同
- 负数:符号位一定是1,反码+1
位运算
-
与运算:两个都为1,结果才为1
-
或运算:两个都为0时结果才为0
-
异或运算:不同为1,相同为0
-
非运算
取反运算,0就是1 ,1就是0
1001001
0110110
- 位运算(移动位,左移*2,右移/2
左移:所有二进制位全部左移若干位,高位就丢弃了,低位补0
0000 0001
0000 0010
右移:所有二进制全部右移若干位,高位则丢弃,低位则补0
0000 0001
0000 0000
如果是正数则在第一位补0,是负数则第一位补1
位运算的加减乘除
加法
0000 0100
0000 0101
0000 1001
0加1为1,1+1向前进1
在计算机内,先异或,再进行与运算
1:异或,如果不考虑结果,异或就可以直接得出结果,因为有一个1,所以有进位
0000 0100
0000 0101
——————
0000 0001
2:与,如果结果为0则没有进位
0000 0100
0000 0101
——————
0000 0100
3:与有进位,所以需要将运算结果左移一位
0000 1000
4:异或:第一步的结果与我们与运算的结果继续异或
0000 0001
0000 1000
——————
0000 1001
5:要进行确认结果,则还要做一次与运算,如果结果为0,则没有进位
0000 0001
0000 1000
——————
0000 0000
则最终的结果就是第五步为0的结果,否则要继续做位运算与异或运算
减法
4+(-5)
1:先进行异或判断是否有进位
0000 0100
1111 1011
——————
1111 1111
2:进行与运算判断是否有进位
0000 0100
1111 1011
——————
0000 0000
没有结果,所以答案就为上一个结果1111 1111
乘除法
乘:x*y,就是y个x相加
除:x/y,本质是减法,就是x能减去多少个y
寄存器
存储数据:CPU>内存>硬盘
存值范围:0~FFFFFFFF
计算机如果要向寄存器存值则用到mov指令
可以将数字写入到寄存器,可以将寄存器的值写入到寄存器
32位 16位 8位
EAX AX AL
ECX CX CL
EDX DX DL
EBX BX BL
ESP SP AH
ENP NP CH
ESI SI DH
EDI DI BH
8位:L高8位,H低八位
内存
寄存器很小,不够用所以数据存放到内存中。
每个应用程序都有4GB的内存空间,空头支票
程序真正运行的时候才会用到物理内存。
1B=8bit
1KB = 1024B
1MB = 1024KB
1GB = 1024MB
给内存起的编号就是握矛盾内存地址 32位,8个16进制的值。
汇编语言的产生
机器指令:1000100111011000
操作:寄存器BX的内容送到AX中
汇编指令: MOV AX BX
寄存器:是CPU中可以存储数据的器件,一个CPU中有多个寄存器。
AX是其中一个寄存器的代号,BX是另一个寄存器的代号。
汇编语言的组成
1:汇编指令(机器码的助记符)
2:伪指令(由编译器执行)
3: 其他符号(由编译器识别)
存储器:
在一台PC机中内存的作用仅次于CPU
离开了内存 ,性能再好的CPU也无法工作。
磁盘不同于内存,磁盘上的数据或程序如果不读到内存中,就无法被CPU使用。
在内存或磁盘上,指令和数据没有任何区别,都是二进制信息。
二进制信息:
8 9 D 8(数据)
1000 1001 1101 1000
1000100111011000
MOV AX BX(程序)
存储单元
存储器被划分为若干个存储单元,每个存储单元从0开始编号:
例:一个存储器有128个存储单元,编号从0~127
当然也有如下单位:
1KB=1024B
1MB=1024KB
1GB=1024MB
1TB=1024GB
CPU对存储器的读和写:
CPU想要进行数据的读写,必须和外部器件(芯片)进行三类信息的交互
1:存储单元的地址(地址信息)
2:器件的选择,读或写命令(控制信息)
读或写的数据(数据信息)
CPU是通过什么将地址、数据和控制信息传到其他芯片中的呢?
回答电子计算机能处理、传输的信息都是电信号,电信号当然要用导线传送。
总线:在计算机中专门有连接CPU和其他芯片的导线,通常称为总线。
物理上:一根根导线的集合;
逻辑上划分为:地址总线,数据总线,控制
地址总线
CPU是通过地址总线来指定存储单元的。
地址总线上能传送多少个不同的信息,CPU就可以对多少个存储单元进行寻址。
一个CPU有N个地址总线,则可以说这个CPU的地址总线的宽度为N。
这样的CPU最多可以寻找2的N次方个内存单元(每个地址总线有0和1两种可能)
64位CPU代表一次可以走8个字节,bit是位,byte是字节。一个字节可以存放2的8次方个数据
数据总线
实现CPU与其他器件之间的数据传输
数据总线的宽度决定了CPU和外界的数据传送速度。
控制总线
CPU对外部器件的控制是通过控制总线来进行的。控制总线是一些不同控制线的集合。
有多少根控制总线,就意味着CPU提供了对外部器件的多少种控制。
内存地址空间
一个CPU的地址线宽度为10,那么可以寻址1024个内存单元,这1024个可寻到的内存单元就构成这个CPU的内存地址空间
主板:
在每一台PC机中,都有一个主板,主板上有核心器件和一些主要器件。
这些器件通过总线(地址总线、数据总线、控制总线)相连。
接口卡
CPU对外部设备不能直接进行控制,如显示器、音箱、打印机等。直接控制这些设备进行工作的是插在扩展插槽上的接口卡。
各类存储器芯片
从读和写属性上看分为两类:
随机存储器和只读存储器
从功能和连接上分类:
随机存储器RAM
装有BIOS的ROM
接口卡上的RAM
内存地址空间
寄存器(CPU)工作原理
一个典型的CPY由运算器、控制器、寄存器等器件组成,这些器件靠内部总线相连。
区别:内部总线实现CPU内部各个器件之间的联系,外部总线实现CPU和主板上其他器件的联系。
8086CPU有14个寄存器,它们的名称为:AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW。
8086CPU所有的寄存器都是16位的,可以存放两个字节。
AX、BX、CX、DX通常用来存放一般性数据被称为通用寄存器。
由于一个内存单元可以存放8位数据,CPU中的寄存器又可存放n个8位数据。。也就是说,计算机中的数据大多是由1~N个8位数据构成的。
几条汇编指令
测试
物理地址
CPU访问内存单元时要给出内存单元的地址。所有的内存单元构成的存储空间时一个一维的线性空间。我们将这个唯一的地址称为物理地址。
16位结构的CPU
1:运算器一次最多可以处理16位的数据。
2:寄存器的最大宽度为16位。
3:寄存器和运算器之间的通路是16位的。
8086CPU给出物理地址的方法
地址加法器工作原理
地址加法器合成物理地址的方法:
物理地址:段地址x16+偏移地址
段
其实内存并没有分段,段的划分来自于CPU,由于8086CPU用“(段地址x16)+偏移地址=物理地址”的方式给出内存单元的物理地址,使得我们可以用分段的方式来管理内存。
在编程时可以根据需要,将若干地址连续的内存单元看作一个段,用段地址X16定位段的起始地址(基础地址),用偏移地址定位段中的内存单元。
偏移地址为16位,16位地址的寻址能力为64k,所以一个段的长度最大为64k。
寻址能力
20根地址总线,寻址能力为2^20byte=1024kb;
段寄存器
段寄存器就是提供段地址的。
8086CPU有4个段寄存器:CS、DS、SS、ES:代码地址,数据地址,堆栈地址,辅助地址
当8086CPU要访问内存时由这4个段寄存器提供内存单元的段地址。
工作过程:
1:从CS:IP指向内存单元读取指令,读取的指令进入指令缓冲器;
2:IP=IP+所读取指令的长度,从而指向下一条指令;
3:执行指令,转到步骤1,重复这个过程。
8086CPU的工作过程
在8086CPU加电启动或复位后(即CPU刚开始工作时)CS和IP被设置为CS=FFFFH,IP=OOOOH.
即在8086PC机刚启动时,CPU从内存FFFFOH但愿你中读取指令执行。
FFFFOH单元中的指令是8086PC机开机后执行的第一条指令。
修改CSIP的指令
8086CPU 为CS、IP提供了另外的指令来改变它们的值:转移指令
同时修改CS、IP的内容
jmp段地址:偏移地址
jmp 2AE3:3:要跑到2AE33这个地址
jmp 3:OB 16
注:此处左为段地址,又为偏移地址,所以物理地址:段地址X16+偏移地址
所以为0B46
仅修改IP的内容
jmp某一合法寄存器
jmp ax
jmp bx
jmp bx表示修改ip的内容,ip改变也表示会跳到相应的ip地址去执行语句。
如果没有jmp,ip自己也会发生相应的改变去跳到下一个ip指到相应的指令。
代码段
可以将长度为N的一组代码,存在一组地址连续,起始地址为16的倍数的内存单元中,这段内存是用来存放代码的,从而定义了一个代码段。
如何使得代码段中的指令被执行呢?
CPU只认被CS:IP指向的内存单元中的内容为指令。
段地址在8086CPU的寄存器中存放。当8086CPU要访问内存时,由段寄存器提供的内存单元的段地址。8086有四个段寄存器,其中CS是用来存放指令的段地址。
CS存放指令的段地址,IP存放指令的偏移地址。
8086计算机中,任意时刻,CPU将CS:IP指向的内容当作指令执行。
练习题
4次两个mov是两次,然后跳到执行jmp的ip地址,最后执行ax这个ip地址
Debug
Debug是DOS、Windows都提供的实模式(8086方式)程序的调试工具。使用它,可以查看CPU各种寄存器中的内容、内存的情况和在机器码级跟踪程序的运行。
我们用到的Debug功能。
1:用Debug的R命令查看、改变CPU寄存器的内容。
2:用Debug的D命令查看内存中的内容
3:用Debug的E命令改写内存中的内容
4:用Debug中的U命令将内存中的机器指令翻译成汇编指令。
5:用Debug中的T命令执行一条机器指令
6:用Debug的A命令以汇编指令的格式在内存中写入一条机器指令。
debug程序安装文章地址:
汇编语言:Win10下的Debug配置_每天努力一点点-CSDN博客
将ax的值改为1111
来个小实验吧
d用来查看内存中的内容,我们看不懂DB 20 4E 05 16 14等,所以我们来把它转换成我们看得懂的汇编语言。
我们来观察执行命令时的cs与ip的变化
首先查看cs与ip的值
如果我们执行指令会执行 mov ax,4E20
下一条会执行指令add ax,1416
例2
![image-20210921095420237](https://i-blog.csdnimg.cn/blog_migrate/de1841a0d6d3feb52e6689d5f154eb94.png)
执行2000:0内存单元的指令,需要将cs改为2000,ip改为0
(1+1)8,4个t表示2的2次方,2的8次方需要16个t
256也就是0100,当ax为0100时终止
例3
ascII码表示十六进制的数字。
如何查看所有范围?加上ff
我们发现出现了日期,来对日期进行改变,往内存里写数据用e
将30改写为48,再查询结果
发现没有发生任何改变,因为这些数据是写在主板上的,只能读不能写。
因为有b810,往显存里写数据,所以出现了如图的图案
改变数据后图案的变化如下:
内存中字的存储
CPU 要读取一个内存单元的时候,必须先给出这个内存单元的地址;
在8086PC中,内存地址由段地址和偏移地址组成。
个t表示2的2次方,2的8次方需要16个t
256也就是0100,当ax为0100时终止
例3
[外链图片转存中…(img-wMMGIQuf-1632670208133)]
ascII码表示十六进制的数字。
如何查看所有范围?加上ff
[外链图片转存中…(img-ooa2rBXY-1632670208134)]
我们发现出现了日期,来对日期进行改变,往内存里写数据用e
[外链图片转存中…(img-2P8r3vTi-1632670208136)]
将30改写为48,再查询结果
[外链图片转存中…(img-UF4DoQ9r-1632670208137)]
发现没有发生任何改变,因为这些数据是写在主板上的,只能读不能写。
[外链图片转存中…(img-NI6bGckv-1632670208138)]
[外链图片转存中…(img-9PsEYaa1-1632670208141)]
因为有b810,往显存里写数据,所以出现了如图的图案
改变数据后图案的变化如下:
[外链图片转存中…(img-HLD6Jia7-1632670208142)]
内存中字的存储
CPU 要读取一个内存单元的时候,必须先给出这个内存单元的地址;
在8086PC中,内存地址由段地址和偏移地址组成。