汇编语言---从入门到精通
在上述汇编指令中,最后一条指令的计算add al,93H,在执行前al中数据为C5H,相加之后的值为158H,al寄存器是8位寄存器,只能存放两位16进制的数据,所以最高位的1丢失,ax的数据位为0058H,注意,此时al作为一个独立的8位寄存器来使用,和ah没有关系,对于一个计算机来讲,其内部的存储器有多个,每个的功能都是不同的在物理上来说也都是独立的器件,但是对于CPU来讲系统中的所有存储器中
一、基础知识
1.1机器、汇编与高级语言
机器语言是机器指令的合集,电子计算机的机器指令是一列二进制数字,计算机将其转变为高低电平,早期的程序设计使用的是机器语言,程序员用0和1进行编程。
汇编语言,汇编语言的主体是汇编指令,汇编指令和机器指令的区别是在于指令的表示方法,汇编指令是机器指令便于记忆的书写格式。
操作:将寄存器BX的内容送到AX中
机器指令;1000100111011000
汇编指令:mov ax,bx
至此,程序员便用汇编语言开始书写源程序,但对于计算机来说,只能读懂机器指令,这时就需要一个能够将汇编指令转化为机器指令的编译器,实现转化的功能。
高级语言,在汇编语言的基础上,形成了一种更加容易理解的语言,因为汇编语言只有相对专业的人员在使用。
1.2存储器与存储单元
在计算机硬件中,有个很重要的核心部件---CPU,它是控制整个计算机的运作,并进行计算。要想让CPU工作,就得向它的提供指令与数据,指令与数据在内存中存放(指令与数据没有什么区别都是二进制信息)。在此我们可以将存储器认为是内存,数据与指令都在内存中存放。
存储器有若干个存储单元,一个存储单元中存储一个字节,一个字节8个比特,一个比特代表一个二进制位。每个存储单元从0开始进行编号,一个存储器有256个存储单元,则编号从0-256,编号的作用是便于对内存中数据的访问。
1.3CPU对存储器的读写
当CPU需要指令或数据时需要从存储器中进行读取,那么如何读取呢?这里有三点需要注意:1、从哪读取。2、怎样读取。3、读取信息。
从哪读取:即为需要读取(指令或数据的地址),存储器很大,存储单元也很多,且具有编号,我们首先要指定读取存储单元的地址。
怎样读取:在微机中,器件很多,CPU在读写数据时还需要指明,对那个器件进行操作,进行那种操作,是都还是写。
读取信息:确定好存储器,存储单元以及读写的方式,进行信息的读取。
这三个问题对应三种信息:
存储单元地址(地址信息)
器件的选择、读或写命令(控制信息)
读或写的数据(数据信息)
确定好这些信息后,只需要将CPU与内存连接,通过这些信息实现数据的交换。
CPU与内存的连接 ,靠的都是总线(实质是导线),从物理上讲,总线就是一根根导线的集合,但从逻辑功能来讲,总线又可分为地址总线、控制总线以及数据总线。
CPU读取信息的过程:
- CPU通过地址总线将地址信息发出;
- CPU通过控制总线发出“读”命令,选中存储器件;
- 存储器将对应地址信息的数据通过数据总线送入CPU。
1.4地址、数据以及控制总线
地址总线:用于寻找内存的地址,地址总线能传送多少不同的信息,CPU就能对多少存储单元进行寻址,也就是说地址总线的宽度,决定了寻址的范围。
数据总线:用于将CPU与器件之间的数据传递,数据总线的宽度决定了CPU与外接的数据传送速度。
控制总线:CPU对外部器件的控制,控制总线的宽度决定了CPU对外部期间的控制能力。
1.5内存地址空间
对于一个计算机来讲,其内部的存储器有多个,每个的功能都是不同的在物理上来说也都是独立的器件,但是对于CPU来讲系统中的所有存储器中的存储单元都处于一个统一的逻辑存储器中,它的容量收CPU寻址能力的限制,这个逻辑存储器即为内存地址空间。
二、寄存器
上面我们讨论的主要是,CPU与其他器件进行的信息传递,这节我们学习CPU内部的一些相关知识。
CPU内部主要有:寄存器、控制器、运算器等器件构成,这些器件之间也是通过总线相连的,不过这些总线是CPU内部的总线,实现的是CPU内部各个器件之间的联系。
运算器:进行信息的处理;
寄存器:进行信息的存储;
控制器:用于控制各种器件进行工作;
内部总线:用于连接各种器件,在它们之间进行数据的传送;
程序员通过改变寄存器的内容来实现对CPU的控制。
不同的CPU寄存器的个数、结构是不同的。8086中有14个寄存器,分别为:AX,BX,CX,DX,CS,SS,DS,ES,SI,DI,SP,BP,IP,PSW.
2.1通用寄存器
8086的寄存器是16位的,可以存放两个字节,其中AX,BX,CX,DX这4个寄存器为通用寄存器,用于存放一般性的数据。
8086之前的CPU中寄存器的位数为8位,因此为了保证兼容性,使原来上一代CPU编写的程序稍加修改可以继续运行,AX,BX,CX,DX这四个寄存器都可分为两个独立的8位寄存器使用。
AX可分为AH与AL;
BX可分为BH与BL;
CX可分为CH与CL;
DX可分为DH与DL;
AH称为高八位寄存器,AL称为低八位寄存器;
在AX寄存器中,存储20000,并且分别用AH与AL观察;
在16位寄存器与8位寄存器的数据存储情况为:
寄存器 | 寄存器中的数据 | 所表示的值 |
AX | 0100111000100000 | 20000(4E20H) |
AH | 01001110 | 78(4EH) |
AL | 00100000 | 32(20H) |
此时,寄存器AH、AL作为两个寄存器单独使用,互不干扰。
2.2汇编指令
通过汇编指令控制CPU进行进行计算,在此我们列出常见的几个指令;
汇编指令 | 控制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 |
在写一条汇编指令或者寄存器的名称时,不区分大小写;
执行下方的汇编指令,其相关寄存器的数据内容为:设寄存器AX、BX初始值均为(0000H)
程序中的指令 | 执行后寄存器AX中的数据 | 执行后寄存器BX中的数据 |
mov ax,4E20H | 4E20H | 0000H |
add ax,1406H | 6226H | 0000H |
mov bx,2000H | 6226H | 2000H |
add ax,bx | 8226H | 2000H |
mov ax,bx | 8226H | 8226H |
add ax,bx | ? | 8226H |
在上述汇编指令的最后一条指令add ax,bx中,执行前ax=8226H,bx=8226H相加之后所得的值为:1044CH,但是ax为16为寄存器,只能存放4为16进制的数据,所以最高位的1不能保存在ax中,ax的数据为:044CCH。
此处我们想说明的是,当存入寄存器的值超过寄存器的位数时,存储的数值从低位往进放,高位舍弃。
执行下方的汇编指令,其相关寄存器的数据内容为:设寄存器AX、BX初始值均为(0000H)
程序中的指令 | 指令执行后AX中的数据 | 指令执行后BX的数据 |
move ax,001AH | 001AH | 0000H |
move bx 0026H | 001AH | 0026H |
add al,bl | 0040H | 0026H |
add ah,bl | 2640H | 0026H |
add bh,al | 2640H | 4026H |
move ah,0 | 0040H | 4026H |
add al,85H | 00C5H | 4026H |
add al,93H | ? | 4026H |
在上述汇编指令中,最后一条指令的计算add al,93H,在执行前al中数据为C5H,相加之后的值为158H,al寄存器是8位寄存器,只能存放两位16进制的数据,所以最高位的1丢失,ax的数据位为0058H,注意,此时al作为一个独立的8位寄存器来使用,和ah没有关系,CPU在执行这条指令时认为ah与al是两个不相关的寄存器,不要错误的认为al产生进位后会存储到ah中,add al ,93H进行的是8位运算。
2.3物理地址
前面我们讲过,在CPU访问内存单元时,要给出内存单元的地址,所有的内存单元构成的存储空间是一个一维的线性空间,每一个内存单元在这个空间中都有一个唯一的地址,这个地址被称为物理地址。
CPU通过地址总线将一个内存单元的物理地址送入存储器,在送入之前,必须在CPU内部产生这个地址,不同的CPU产生物理地址的方式是不同的。
2.4 8086CPU
8086CPU是16位结构的CPU,这16位结构指的是什么呢?
1、运算器一次最多可以处理16位的数据;
2、寄存器的最大宽度为16位;
3、寄存器与运算器之间的通路是16位;
这也就是说,宰086内部能够一次性处理、传输、暂时存储的信息最大长度是16位。对于16位CPU,能一次性处理、传输的地址也是16位的。
2.5 8086CPU产生物理地址的方法
8086CPU有20位地址总线,这也就是说明可以传送20位地址,寻址能力为(2^20字节)1MB,但是8086CPU又是16位结构,如何在16位结构内部产生20位地址,是我们本节讨论的内容。
8086CPU采用一种在内部用两个16位地址合成的方法形成一个20位的地址。
在8086CPU需要一个20位的物理地址时,CPU的相关部件会提供两个16位的地址,一个称为段地址,一个称为偏移地址。两个地址通过CPU内部总线送至地址加法器中,地址加法器将两个16位地址合成为一个20位的物理地址。再通过内部总线送至输入输出控制电路,通过地址总线将20位物理地址传送至存储器中。
地址加法器产生物理地址方法为:物理地址=段地址×16+偏移地址;具体操作如下:
8086CPU想要访问物理地址为12345H的内存单元,此时CPU的地址加法器的工作方式为:
1、相关器件提供段地址与偏移地址;;
2、段地址和偏移地址送入地址加法器;
3、段地址×16;
4、段地址×16+偏移地址,得出物理地址;
5、输入物理地址。
在此说明一个X进制的数据左移1位,相当于乘X;用16进制来表示对应的二进制数,乘以16相当于左移一位。
2.6段地址偏移地址的本质
“段地址×16+偏移地址=物理地址”的本质含义是:CPU在访问内存单元时,用一个基础地址(段地址×16)和一个相对基础地址的偏移地址相加,给出内存单元的物理地址。
举例说明:
现在我们利用纸条进行传信,传递的信息是1234,如果我有一张可以容纳4位数字的纸条,我可以直接写下1234,但是如果我们没有可以容纳4位的纸条,只有两张容纳3位的纸条。那么我们只能写下100(段地址)与234(偏移地址)。并且我们对事先做了约定,得到两张纸条后,做运算:段地址(100)×10+偏移地址(234)=物理地址(1234)。
这里还需要注意的是,内存中是没有实质“段”这个划分的,段的划分来自于CPU,将若干个地址的连续的内存单元看作是一个段,我们自己将一段内存定义为一个段,用段地址指示段,用偏移地址访问段内的单元。
如果用一个段存放数据,则定义为:“数据段”;
如果用一个段存放代码,则定义为:“代码段”;
如果用一个段存放栈,则定义为:“栈段”;
总结:本节为汇编语言的入门,汇编语言是很多计算机相关课程的基础,所以打好基础很重要,本节的概念较多,后面我会写一些相关的实验帮助大家更好的理解。
参考资料:《汇编语言》第四版--王爽老师著
创作不易,还请大家多多点赞支持!!
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)