汇编语言程序设计(第二版)第3章.ppt
《汇编语言程序设计(第二版)第3章.ppt》由会员分享,可在线阅读,更多相关《汇编语言程序设计(第二版)第3章.ppt(93页珍藏版)》请在三一办公上搜索。
1、第3章 基本指令与简单程序设计,3.1 寻址方式 3.2 基本指令 3.3 单个字符的输入输出 3.4 源程序的基本格式 3.5 顺序程序设计 习题三,3.1 寻 址 方 式,3.1.1 立即数型寻址方式 这种寻址方式又称为立即数或立即寻址,是直接把参与操作的数据写在指令中。用汇编语言书写时,操作数可以是各种数制下的数值,也可以是带单引号的字符。比如,下面的MOV指令中源操作数都是立即寻址的简单情况。汇编语言要求指令在一行写完,指令后面所带的分号表示该行的后续内容是注释。,MOV AL,30;源操作数是十进制形式的立即数30MOV AX,3030H;源操作数是十六进制形式的立即数3030HMO
2、V AL,11001101B;源操作数是二进制形式的立即数11001101BMOV AL,3;源操作数是字符形式的立即数3,即其ASCII值33H尽管MASM支持把立即数加上方括号的写法,比如上面的第一条指令也可以写成MOV AL,30但是,这会导致初学者概念上的混淆,建议读者不要使用这种写法。,立即寻址还有一些比较复杂的情况。如果操作数是由数值和运算符构成的表达式,汇编程序在翻译时会计算出表达式的值,并把计算结果以立即数形式翻译到机器指令中。比如下面的指令中源操作数就是这种情况:MOV AL,3-30H该指令中的源操作数是一个可直接计算的表达式。汇编程序会计算出表达式的值是3,并以3作为立即
3、寻址方式的源操作数。,3.1.2 寄存器型寻址方式 这种寻址方式比较简单,就是在指令的操作数部分写寄存器的名称。可用的名称有:AH,AL,BH,BL,CH,CL,DH,DL 8位通用寄存器;AX,BX,CX,DX,SI,DI,BP,SP 16位通用寄存器;CS,DS,ES,SS 16位的段寄存器。,下面的指令中所有操作数都是寄存器寻址方式。MOV AL,BLMOV AL,DHMOV BP,SPMOV AX,SIMOV AX,CSMOV DS,DX,【注意】指令指针IP、标志寄存器PSW以及所有标志位的代号CF、ZF、OF等都不能作为寄存器寻址方式的操作数,不允许出现在汇编语言的任何指令中。另外
4、,8088汇编语言还规定,不允许用MOV等具有赋值功能的指令修改CS的值,也就是说,类似于“MOV CS,AX”试图对CS赋值的指令在8088汇编语言中是不允许的。,3.1.3 内存型寻址方式 内存型寻址方式是指参与操作的数据在内存中,因此必须指明操作数究竟在内存的什么地方,即指出内存的逻辑地址。逻辑地址的段地址部分来自某个段寄存器。每一个内存型操作数都有一个不需要在指令中写出的缺省段寄存器与之对应,如果就以这个缺省段寄存器的值作为段地址,则指令中只要确定偏移地址即可。但是,有时指令中需要使用其它段寄存器而不用缺省段寄存器作为段地址,这时就要先写出需要使用的段寄存器的名字,后面加冒号“:”,再
5、接偏移地址的各种写法。这种不用缺省段寄存器而明确写出段寄存器名称的方式称为“段跨越”。按照确定操作数偏移地址的不同方法,内存型寻址又细分为5种具体情况,分别称为直接寻址、寄存器间接寻址、寄存器相对寻址、基址变址和相对基址变址。,3.1.3.1 直接寻址 这种寻址方式是在指令中直接写明操作数所在的偏移地址。在汇编语言中,这个偏移地址通常以变量的形式出现,在指令中就是直接写变量的名字。变量名字与偏移地址之间存在固定的对应关系,在源程序中写变量的名字,汇编程序会把名字翻译成相应的偏移地址。确立这种对应关系的方法是定义变量。定义变量的具体写法在第5章中加以说明,在此需要说明的是,定义变量时会说明它的类
6、型(字节、字或者双字),定义后的变量就有了一个确定的偏移地址,程序中还会有伪指令说明变量对应的缺省段寄存器是哪一个。也就是说,每个已定义的变量都有缺省段寄存器与之对应,都有固定的偏移地址和类型。,设buf是已经定义的字节型变量,指令“MOV AL,buf”中源操作数寻址方式就是直接寻址。用方括号把变量名字括起来是直接寻址的基本写法。上述指令中的“buf”表示以变量buf对应的偏移地址和缺省段寄存器中的值作为完整的逻辑地址,操作数在逻辑地址所确定的内存单元中。假定上述指令中变量buf的缺省段寄存器是DS,执行上述指令时DS的值是1234H,buf的偏移地址是0ABCDH,则物理地址的形成可用图3
7、.1表示,图中数据均为十六进制。,图3.1 直接寻址方式下操作数的物理地址的形成,直接寻址方式可以使用段跨越。下面是两个使用段跨越的例子:MOV AL,CS:bufMOV AL,ES:buf使用段跨越时物理地址的形成方式,只要在图3.1中把段寄存器DS换成段跨越符号所指明的段寄存器即可。MASM V5.0还支持不写方括号的直接寻址方式,前面的3个例子可以写成如下形式:MOV AL,bufMOV AL,CS:bufMOV AL,ES:buf,变量占据内存空间的大小是以字节为单位的,一个变量并不一定只占一个字节,2.3节就已说明了一个变量占多个字节时在内存中如何安排。汇编语言中还有类似高级语言的数
8、组变量的形式。假定变量buf是存放5个数据的数组,每个数据是字节型,所以共占5字节。现在需要取它的第3个数据送到寄存器AL中,又该怎么写呢?很简单,可以在变量名的后面用加号连接一个数值的形式书写,比如:MOV AL,buf+2,对字节型数组变量buf,分别用buf、buf+1、buf+2、buf+3和buf+4依次对应它所占据的5个字节的偏移地址。汇编程序在翻译这种“变量数值”的写法时,先找出变量名所对应的偏移地址,再与另一个数值相加(如果是用减号连接则计算出两者的差),计算结果作为操作数的偏移地址,以直接寻址方式翻译到机器指令中。如果buf变量所占据的5个字节中依次存放的是1、2、3、4、5
9、,上述指令取到AL中的数据会是3而不是2。尽管下面的写法与上述指令完全等同,但也不建议使用:MOV AL,buf2,3.1.3.2 寄存器间接寻址 这种寻址方式是把一个基地址寄存器或变址寄存器中的字型数据当作偏移地址,写法是以该寄存器的名字加上方括号。这表示寄存器的内容作为偏移地址,而不是参与操作的数据本身,操作数需要到内存中去找。注意与寄存器寻址相区分。下面的例子中源操作数都是寄存器间接寻址方式。MOV AL,BXMOV AL,SIMOV AL,BP,【注意】并不是所有的通用寄存器都能加上方括号,按寄存器间接寻址方式到内存去寻找操作数。8088汇编语言规定,只有基址寄存器BX和BP,变址寄存
10、器SI和DI共4个寄存器可以作为间接寻址方式使用的寄存器。,如果需要,寄存器间接寻址方式也可以使用段跨越,比如:MOV AL,DS:BPMOV AL,ES:BXMOV AL,SS:DI 直接寻址和寄存器间接寻址是汇编语言中内存型操作数最常用的两种寻址方式。如果与高级语言相比较,直接寻址相当于高级语言中的整数、字符等类型的简单变量,而寄存器间接寻址则相当于指向某种数据类型的指针变量。,3.1.3.3 寄存器相对寻址 寄存器相对寻址又称作变址寻址,是以一个基址寄存器或变址寄存器中的值与一个字型数据相加,相加的结果作为偏移地址。相加的结果如果超过16位二进制,超出部分会被忽略。从书写形式上说,以下几
11、个例子中的源操作数都采用了正确形式的寄存器相对寻址方式,其中的标识符buf是已经定义的变量。但是,建议读者在编程时尽量使用第1、第3和第5个例子的写法,以清楚地表明偏移地址是两个数据相加而来。其中的方括号不能省略,方括号中不允许出现一个变量减一个寄存器的写法。,MOV AL,buf+SI MOV AL,bufDI MOV AL,buf+BP MOV AL,bufBXMOV AL,BX+15 汇编语言中还支持更复杂的寄存器相对寻址写法,下面是几个这样的例子。MOV AL,buf+BX+3MOV AL,BX-30H,对于“buf+BX+3”的写法,汇编程序会先把buf对应的偏移地址与数值3相加,得
12、到的和与BX一起,以寄存器相对寻址的形式翻译到机器指令中;对于“BX-30H”,汇编程序会把-30H翻译成相应的补码形式,即0FFD0H,并把减法转变成加法。前面几个例子说明了寄存器相对寻址方式下偏移地址的处理方法,但段地址从何而来呢?这里当然也存在缺省段寄存器的问题。,寄存器相对寻址的缺省段寄存器按下列规则处理:(1)如果是“变量+寄存器”的形式,以变量对应的缺省段寄存器为准。(2)如果是“寄存器+数值”的形式,则以寄存器对应的缺省段寄存器为准。(3)寻址方式中不允许同时出现两个或两个以上的变量相加的情况,但可以出现两个变量相减。减法表示两个变量偏移地址的差值,这个差值不再作为变量看待,而是
13、当作数值,此时缺省段寄存器按第(2)条处理。以指令“MOV AL,BX+15”为例,源操作数采用了寄存器相对寻址,形成物理地址的方式如图3.2所示。,图3.2 寄存器间接寻址方式下物理地址的形成,【例3.1】设变量buf1和buf2定义在同一个段中,偏移地址分别是102H和3ACH,两个变量对应的缺省段寄存器都是ES,寄存器BX和BP的值分别是2000H和3000H。试计算下列各指令中源操作数的偏移地址值,并判断缺省段寄存器是哪一个。(1)MOV AL,buf1+BX(2)MOV AL,BX+13(3)MOV AL,BP+buf1-buf2(4)MOV AL,buf2+BP-4000H,【解】
14、(1)偏移地址为102H+2000H2102H段寄存器为buf1对应的缺省段寄存器ES。(2)偏移地址为2000H+13200DH段寄存器为BX对应的缺省段寄存器DS。(3)偏移地址为3000H+102H3ACH2D56H段寄存器为BP对应的缺省段寄存器SS。(4)偏移地址为3ACH+3000H4000H0F3ACH段寄存器为buf2对应的缺省段寄存器ES。,【例3.2】设arr是一个整型数组变量,其中存放了10个字型带符号整数,用C语言写出相应的变量定义,编写程序段显示该数组中各元素的值;并说明如果使用汇编语言的寄存器相对寻址方式arr+BX分别去取各元素,BX应如何变化。【解】C语言的变量
15、定义为 int arr10;程序段写作:for(i=0;i10;i+)printf(“%dn”,arri);,在汇编语言中,如果要用arr+BX的形式分别访问各元素,则BX应分别取值为十进制的0、2、4、6、8、10、12、14、16、18,即每次加2,因为每个整数(字型带符号数)占2字节。在C语言中,下标变量i从0到9逐个递增,而汇编语言中BX每次加2,请仔细观察两者的对应关系,体会使用上的差别。例3.2同时还说明“寄存器相对寻址”这个名称中相对二字的含义,是指寄存器中的值代表操作数的地址相对于变量起始地址的偏差值。,3.1.3.4 基址变址 这种寻址方式是用一个基址寄存器与一个变址寄存器的
16、值相加,计算结果作为操作数的偏移地址。如果加法运算的最高位向前有进位则被忽略。书写形式是用加号把两个寄存器连接起来,并加上方括号。汇编语言的语法规定,必须用一个基址寄存器与一个变址寄存器相加。基址寄存器只有BX和BP,变址寄存器只有SI和DI,组合起来只可能出现4种情况。下面的4个例子中的源操作数就是这4种组合的书写形式。,MOV AL,BX+SIMOV AL,BX+DIMOV AL,BP+SIMOV AL,BP+DI,这里再次出现段地址在哪个段寄存器的问题。上面的写法仍然采取了缺省段寄存器方式,缺省段寄存器由基址寄存器确定,对应关系是:当基址寄存器是BX时,缺省段寄存器是DS;当基址寄存器是
17、BP时,缺省段寄存器是SS。上面的例子中源操作数都是基址变址方式,前两个都使用DS作为逻辑地址中的段地址,而后两个则用SS。如果需要,基址变址寻址方式也可以使用段跨越。,汇编语言的语法还允许把基址变址方式中的两个寄存器分别写在两个方括号中,连在一起不用加号“+”。下面的写法与前面的4个例子在效果上完全对应相同。MOV AL,BXSIMOV AL,BXDIMOV AL,BPSIMOV AL,BPDI,3.1.3.5 相对基址变址 这种寻址方式是把一个基址寄存器和一个变址寄存器的值以及一个字型数据三者相加,结果作为操作数的偏移地址。字型数据可以是一个变量,也可以是一个数值。段地址部分可以用段跨越方
18、式明确指出段寄存器的名字。没有段跨越符号时,缺省段寄存器分两种情况:一是寻址方式中出现变量时,以变量对应的缺省段寄存器为准;另一种情况是寻址方式中没有变量而是直接写数值,这时以基址寄存器对应的缺省段寄存器为准。下面的几个例子中,假设buf是已定义的变量,对应的缺省段寄存器是DS,指令后面的注释对操作数逻辑地址中的段地址做了简单说明。,MOV AL,buf+BX+SI;段寄存器是buf对应的缺省段寄存器DSMOV AL,buf+BP+DI;段寄存器是buf对应的缺省段寄存器DSMOV AL,BX+SI+30;段寄存器是BX对应的缺省段寄存器DSMOV AL,BP+SI-30;段寄存器是BP对应的
19、缺省段寄存器SSMOV AL,ES:BP+SI-30;以段跨越方式明确指明段寄存器是ES,MOV AL,bufBXSIMOV AL,bufBP+DIMOV AL,BXSI+30MOV AL,-30BPSI,与基址变址类似,相对基址变址在书写时也可以用两个方括号把基址寄存器和变址寄存器括起来,并且不写加号“+”。下面是相对基址变址寻址方式在书写上的几种变形。,相对基址变址最典型的应用是对二维数组元素的访问,它具有类似双下标的书写形式,但与高级语言的双下标又有很大的区别。在C语言中,若定义了一个二维数组变量buf存放m行n列的矩阵,可以直接用行列坐标的形式bufij表示第i行第j列的元素(以左上角
20、为第0行第0列)。若要逐个取某一行元素,可以固定i的值不变,让j依次取值0、1、n-1;若要逐个取某一列元素,可以固定j的值不变,让i依次取值0、1、m-1。这种方式简洁明了,充分体现了高级语言的优势。在汇编语言中,bufBXSI的含义完全不同,它代表了buf+BX+SI,这里BX和SI的值不代表矩阵的行与列。如果想用bufBXSI表示出第i行第j列元素的偏移地址,则需要让BX和SI分别取如下值:BX i n kSI j k,其中n是矩阵的列数,k是每个矩阵元素占据的内存字节数,在编写程序时,n和k都是常量。若要逐个取某一行元素,可以固定BX的值不变,让SI先取初值0,然后每次加k;若要逐个取
21、某一列元素,可以固定SI的值不变,让BX先取初值0,然后每次加nk。实际上,汇编语言要求编程人员自己根据数据在内存中的存放情况考虑基址寄存器和变址寄存器的变化。,3.1.4 外设型寻址方式 给操作对象逐个编号是计算机的基本处理方法。在8088系统中把内存的每个字节进行编号,形成内存的物理地址,类似地也把控制各种外部设备的接口中的各部件编排号码,每个号码对应的一个外设部件称为一个外设端口,号码本身就是外设地址,又称外设端口号。外设是多种多样的,各自的接口也不同,但接口中的各个部件却有一个共同特点,就是能够以1字节为基本单位存放来自系统总线的数据,或者向系统总线提供数据。从这一特点上看,接口中的每
22、个基本部件与内存的一个字节在操作方式上并没有什么差别。于是有些计算机在设计上把内存与外设端口综合在一起,统一地编排一套地址,以地址本身来区分操作对象是内存还是外设,这种地址编排方式称为统一编址或混合编址。,8088采取的是另一种地址编排方式,把外设端口与内存分开来,各编各的地址,这种编址方法称为独立编址。前面已经介绍了8088内存地址的有效范围是1 MB,而它的外设地址有效范围是64 KB。那么,如果写出一个地址,比如300H,如何判断操作对象是内存还是外设呢?这个问题从地址本身是无法解决的,8088系统以指令来区分操作对象的种类。用于内存操作的指令很多,MOV指令就是其中一个,但用于外设操作
23、的指令就只有两条:IN和OUT。输入输出指令的具体用法在第8章中加以说明,这里只是用它们作例子解释外设寻址方式。,外设寻址方式比较简单。一种是把外设地址直接写在指令中,类似于对内存的直接寻址方式,但是不加方括号,比如:IN AL,61H;第2个操作数表示61H号外设端口OUT 43H,AL;第1个操作数表示43H号外设端口这种寻址方式要求外设地址不超过255。另一种方式是把外设地址放在寄存器DX中,类似于内存型的寄存器间接寻址方式,但是也不加方括号,比如:IN AL,DXOUT DX,AL,3.2 基 本 指 令,3.2.1 MOV指令【指令格式】MOV d1,d2【功能】取d2操作数的值,放
24、到d1操作数指定的位置。这是一种典型的双操作数指令,d1称为目的操作数,d2称为源操作数。这条指令一般用于对某个寄存器或内存变量进行赋值,与高级语言中的赋值语句大致相当,两者的一个重要区别在于,高级语言中的赋值语句有计算能力而MOV指令没有。,【注意事项】(1)目的操作数d1是数据送往的地点,不允许是立即寻址方式。(2)如果d1是使用通用寄存器的寄存器寻址方式,则源操作数可以是立即数、寄存器寻址或内存型寻址方式中的任何一种。(3)当d1是段寄存器时,d2只能是通用寄存器或内存型寻址方式,不能是立即数,也不能是另一个段寄存器。(4)不允许两个操作数都是内存型寻址方式。,(5)如果两个操作数都有确
25、定的类型,则两者的类型必须相同,即要么都是8位的字节型,要么都是16位的字型。(6)如果两个操作数中只有一个可以确定类型,则另一操作数的类型按可确定类型的操作数同型处理;当一个操作数是寄存器,另一操作数是变量,且两者类型不同时,变量可以临时改变类型,保证与寄存器类型一致。(7)如果d1是寄存器间接寻址或者基址变址寻址方式,d2是不超过255的立即数,这时从任何一个操作数都不能确定类型,需要在d1操作数的前面用伪指令BYTE PTR或者WORD PTR指明是字节型操作还是字型操作。,(8)指令中的内存型操作数可以使用段跨越。(9)MOV指令不影响标志寄存器的值。,下面的各个例子从汇编语言的语法上
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 汇编语言 程序设计 第二
链接地址:https://www.31ppt.com/p-6586405.html