汇编语言
《汇编语言》 王爽
本文只是自己看书的回忆,不如去看书,讲的更全面和透彻。
每种微处理器的汇编语言都不同,本书以8086CPU为中央处理器的PC机为例
基础知识
机器语言
电子计算机的机器指令是一列二进制数字,计算机将其转变为一列高低电平,使计算机的电子器件受到驱动,进行运算。每种微处理器由于硬件设计和内部结构不同,需要用不同的电平脉冲来控制,所以不同的微处理器其机器指令集不同。
汇编语言的产生
汇编指令是机器指令便于记忆的书写格式。每种CPU都有自己的汇编指令集。
例如:
操作:寄存器BX的内容送到AX
机器指令:1000100111011000
汇编指令:mov ax,bx
程序员用汇编语言写出源程序,汇编编译器将其编译为机器码,由计算机最终执行。
汇编语言的组成
汇编语言包括3种指令:
1.汇编指令:机器码的助记符,有对应的机器码;
2.伪指令:无对应机器码,由编译器执行(告诉编译器怎么翻译),计算机不执行;
3.其他符号:如+、-、*、/等,无对应机器码,由编译器识别;
存储器
CPU控制计算机的运作并进行运算,为其提供的指令和数据存放在存储器中。磁盘中的数据或程序必须读到内存中才可以被CPU使用。
指令和数据
指令和数据是应用上的概念。在内存或磁盘中无任何区别,都是二进制信息,区别只在于CPU在使用时赋予其意义。
例如:
1000100111011000 -> 89D8H(数据)
1000100111011000 -> mov ax,bx(指令)
储存单元
电子计算机最小信息单位是bit,是一个二进制位。8 bit = 1 Byte(字节)
微型机存储器的一个存储单元可以存储一个Byte。一个存储器被划分为若干存储单元,从0开始编号,一个存储单元的容量为一个字节。
1KB=1024B, 1MB=1024KB……
CPU对存储器的读写
存储单元的编号可看作存储单元在存储器中的地址。
CPU进行数据的读写,要和外部器件进行一下3类信息的交互:
1.存储单元的地址;(地址信息)
2.器件的选择,读或写的命令;(控制信息)
3.读或写的数据。(数据信息)
在实际信息交互层面,是通过处理、传输电信号实现的,电信号由总线(专门连接CPU和其他芯片的导线)传送。总线在逻辑上分为地址总线、控制总线和数据总线
CPU从内存中读取数据:
CPU通过地址线将地址信息3发出 → CPU通过控制线发出内存读命令,选中存储器芯片,通知它要从中读取数据 → 存储器将3号单元中的数据8通过数据线送入CPU
写操作类似。
总线
每一个CPU芯片有许多管脚,这些管脚与总线相连。
地址总线的宽度决定了CPU的寻址能力;
控制总线的宽度决定了CPU对系统中其他器件的控制能力;
数据总线的宽度决定了CPU与其他器件进行数据传送时的一次数据传送量。
地址总线
CPU有N根地址线,称该CPU的地址总线宽度为N,最多可以寻找 2 N 2^N 2N个内存单元(意味着寻址能力最小单位为B,而不是bit)。N根地址线,对应 2 N B 2^NB 2NB的寻址能力。
地址总线宽度为16根,可以寻找
2
16
2^{16}
216个内存单元,寻址能力为
2
16
2^{16}
216B=
2
6
2^{6}
26KB=64KB
控制总线
CPU通过控制总线对外部器件进行控制。控制总线是不同控制线的集合,有多少根控制总线,意味着CPU提供了对外部器件的多少种控制。
例如:内存读或写命令由几根控制线综合发出,有一根称为“读信号输出”的控制线负责由CPU向外传送读信号,为低电平时表示将要读取数据。
数据总线
CPU与内存或其他器件间的数据传送是通过数据总线进行的,数据总线的宽度决定了CPU与外界的数据传送速度。8根数据总线一次可传送一个8位二进制数据(即一个字节)。一根数据线对应1bit的传送数据大小(一次)。
例如:传送一个长度为两字节的数据时,若CPU的数据总线宽度为8,则分两次传送;若CPU的数据总线宽度为16,则进行一次传送。
数据总线宽度为8根,一次可以传送数据大小为8bit=1B;数据总线宽度为32根,即32bit=4B。
主板
每台PC机都有一个主板,主板上有核心器件和一些主要器件,器件之间通过总线相连。器件包括CPU、存储器、外围芯片组、扩展插槽等。扩展插槽上一般插有RAM内存条和各类接口卡。
接口卡
CPU无法直接控制显示器、音响、打印机等外设,直接控制这些设备进行工作的是插在扩展插槽上的接口卡。扩展插槽通过总线与CPU相连,相当于接口卡通过总线与CPU相连。简单来讲,CPU通过总线向接口卡发送命令,接口卡通过CPU命令控制外设进行工作。
各类存储器芯片
RAM内存断电后指令和数据丢失,ROM内存断电后指令和数据还在。
1.随机存储器(RAM)
用于存放CPU使用的绝大部分程序和数据,主RAM一般由两个位置上的RAM组成,即装在主板上的RAM和插在扩展插槽上的RAM。
2.装有BIOS(基本输入/输出系统)的ROM(只读存储器)
BIOS是由主板和各类接口卡(如显卡、网卡)厂商提供的软件系统,可通过它利用该硬件设备进行最基本的输入输出。例如,主板上的ROM储存着主板的BIOS,显卡上的ROM储存着显卡的BIOS。
3.接口卡上的RAM
某些接口卡需要对大批量输入输出数据进行暂时储存,其上装有RAM。如显卡上的RAM被称为显存,我们将需要显示的内容写入显存,就会出现在显示器上。
内存地址空间
上述的储存器,在物理上是独立的,但在CPU的眼里,他们都是内存,把他们总的看作一个由若干储存单元组成的逻辑储存器,这个逻辑储存器就是我们所说的内存地址空间。每个物理存储器在逻辑存储器中占有一个地址段,CPU在这段地址空间中读写数据,实际上就是在对应物理存储器中读写数据。
内存地址空间大小受CPU地址总线宽度的限制。
寄存器
CPU通常由运算器(进行信息处理)、控制器(控制各种器件进行工作)、寄存器(进行信息存储)等器件构成,这些器件内部由总线相连。上一章说的是外部总线,实现CPU和主板上其他器件的联系,内部总线实现CPU内部各器件之间的联系。
寄存器是CPU中程序员可以用指令读写的部件,程序员通过改变各种寄存器中的内容来实现对CPU的控制。
不同的CPU,寄存器的个数和结构不同。
8086CPU有14个寄存器,分别为AX、BX、CX、DX、SI、DI、SP、BP、IP、CS、SS、DS、ES、PSW,大小都是16位的,可以存放2个字节。
通用寄存器
AX、BX、CX、DX通常用来存放一般性数据,被称为通用寄存器。
字在寄存器中的存储
字:word,一个字由两个字节组成
8086CPU给出物理地址的方法
CPU相关部件提供两个16位地址,分别为段地址和偏移地址,段地址和偏移地址通过内部总线送入地址加法器,得到一个20位的物理地址,通过内部总线送入输入输出控制电路,该电路将20位物理地址送上地址总线,再被送到存储器。
物理地址=段地址×16+偏移地址
段地址在段寄存器中存放,8086CPU有4个段寄存器:CS、DS、SS、ES。其中CS用来存放指令的段地址。
CS和IP
CS:代码段寄存器
IP:指令指针寄存器
在8086PC机中,任意时刻,设CS中内容为M,IP中内容为N,8086CPU将从M×16+N单元开始,读取一条指令并执行(即CPU将CS:IP指向的内容当作指令执行)。
过程:从内存单元中读取的指令进入指令缓冲器;IP=IP+所读取指令长度,从而指向下一条指令(这一过程是自动的);执行指令,回到初始步骤。
CPU从何处执行指令是由CS、IP中的内容决定的,程序员可以通过改变CS、IP中的内容来控制CPU执行目标指令。
修改CS、IP的指令:
大部分寄存器的值都可以用mov指令来改变,mov指令被称为传送指令,但无法用于CS、IP的修改。
能改变CS、IP的内容的指令统称为转移指令。如jmp指令,形如”jmp 段地址:偏移地址“,用指令中给出的段地址修改CS,偏移地址修改IP;”jmp 某一合法寄存器“,用寄存器中的值修改IP
寄存器(内存访问)
字单元
字单元由两个连续的内存单元组成,即存放一个字型数据(16位)的内存单元。高地址内存单元存放字型数据的高位字节,低地址内存单元存放字型数据的低位字节。
将起始地址为N的字单元称为N地址字单元。
DS和[address]
DS:存放要访问数据的段地址,[]中是偏移地址。
不能用mov ds,数据的指令来修改ds,应该是mov ds,通用寄存器,用通用寄存器中的数据修改ds。
访问内存单元时,段地址默认在DS寄存器中。
栈
“后进先出”原则,在数据结构中学过,在此不赘述。
任意时刻SS:SP指向栈顶元素,执行push和pop指令时,CPU从SS和SP获得栈顶位置。
8086CPU的入栈、出栈操作都是以字为单位
以栈段为10000H~1000FH为例:
栈空时,SS=1000H,SP=10H。(1000FH为“栈底”,10000H为“栈顶”,由于以字为单位,栈中只有一个元素时,SS=1000H,SP=000EH,所以栈空时,SP后移两格,SP=0010H)。
push ax操作:
(1)SP=SP-2;
(2)将ax中的内容送入SS:SP指向的内存单元处。(ax的低位字节存放在低地址单元)
pop ax操作:
(1)将SS:SP指向的内存单元处的数据送入ax中;
(2)SP=SP+2。
8086CPU不能保证对栈的操作不超界,所以要做好栈空间大小的管理。
一个栈段的容量最大为64KB。
段
数据段
段地址存放在DS中,用mov, add, sub等访问内存单元的指令时,CPU就将我们定义的数据段中的内容当作数据访问。
代码段
段地址存放在CS中,将段中第一条指令的偏移地址放在IP中。
栈段
段地址存放在SS中,栈顶单元的偏移地址放在SP中,执行pop、push等指令时,CPU将我们定义的栈段当作栈空间访问。
第一个程序
源程序经编译程序编译后产生目标文件(.obj),用连接程序对目标文件进行连接,生产可执行文件(.exe)。可执行文件包括程序和数据、相关的描述信息两部分内容。
程序返回:
mov ax,4c00H
int 21H
程序执行过程的跟踪
exe文件中程序的加载过程:
程序加载后,DS中存放着程序所在内存区的段地址,这个内存区的偏移地址为0;这个内存区的前256个字节存放的是PSP,DOS用来和程序进行通信,从256字节处向后的空间存放的是程序。
程序跟踪:
debug xx.exe
到了int 21时,用P命令执行。