博客开通。。第一篇文章:8086汇编学习笔记(原创)

1.   寄存器

1.   通用寄存器组

       (1)   AX-累加器。算数运算的主要寄存器,用于存放操作数和或运算结果;另外,外设操作指令都是用AX存放数据。

       (2)   BX-基地址寄存器。用于存放操作数的偏移地址。

       (3)   CX-计数寄存器。用于循环指令、移位指令及串操作指令的计数控制。

       (4)   DX-数据寄存器。在乘除法运算中,与AX组合在一起存放双字型数据;DX还用于存放外设操作数的端口地址。

       (5)   SI-源变址寄存器。作为串操作的源操作数地址指针,也可用于存放操作数的偏移地址。

       (6)   DI-目的变址寄存器。作为串操作的目的操作数地址指针,也可用于存放操作数的偏移地址。

       (7)   BP-栈基地址寄存器。用于存放堆栈中的操作数的偏移地址。

       (8)   SP-栈顶指针。用于记载栈顶的当前位置(偏移地址)。

2.   标志寄存器

       (1)   条件标志位

CF-进位标志。记录加法运算的进位,或者减法运算的借位值。

ZF-零标志。记录运算结果是否为0

SF-符号标志。记录运算结果的正负情况。

OF-溢出标志。记录运算结果是否超出有符号数的表示范围。

PF-奇偶标志。记录字节型运算结果中1的个数的奇偶性。

AF-辅助进位标志。记录加/减法运算中最后4位向前有无进/借位。

       (2)   控制标志位

TF-单步中断允许标志。又称跟踪标志,表示系统当前是否允许单步中断。

IF-外中断屏蔽标志。表示系统当前是否允许可屏蔽外中断。

DF-方向标志。表示串操作按增量方向(0)还是按减量方向(1)进行。

3.   段寄存器组

       (1)   CS-代码段段地址寄存器,或称指令段段地址寄存器。

       (2)   DS-数据段段地址寄存器。

       (3)   ES-附加段段地址寄存器。

       (4)   SS-堆栈段段地址寄存器。

4.   指令指针

       (1)   IP-专门用于存放下一条指令所在的偏移地址。它与CS配合使用,用来确定程序的下一条指令在内存的哪个字节。

2.   基本指令

1.   MOV指令

【格式】MOV d1d2

【功能】d2操作数的值,放到d1操作数指定的位置。

【注意事项】

       (1)   目的操作书d1是数据送往的地点,不允许是立即寻址方式。

       (2)   如果d1是使用通用寄存器的寄存器寻址方式,则源操作数可以立即数、寄存器寻址或内存型寻址方式中的任何一种。

       (3)   d1是段寄存器时,d2不能是立即数,也不能是另一个段寄存器,只能是通用寄存器或内存型寻址方式

       (4)   不允许两个操作数都是内存型寻址方式。

       (5)   如果两个操作数中都有确定的类型,则两者的类型必须相同,即要么都是8位的字节型,要么都是16位的字型。

       (6)   如果两个操作数中只有一个可以确定的类型,则另一个操作数的类型按可确定类型的一个操作数同型处理;当一个操作数是寄存器,另一操作数是变量,且两者类型不同时,变量可以临时改变类型,保持与寄存器类型一致。

       (7)   如果d1是寄存器间接寻址或者基址变址寻址方式,d2是不超过255的立即数,这时两个操作数的类型都不能确定,需要在d1操作数的前面用BYTEPTR或者WORDPTR指明操作是字节型还是字型。

       (8)   指令中的内存型操作数可以使用段跨越。

       (9)   MOV指令不影响所有标志位的值。

2.   ADD指令

【格式】ADD d1d2

【功能】把目的操作数d1与源操作数d2相加,结果放入目的操作数中。加法运算不改变源操作数d2的值。

【注意事项】作为双操作数指令,ADD指令在语法规定上大部分与MOV指令是一样的,但也有它特别的地方

       (1)   MOV指令中的注意事项⑴⑵⑷~⑻。

       (2)   两个操作数都不允许是段寄存器。

       (3)   ADD指令本身并不区分相加的两个数是无符号数还是带符号数,因为相加的结果在储存形式上是一样的。

       (4)   该指令将根据运算结果设置标志寄存器中的各条件标志位。

3.   SUB指令

【格式】SUB d1d2

【功能】用目的操作数d1作为被减数,源操作数d2作为减数,把两者相减的差送回目的操作数d1中。运算不改变源操作数d2的值。

4.   MUL 指令

【格式】MUL d

【功能】完成无符号数的乘法运算。根据操作数d的类型分两种情况:如果d是字节型,则把AL的值与d相乘,16位的积放到AX中;如果d是字型,则把AX的值与d相乘,32的积放到DXAX中,DX放积的高16位,AX放低16位。

【注意事项】

       (1)   MUL指令只能完成无符号数乘法运算,如果是带符号数则需要用另外的指令。

       (2)   两个乘数的位数必须相同,如不同则需要转换,或怍适当处理,运算结果的位数是乘数的两倍。

       (3)   指令中的操作数d不允许是立即数,只能用寄存器或内存型寻址方式,但不能是段寄存器。

       (4)   操作数d必须有确定的类型,当使用内存型寻址方式且不能确定类型时,必须用BYTE PTRWORD PTR伪指令加以说明,并且可以使用段跨越。

5.   DIV指令

【格式】DIV d

【功能】完成无符号数的除法运算。根据操作数d的类型分两种情况:如果d是字节型,则用AX的值作为被除数,指令中的操作数d作为除数,除法运算结果包括商和余数两部分,字节型的商放到AL中,字节型的余数放到AH中;如果d是字型,则用DX的值作为高16位,AX的值作为低16位,组成32位的被除数,操作数d作为除数,计算结果,字型的商放到AX中,字型的余数放到DX中。

【注意事项】

       (1)   DIV指令只能完成无符号数除法运算,带符号数的除法需要另外的指令。

       (2)   被除数必须是字型或双字型,如果是其他类型则需要采取适当的方式进行处理,商和除数的类型相同,位数是被除数位数的一半。

       (3)   MUL指令注意事项(3)、⑷。

6.   CMP指令

【格式】CMP d1d2

【功能】用操作数d1减去操作数d2,把运算的情况反映到条件标志位上,运算得到的差并不送到任何一个操作数中,即CMP指令并不改变两个操作数的值。

【说明】

       (1)   CMP指令专门用于两个数据的比较,数据本身可以时无符号数,也可以是带符号数。

       (2)   CMP指令关于操作数寻址方式的要求与SUB指令完全相同。

       (3)   CMP指令对各标志位的设定规则也与SUB指令相同。

7.   无条件跳转指令—JMP

【格式】JMP 标号

【功能】让计算机转到标号所在处继续执行。

通常情况下,标号的定义与JMP指令应该在同一个段中,这种情况下的跳转称为段内跳转,只需要改变IP的值即可实现转移。标号定义的位置与JMP指令的位置之间没有先后限制,JMP指令既可以实现向前跳转,也可以用于向后跳转。程序中还可以多处使用JMP指令转到同一个标号。

8.   以单个标志位为条件的跳转指令—JZ指令(Jump if ZF Set

【格式】JZ 标号

【功能】如果ZF标志位的值是1,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。

9.   JNZ指令(Jump if ZF Not Set

【格式】JNZ 标号

【功能】如果ZF标志位的值是0,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。

10.  JC指令(Jump if CF Set

【格式】JC 标号

【功能】如果CF标志位的值是1,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。

11.  JNC指令(Jump if CF Not Set

【格式】JNC 标号

【功能】如果CF标志位的值是0,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。

12.  JS指令(Jump if SF Set

【格式】JS 标号

【功能】如果SF标志位的值是1,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。

13.  JNS指令(Jump if SF Not Set

【格式】JNC 标号

【功能】如果SF标志位的值是0,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。

14.  JO指令(Jump if OF Set

【格式】JO 标号

【功能】如果OF标志位的值是1,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。

15.  JNO指令(Jump if OF Not Set

【格式】JNC 标号

【功能】如果OF标志位的值是0,则转到标号所在处继续执行,否则按正常顺序执行下一条指令。

16.  JE指令—等于跳转(Jump if Equal

【格式】JE 标号

【功能】如果ZF1,则转到标号处继续执行,否则按正常顺序执行下一条指令。这是JZ的另一种写法

17.  JNE指令—不等于跳转

【格式】JNE 标号

【功能】如果ZF0,则转到标号处继续执行,否则按正常顺序执行下一条指令。是JNE的另一种写法

18.  JA指令—无符号数大于跳转(Jump if Above

【格式】JA 标号

【功能】如果ZFCF都是0,则转到标号处继续执行,否则按正常顺序执行下一条指令。

JA指令完全等同的写法是JNBEJump if Not Below nor Above

19.  JNA指令—无符号数小于或等于跳转(Jump if Not Above

【格式】JNA 标号

【功能】如果ZF1,或者CF1,则转到标号处继续执行,否则按正常顺序执行下一条指令。

JNA指令完全等同的写法是JBEJump if Below or Equal

20.  JB指令—无符号数小于跳转(Jump if Below

【格式】JB 标号

【功能】如果CF1,则转到标号处继续执行,否则按正常顺序执行下一条指令。

JB指令完全等同的写法有JNAE(Jump if Not Above nor Equal)JC

21.  JNB指令—无符号数大于或等于跳转(Jump if Not Below

【格式】JNB标号

【功能】如果CF0,则转到标号处继续执行,否则按正常顺序执行下一条指令。

JNB指令完全等同的写法有JAEJump if Above or Equal)和JNC

22.  JG指令—带符号数大于跳转(Jump if Great

【格式】JG标号

【功能】如果ZF0并且SFOF值相同,则转到标号处继续执行,否则按正常顺序执行下一条指令。

JG指令完全等同的写法是JNLEJump if Not Less nor Equal

23.  JGE指令—带符号数大于或等于跳转(Jump if Great or Equal

【格式】JGE标号

【功能】如果SFOF值相同,则转到标号处继续执行,否则按正常顺序执行下一条指令。

JGE指令完全等同的写法是JNLJump if Not Less

24.  JL指令—带符号数小于跳转(Jump if Less

【格式】JL标号

【功能】如果SFOF值不同,则转到标号处继续执行,否则按正常顺序执行下一条指令。

JL指令完全等同的写法是JNGEJump if Not Great nor Equal

25.  JLE指令—带符号数小于或等于跳转(Jump if Less

【格式】JLE标号

【功能】如果SFOF值不同,或者ZF1,则转到标号处继续执行,否则按正常顺序执行下一条指令。

JLE指令完全等同的写法是JNGJump if Not Great

26.  JCXZ指令(Jump if CX is Zero

【格式】JCXZ标号

【功能】如果CX=0,则转到标号处继续执行,否则按正常顺序执行下一条指令。

27.  LOOP—计数器型循环

【格式】LOOP 标号

【功能】先把寄存器CX的值减1,在判断若减1后的CX值不是0,则转到标号所在的指令继续执行,否则按正常顺序执行下一条指令。

【说明】

       (1)   这是把CX当作递减计数器使用,LOOP指令包含了把CX1的功能,不需要另外写CX1的指令。

       (2)   LOOP属于条件跳转指令,但跳转不依赖于任何标志位,仅仅根据CX1后的值是否为0;与其他条件跳转一样,跳转的距离不能超过前后128字节。

       (3)   LOOP指令构成的循环,通常是先将CX中放预订的循环次数,然后是循环体,并在循环体的第1条指令处定义一个标号,循环体的后面时LOOP指令,跳转到前面定义的标号处。

       (4)   由于是对CX先减1后判断,若执行LOOP指令时CX的值时0,则减1后变成0FFFFH,不为0,则会转到标号处,所以如果CX中预先放的值是0,循环体将会执行65536次,为预防这样的情况出现,通常先用JCXZ指令判断一下CX值是否为0,不为0时再进如循环部分。

28.  带进位CF的加法

【格式】ADC d1d2

【功能】把目的操作数d1,源操作数d2以及进位标志CF的值相加,结果送回d1中。

【说明】这条指令与ADD指令相比,仅仅是参与加法运算的加数多了CF,如果执行该指令时CF的值时0,就与ADDd1d2在效果上完全相同。ADC指令与ADD指令在对操作数的寻址方式要求上,以及运算结果对标志位的设置方法上都是一样的。该指令主要用于多字节整数相加。

29.  1指令

【格式】INC d

【功能】把操作数d1后的结果送回d中,

【说明】

       (1)   这是一条单操作数指令,要求操作数d必须是寄存器或内存型寻址方式,并且不能是段寄存器。如果是内存型寻址方式,必须能够确定d的类型。d本身不能确定类型时,在d的前面加上BYTE PTRWORD PTR指明类型。

       (2)   该指令对条件标志位的影响是:SFZF根据实际情况设置,对CF没有影响,对于OF,当执行前操作数是字节型的7FH或是字型的7FFFH时,执行后把OF1,其余情况都把OF0

       (3)   INC指令可以用来把操作数的值加1,它与ADD d1的差别主要在于对标志位CF的影响上。

30.  带借位CF的减法

【格式】SBB d1d2

【功能】用目的操作数d1减去源操作数d2,再减去CF的值,结果送到d1中。

除了多减一个CF的值外,SBB指令与SUB指令在对操作数的寻址方式要求上,以及对标志位的影响上是一样的。这条指令主要用于多字节型整数的减法。

31.  求补操作

【格式】NEG d

【功能】对操作数d按位取反后再加1,结果送回d中。

【说明】

       (1)   这条指令的功能就是求补函数,它并不考虑操作数d是否带符号,只是按“取反加1”的规则处理。

       (2)   对操作数寻址方式的要求与INCDEC指令的要求相同。

       (3)   对标志位的影响:SFZF按实际情况设置:若执行前d=0。则执行后CF0,否则CF1;若执行前d是字节型的80H或字型的8000H,则执行后OF1,其余情况都将使OF0

32.  带符号数乘法

【格式】IMUL d

【功能】带符号数的乘法指令。当d是字节型时,把AL×d的结果放到AX中;当d是字型时,把AX×d的结果放到DXAX构成的双字中,DX放高16位,AX放低16位。不论操作数d中的数据来源如何,都当作带符号数。

33.  带符号数除法

【格式】IDIV d

【功能】带符号数的除法指令。当d是字节型时,用AZ/d,商放在AL中,余数放在AH中;当d是字型时,用DXAX组成的双字作为被除数,除以d的商放在AX中,余数放在DX中。不论操作数d中的数据来源如何,都当作带符号数。如果商超出数据的有效范围,将作为除法溢出处理,在屏幕上显示“Divide Overflow”字样,并结束程序的执行。

34.  字节型符号扩展

【格式】CBW

【功能】AL中的带符号数进行符号扩展,当AL<0时,AH被赋值为0FFH,否则AH被置为0。该指令不影响所有标志位。

35.  字型符号扩展

【格式】CWD

【功能】AX中的带符号数进行符号扩展,当AX<0时,DX被赋值为0FFFFH,否则DX被置为0。该指令不影响所有标志位。

36.  交换指令

【格式】XCHG d1d2

【功能】把操作数d1d2的值交换。该指令不影响所有标志位。

【说明】交换指令XCHG要求两个操作数中不能有立即寻址方式,不能有段寄存器,也不允许两个都是内存型寻址方式。

37.  查表转换

【格式】XLAT

【功能】这是一条隐含操作数指令,把字型寄存器BX的值与字节型的AL相加,结果作为内存的偏移地址,以DS为段,到内存中取出一字节送到AL中。该指令不影响所有标志位。

38.  逻辑与

【格式】AND d1d2

【功能】把两个操作数按二进制形式,相应位进行逻辑与运算,结果放到操作数d1中。

【说明】对操作数d1d2的寻址方式的要求与MOVADD等典型双操作数指令的要求完全相同。运算结果将影响到标志寄存器的各条件标志位,具体设置情况是:CFOF总是被清0;运算结果的最高位复制到SF中;若运算结果各位都是0ZF1,否则ZF0

AND指令主要用于把目的操作数的指定位清0

39.  逻辑或

【格式】OR d1d2

【功能】把两个操作数按二进制形式,相应位进行逻辑或运算,结果放到操作数d1中。

【说明】对操作数d1d2的寻址方式的要求以及对标志位的影响与AND指令完全相同。

OR指令主要用于把目的操作数的指定位置1

40.  逻辑非

【格式】NOT d

【功能】把操作数d按二进制形式,每位取反,结果放回操作数d中。

【说明】对操作数d的寻址方式的要求与INC等典型单操作数指令一样,可以是寄存器寻址或内存型寻址方式,不能是段寄存器。操作数必须有确定的类型,可以使用段跨越。

41.  逻辑异或

【格式】XOR d1d2

【功能】把两个操作数按二进制形式,相应位进行逻辑异或运算,结果放到操作数d1中。

【说明】对操作数d1d2的寻址方式的要求以及对标志位的影响与AND指令完全相同。

XOR指令主要用于对目的操作数的指定位取反。

42.  位测试

【格式】TEST d1d2

【功能】把两个操作数按二进制形式,相应位进行逻辑与运算,按结果设置条件标志位,结果不送回目的操作数。

【说明】对操作数d1d2的寻址方式的要求以及对标志位的影响与AND指令完全相同。

TEST指令通常用于检测指定位上是0还是1TEST指令总是与JZJNZ指令配合使用。

43.  LEA——取变量的偏移地址

【格式】LEA d1d2

【功能】把源操作数d2的偏移地址取到目的操作数d1中。

【说明】

       (1)   这是一条数据传递类指令,不影响标志位。

       (2)   该指令专用于取源操作数的偏移地址,所以源操作数d2一定是内存型寻址方式,可以是内存型操作数5种寻址方式中的任何一种。

       (3)   d2是变量名形式的直接寻址方式时,变量名两边的方括号可以省略。

目的操作数d1一定是寄存器型,且必须是16位的字型通用寄存器,不能是段寄存器。

44.  PUSH指令

【格式】PUSH d

【功能】先把SP的值减去2,然后把操作数d指明的字型数据放入以SS为段地址、SP为偏移地址所对应的内存单元中。

【说明】

       (1)   这是单操作数指令,操作数d可以是包括段寄存器在内的任何字型寄存器,或者内存型寻址方式,但不能是立即寻址,当使用内存型寻址方式时可以使用段跨越。

       (2)   PUSH指令的功能包括移动栈顶和存入数据两部分,两部分连续完成,密不可分。

       (3)   操作数d进栈是以减2以后的SP的值作为偏移地址,但程序中不允许出现[SP]的写法。

       (4)   PUSH指令会导致栈顶指针的移动,如果用PUSH指令把很多数据进栈,使SP不断减2,就有可能超出栈的有效范围。

45.  POP指令

【格式】POP     d

【功能】从SS为段地址、SP为偏移地址对应的内存中取出一个字型数据,送到操作数d的指定的位置,然后把SP的值加2。对操作数d的寻址方式要求与PUSH指令相同。

46.  PUSHFPOPF指令

【格式】PUSHF

【功能】把SP的值减2,并把16位的标志寄存器送入SSSP所指向的内存,即把标志寄存器入栈

 

【格式】POPF

【功能】把栈顶的一个16位的字型数据送入标志寄存器,并把SP的值加2

47.  CALL指令

【格式】CALL    子程序名

        【功能】调用子程序指令

       (1)   如果被调用的子程序是NEAR类型,则先把当前指令指针IP的值入栈,这会使SP的值减2,然后把IP改成子程序的第1条指令的偏移地址。

       (2)   如果被调用的子程序是FAR类型,则先把当前CS寄存器的值入栈,再把IP入栈,如果会使SP的值减4,然后把CSIP改为子程序第1条指令的逻辑地址。

48.  RET指令

【格式】RET

【功能】这是子程序返回指令,必须写在子程序的指令序列之中。根据所在的子程序的类型不同,RET指令的功能也分为两种情况:

       (1)   如果RET所在的子程序是NEAR类型,则从堆栈中出栈一个字(当然,SP会加2),送给IP

       (2)   如果RET所在子程序是FAR类型,则先从堆栈中出栈一个字送到IP,在出栈一个字送到CS,栈顶指SP的值加4

【格式】RET n

【功能】完成RET指令的功能后,把SP的指令加n结果送回SP

49.  CLC指令

【格式】CLC

【功能】对CF标志位清0

50.  STC指令

【格式】STC

【功能】对CF标志位置1

51.  CMC指令

【格式】CMC

【功能】对CF标志位的原值取反。

52.  逻辑左移

【格式】SHL d1d2

【功能】把操作数d1的各个二进制位依次向左移动d2位,移动造成右边的空位填0,结果放回操作d1中。

【说明】

       (1)   操作数d1必须是通用寄存器或内存型寻址方式,必须有确定的类型,可以是字节型,也可以是字型,并且对内存型寻址方式可以使用段跨越。

       (2)   操作数d2表示移位的位数,只能是立即数或者寄存器CL,当移动位数超过1位时,必须把移动位数放在CL中,以CL作为d2操作数。

       (3)   操作数d1各位移动情况从最高位起,将有d2位移到操作数d1之外,除了最后移出的一位放到标志位CF中之外,其余各位均被丢弃,移动造成右边的空位用0填充。

       (4)   移动后d1中的数据是在其原值的后面加了d20,即把原数值扩大了2d2倍,当扩大后的值超过表示范围时,超过d1类型(字节或字)规定位数的高位部分会自动丢失。

       (5)   该指令对其余标志位的影响情况是:移动后的结果为0ZF1,否则ZF0;移动后d1最高位的值会复制到SF上;如果移动前后d1的最高位不同则OF1,否则OF0

53.  算术左移

【格式】SAL d1d2

【说明】这是一条与SHL完全相同的指令,该指令与SHL指令是同一条机器指令的不同写法。

54.  逻辑右移

【格式】SHR d1d2

【功能】把操作数d1的各个二进制位依次向右移动d2位,移动造成左边的空位填0,结果放回操作数d1中。

【说明】

       (1)   对两个操作数的语法限制以及对标志位的设置情况都与SHL指令相同,见SHL指令说明的(1),(2)和(5)。

       (2)   SHR指令在位的移动方向上与SHL指令刚好相反,其他方面则很类似,向右移出的最后一位放到CF中,右移造成左边的空位以0填充。

       (3)   移动后的值是把d1中的原值作为无符号数,除以2d2的商。

55.  算数右移

【格式】SAR d1d2

【功能】把操作数d1的各个二进制位依次向右移动d2位,移动造成左边的空位填d1原值的最高位,结果放回操作数d1中。

【说明】SAR指令的功能基本上与SHR的一样,仅仅是移动造成的空位填充方式不同,如果操作数d1移动前最高位是1,则移动造成的空位以1填充,否则以0填充。

56.  循环左移

【格式】ROL d1d2

【功能】把操作数d1的各个二进制位向左移动d2位,从d1左端移出的每一位再依次移到右端空出的位上,最后移出的一位还要送到CF中。

57.  循环右移

【格式】ROR d1d2

【功能】把操作数d1的各个二进制位向右移动d2位,从右端移出的各位再依次移到d1左端空出的位上,最后移出的一位还要送到CF中。

58.  带进位的循环左移

【格式】RCL d1d2

【功能】把操作数d1的各位与CF联合在一起,构成9个或者17个二进制位,向左移懂d2位,从左端移出的各位再依次移到右端空出的位上。

59.  带进位的循环右移

【格式】RCR d1d2

【功能】把操作数d1的各位与CF联合在一起,构成9个或者17个二进制位,向右移动d2位,从右端移出的各位再依次移到左端空出的位上。

60.  专用指令设置DF——CLDSTD

【格式】CLD

【功能】把标志位DF0

【格式】STD

【功能】把标志位DF1

61.  LODS指令——从串中取出数据

【格式】LODSBLODSW

【功能】

       (1)   LODSB进行字节型串操作,从内存中DSSI所确定的逻辑地址处取出一个字节的数据,送到AL中。当DF=0时,令SI=SI+1,DF=1时,令SI=SI+1

       (2)   LODSW进行字型串操作,从内存中DSSI所确定的逻辑地址处取出一个字型数据,送到AX中。当DF=0时,令SI=SI+2;当DF=1时,令SI=SI-2

62.  STOS指令——往串中存入数据

【格式】STOSBSTOSW

【功能】

       (1)   STOSB进行字节型操作,把AL的值送往内存中由ESDI所确定的内存中。当DF=0时,令DI=DI+1,当DF=1时,令DI=DI-1

       (2)   STOSW进行字型串操作,把AX的值送往内存中由ESDI所确定的内存中。当DF=0时,令DI=DI+2,当DF=1时,令DI=DI-2

63.  MOVS指令——串复制

【格式】MOVSBMOVSW

【功能】

       (1)   MOVSB进行字节型串复制,把DSSI所指向的一个字节型数据送往ESDI所指向的内存中。当DF=0时,令SI=SI+1DI=DI+1;当DF=1时,令SI=SI+1DI=DI-1

       (2)   MOVSW进行字型串复制,把DSSI所指向的一个字型数据送往ESDI所指向的内存中。当DF=0时,令SI=SI+2DI=DI+2;当DF=1时,令SI=SI-2,DI=DI-2

64.  CMPS指令——串比较

【格式】CMPSBCMPSW

【功能】

       (1)   CMPSB进行字节型串比较,把DSSI所指向的一个字型数据与ESDI所指向的一个字相减,相减结果反映到条件标志位上。当DF=0时,令SI=SI+2DI=DI+2;当DF=1时,令SI=SI-2DI=DI-2

65.  SCAS指令——串扫描

【格式】SCASBSCASW

【功能】

       (1)   SCASBAL与字节型串中数据比较,用AL减去ESDI所指向的一个字节型数据,相减结果反映到条件标志位上。当DF=0时,令SI=SI+1DI=DI+1;当DF=1时,令SI=SI+1DI=DI-1

       (2)   SCASWAX与字型串中数据比较,用AX减去ESDI所指向的一个字型数据,相减结果反映到条件标志位上。当DF=0时,令SI=SI+2DI=DI+2;当DF=1时,令SI=SI-2,DI=DI-2

66.  REP前缀

【功能】当CX的值不是0时,重复执行后面的串操作指令,每执行一次,把CX的值减1,直到CX=0为止。

67.  REPZREPNZ前缀

【功能】带有REPZ前缀的串指令按下列方式执行:

       (1)   CX=0,则结束指令的执行,否则转(2

       (2)   CX=CX-1

       (3)   执行一次串指令。

       (4)   ZF=0,则结束指令的执行,否则转(2

       (5)   REPNZ的功能与REPZ仅在第(4)项不同,REPZ是在ZF=1时控制串操作重复执行,而REPNZ则是在ZF=0时控制串操作重复执行。

68.  LOCAL

【格式】LOCAL 标号1,标号2

【功能】用于告诉汇编程序,在宏展开时,对宏体中出现的“标号1”、“标号2”等标号定义,代换为特殊的各不相同的标号。汇编程序在遇到用LOCAL说明的标号时,会代以??0000??0001?0002……等特殊的标识符,以保证宏体中的标号定义在每次宏展开时各不相同,避免重复定义的情况。

69.  有规律变化的重复

【格式】REPT n

       

        ENDM

【说明】把一组源代码重复n次。格式中的REPTENDM是汇编语言保留字,是重复汇编的起止标志。REPT后面的n必须是一个常量或常量标识符,表示重复次数,省略号部分是被重复的源程序代码。

70.  无规律变化的重复

【格式】IRP     形参,<实参表>

       

        ENDM

【功能】IRPENDM是重复汇编的起止标志,省略号表示被重复的一组指令或伪指令,形式参数是这一组指令中可变化的部分。如果实参表中有n个参数项,汇编程序将把这一组指令或伪指令重复n次,每一次用实参表中的一个参数项代替形参。

71.  控制外设的指令

【格式】IN d1d2

【功能】从d2指明的外设端口中读取1字节或2字节数据,送到操作数d1指出的地方。

【说明】

       (1)   8088系统限制d1只能是ALAX。当外设端口号不超过255时,d2操作数可直接写端口号码,是外设的直接寻址方式;端口号超过255时,必须先把端口号放在DX中,以DX作为d2操作数,这是外设的简介寻址方式。

       (2)   d1AL时,该指令从指定的端口中读1字节数据;当d1AX时,CPU将从d2对应的端口读一字节数据到AL,从下一个端口号读一字节数据到AH,即总共读取16位数据送到AX中。

【格式】OUT d1d2

【功能】把操作数d2指明的1字节或2字节数据送到d1对应的外设端口中。

【说明】

       (1)   d2只能是ALAX。当外设端口号不超过255时,d1操作数可直接写端口号码;端口号超过255时,必须先把端口号放在DX中,以DX作为d1操作数。

       (2)   d2AL时,该指令把AL中的8位数据送往d指定的外设端口;当d2AX时,该指令把AL中的8位数据送到d1对应的端口,把AH中的8位数据送往下一端口,即把16位数据送到d1对应的端口及下一端口中。

72.  与中断有关的指令

【格式】INT n

【功能】产生一次n号中断请求。由于这是中断指令,属于内中断,具有最高级别,CPU必然响应,因此改指令将导致一次n号中断处理过程。

【说明】

       (1)   指令格式中的n是一个立即数,用以代表中断号,有效范围是0255

       (2)   调用中断服务子程序。

       (3)   指令格式中的n只要求在0255之间,没有其他的限制。

【格式】IRET

【功能】从栈中弹出3个字,第一个弹出的送到IP,第2个到CS,第3个到PSW

【说明】这是专门为中断服务程序设计的一条指令,通常是中断服务程序的最后一条指令,它的功能与中断响应时硬件自动完成的动作相对应,从而保证不论是硬中断还是软中断,在中断服务结束后,CPU都能回到正确的位置继续执行。

【格式】CLI

【功能】把标志寄存器IF标志位清0,使CPU不响应可屏蔽外中断。

【格式】STI

【功能】把标志寄存器的IF标志位置1,允许CPU响应可屏蔽外中断

3.   常用伪指令

1.   OFFSET

【功能】把保留字OFFSET加在变量名字的前面,表示取该变量的偏移地址。

例如:MOV       BXOFFSET disp

2.   SEG

【功能】SEG伪指令放在某个变量的前面,表示取该变量所在段的段地址。

例如:MOV       AXSEG disp

3.   ASSUME

【格式】ASSUME  R1:S1,R2:S2,…

【功能】ASSUME伪指令占一行,用于指出后续程序中所使用的变量、标号等标识符在涉及到逻辑地址的段地址部分时,用哪个段寄存器作为缺省段地址。

【说明】

       (4)   【格式】中的Ri代表段寄存器名。必须是DSESSSCS四个之一,Si时段地址,只能是一个段名或者“SEG 变量名”的形式。

       (5)   RiSi是一组对应关系,表示Si段中的标识符都使用Ri作为缺省段寄存器。

       (6)   ASSUME可以一次指定多个对应关系,其间用逗号分隔。这种写法实际上是多个ASSUME的简写形式。

       (7)   在一个完整程序中,ASSUME伪指令在程序中最少出现一次,用于知名CS与哪一个段相对应。此时,CS对应的段必须是结束伪指令“END标号”中标号所在段,从而确定程序的第一条指令在哪个段的哪个位置,称作程序的入口地址。

       (8)   可以用ASSUME伪指令指定两个或两个以上的段寄存器作为同一个段中标识符的缺省段寄存器。当数据定义与指令写在同一个段中时,就会出现以CSDS甚至ES一起作为一个段的缺省段寄存器的情况。此时,有关数据的操作(取值、存数等)优先以DS作为段寄存器。

       (9)   ASSUME可以在程序的不同行上出现多次,并且可以对一个段寄存器进行两次或两次以上的对应关系指定。当程序中用ASSUME指定了一个段寄存器是某个段的缺省段寄存器后,在程序的后续行中一直有效,除非再次使用ASSUME伪指令改变该段寄存器与段的对应关系。

4.   PTR

【格式】类型    PTR 操作数

功能用于指定操作数类型的伪指令,它需要与类型保留字配合使用。

5.   ORG

【格式】ORG     地址表达式

【功能】ORG伪指令可以改变段中个变量定义时原有的次序,按指定情况安排各变量的偏移地址。

6.   $

【功能】$时汇编语言中的一个特殊符号,代表汇编程序在处理到$所在的位置时当前安排的偏移地址值。程序中出现的$可以作为常量看待,但是不同位置上的$,其代表的值是不同的。与一般的数据不同的是,通常所说的常量(数值)是没有类型的,包括“OFFSET 变量名”也没有类型,但$所表示的数据一定是字型。$一般作为字型变量定义时的一个初值使用。

7.   =EQU

【格式】标识符=数值表达式

【功能】定义常量

【格式】标识符  EQU     符号串

【功能】符号定义

4.   条件标志位的设置规则

1.   CF—进位和借位标志

CF主要用于记载两个数据相加或相减时,最高位向外的进位或借位情况,如果有进位或借位则CF被置为1,否则置0。参与运算的数据可以是16位的,也可以是8位的。

2.   SF—符号标志

SF用于记载两个有符号数运算结果的符号位。执行加减法运算时,运算结果的最高位的值会被复制到SF中。

3.   OF—溢出标志

如果两个带符号数进行加法和减法运算,结果超出了带符号数的表示范围,则OF将被置为1,这种现象称为有符号数加减法运算溢出,没有超出范围则OF被置为0

4.   ZF—零标志

ZF的设置比较简单,如果运算结果位0,则ZF被置为1,如果不为0ZF被置为0

5.   MOVADDSUBMULDIV指令对标志位的影响

       (1)   MOV指令不影响任何标志位,各标志位在MOV指令执行前是什么值,执行后仍然保持原值。

       (2)   ADD指令和SUB指令对标志位的设置情况在前面已经说明。

       (3)   MUL指令对ZFSF无定义,这是指指令执行后对这两个标志位的值有影响,但它们的值没有明确的定义,这与无影响是不同的;对于CFOF,如果乘积的高一半位0,即字节型乘法的结果AH=0或者字型乘法的结果DX=0,则CFOF都被置0,否则两个标志位都被置为1。这一设置规则可以用来检查字节相乘的积是字节还是字,或者检查字相乘的积是字还是双字。

       (4)   DIV指令对4个条件标志位都无定义(注意,不是无影响)

5.   变量

1.      汇编语言对标识符命名的完整规定是:

       (1)   可用符号包括字母、数字和特殊符号“?”、“@”、“$”、“%”、“_”。

       (2)   不允许用数字作为第一个符号。

       (3)   名字的长度没有严格的限制,但一般不超过10个符号。

       (4)   最少由一个符号构成,可以是字母、“ _”或“@”。

       (5)   汇编语言不区分字母的大小写。

2.      变量定义方法

【格式】变量定义的基本格式是:

变量名    类型       初值表

【说明】

       (1)   类型部分只能出现DBDWDDDQDT这几种内部保留字,用以说明初值表中的每个数据占几个字节,对应关系如下:

DB——字节型,每个数据占1个字节;

DW——字型,每个数据占2字节;

DD——双字型,每个数据占4字节;

DQDT不作说明。

       (2)   初值表是用逗号分隔的若干个数据项,每个数据项的值是变量的一个初值项,占据“类型”规定的字节数,所以初值表一方面说明变量的初值是多少,另一方面也指明了变量占多少字节的存储空间。

       (3)   对于DWDD类型,每个数据项的存储遵照“高字节在高地址,低字节在低地址”的原则。

       (4)   每个数据项的书写方法可以是任何数制的整数或者由整数构成的计算式,也可以时字符,如果用整数书写,可以是无符号数,也可以是带符号数。

       (5)   当类型是DB时,初值表可以是任意长度的字符串,而DW类型只允许长度不超过2的字符串。

       (6)   如果初值表需要填写若干个相同的值,可以用下面形式表示把一个值重复若干次:

重复次数      DUP(数据项)

       (7)   初值表中可以用问号“?”作为初值项,含义是用户程序不设定初值,而由汇编程序安排,对此汇编程序将在翻译时把这类初值项都以数值0填充。

       (8)   任何段中都可以写变量定义,也允许把指令与变量定义写在一个段内,但通常时把程序所用到的所有变量集中在一个段内进行定义,而把指令写在另一个段中。习惯上把定义变量的段称为数据段,写指令的段称为代码段或指令段。

3.      变量的三个属性

       (1)   段属性

取变量的段地址MOV   AXSEG d1

       (2)   偏移属性

取变量的偏移地址MOV AXOFFSET d1

取变量的偏移地址的另一种方法时用汇编语言中的一条专用指令:LEA

这两种取偏移地址方式的不同

   寻址方式不同。用OFFSET后接变量名的形式出现的操作数是立即寻址方式,LEA指令中的源操作数是内存型寻址方式。

   LEA指令在功能上比OFFSET更强。

       (3)   类型属性

4.      汇编程序在为变量安排内存时遵照下面的规则:

             (1)     同一段内的变量具有相同的段地址。

             (2)     按照段中变量定义的次序,依次对各变量分配偏移地址。

             (3)     除非有其它伪指令说明,段内的第一个变量被分配在偏移地址为0处。

             (4)     一个变量占据内存的字节数由其类型和初值表中的项数决定。

             (5)     除非有其他伪指令说明,一个变量分配完后,紧接着分配下一个变量。

6.   单字符和字符串的输入输出

1.   Dos1号子功能-单字符输入

【功能】从键盘读取一个按键的ASCII码值。

【入口参数】AH中放子功能号1

【出口参数】AL中是按键的ASCII码。

【说明】

       (1)   该功能只要求在执行INT 21H指令时AH的值是1,而不论AH在何时、以何种指令被赋的值,这一点对所有DOS系统功能调用都是一样的。

       (2)   调用时,计算机的屏幕上将出现一个闪烁的光标,等待操作人员按键;当有键被按下后,取出该键的ASCII值放入AL

       (3)   Pascal中的read标准过程不同,该功能只需要按一个键即可,而不像read一直要等到操作人员按下回车键。

       (4)   每次只读取一个按键,并且按下的符号会显示在屏幕上,退格键、回车键等特殊按键也会被当作有效输入。下面是几个特殊按键与AL中读取结果的对应关系:按ESC键-AL=1BH,按回车键-AL=0DH,按退格键-AL=08H

       (5)   如果读回车键的ASCII码值是0,表示按下的是一个扩展ASCII范围的键,这时可再读一次,以获得该键的扩展ASCII值。

       (6)   调用后不改变除AL外的其他寄存器的值,包括AH中的1

2.   DOS2号子功能-单字符输出

【功能】在屏幕上光标当前所在位置显示一个字符,并把光标向后移一格。

【入口参数】AH中放子功能号2DL中放待输出字符的ASCII值。

【出口参数】

【说明】

       (1)   该子功能在执行时不论DL中数据的来源如何,都当做是一格ASCII值,经过内部转换变成相应字符的形状显示在屏幕上。

       (2)   该子功能调用会改变寄存器AL的值,所以必要时其中的值可放在另一寄存器或内存中临时保存,其他寄存器的值都不受影响。

       (3)   有些特殊的ASCII值可以控制计算机产生特定的效果。比如,当DL中放入7并调用该子功能时,计算机的喇叭会发出“嘀”的一声响,而屏幕上并没有任何字符输出。部分特殊效果与ASCII值的对应关系:07H-发出嘀的一声,08H-光标在同一行上向左移动一格,0AH-光标在同列上向下移动一行,0DH-光标移到所在行的最左端。

3.   字符串输出

【入口参数】AH=9,是DOS的子功能号

        DS:DX=待输出字符串的首字符的逻辑地址

【说明】

       (1)   被输出的字符串的长度不限,但必须连续存放在内存的某个地方,且以ASCII值为24H的字符‘$’结束,中间可以含有回车符、换行符、响铃符等特殊功能符号,存放字符串的起始逻辑地址必须放在指定的寄存器DSDX中。

       (2)   $’符本身不输出到屏幕。

       (3)   调用结果是把字符串中的各个字符从光标当前所在位置起,依次显示在屏幕上,直至遇到‘$’为止,光标停在最后一个输出符号的后面。

       (4)   如果程序中需要输出‘$’,只能用2号子功能实现。

       (5)   9号子功能调用将影响AL的内容,不改变其余寄存器及标志位寄存器的值。

字符串输入

【入口参数】AH=0AH,是DOS的子功能号10

        DSDX=输入缓冲区的起始逻辑地址

【出口参数】DOS10号子功能在输入缓冲区中填写实际输入情况,即根据键盘输入情况,对图5.3中的“实际输入字符数”和“输入串的各个字符”部分进行填写。

【说明】

       (1)   输入缓冲区是一段连续的内存区,首地址必须在调用10子功能前放到指定的寄存器DSDX中。

       (2)   10号子功能在调用时等待操作员从键盘上按键,直到按下回车键为止,按键情况会显示在屏幕上,最后按下的回车键会导致回车操作。如果在按回车键之前发现输入有错误,可以使用退格键或向左的箭头进行修改。

       (3)   输入缓冲区的最前面一个字节的值由用户程序填写,用以指出允许输入的最大字符数。该值是字节型无符号数,有效范围是0255,最后按的回车键也计算在内。当已输入len1-1个字符后就只能按回车键了,按其他键都会被认为是不正确的输入而不被机器认可,并且喇叭还会发出“嘀”的一声响以示警告。如果len1=1,表示只能按1个键,这个键只能是回车键,按其他键都会有“嘀”的一声警告;如果len1=0,表示一个键都不能按,包括回车键在内的任何按键都会被拒绝并且发出“嘀”的警告声,但机器又在等待输入这一矛盾将导致无限期等待,即死机。

7.   堆栈和子程序

1.   定义堆栈段的方法

【格式】

        段名    SEGMENT STACK

                DW      nDUP(?)

        段名    ENDS

【说明】

       (1)   保留字STACK是堆栈段的专用符号,SEGMENT后面的保留字STACK表明这个段专供堆栈使用。

       (2)   段定义中用“DW        n DUP(?)”说明堆栈所用内存区的大小为2n字节,其中n是一个常量。可根据程序需要,调节堆栈段的大小。

       (3)   按基本格式定义的栈是一个空栈,栈中没有存放有效数据。

       (4)   为了使SSSP在程序执行时取得正确的值,必须在源程序中写一条伪指令:
ASSUME                SS
:堆栈段段名
但不需要像DSES一样在程序中用指令进行赋值。

2.   进栈
PUSH指令

3.   出栈
POP指令

4.   PUSHFPOPF指令

5.   定义子程序的方法

子程序名        PROC    类型

                指令序列

子程序名        ENDP

6.   参数传递的方法

       (1)   通用寄存器传值。

       (2)   通用寄存器传地址。

       (3)   标志寄存器传递逻辑型数据。

       (4)   用数据段中已定义的变量存放参数。

       (5)   用堆栈传递。

8.  

1.      宏定义

【格式】宏名 MACRO [形式参数表]

                   宏体

                   ENDM

【说明】

       (1)   “宏名”是一个标识符,一个程序中可以定义多个宏,对每一个宏必须以不同的标识符命名,且宏名不能与变量、标号、段名等标识符同名。

       (2)   汇编语言规定,宏定义的起始标记MACRO前面必须写宏的名字,而结束标记ENDM的前面却不允许写任何内容,写在起止标记之间的部分称为宏体,宏体部分通常是一段程序中需要重复使用的指令。序列。

       (3)   宏定义仅仅是告诉汇编程序,将来宏调用时复制的对象是什么,宏定义中的程序段并不是程序的一部分,也就是说,如果程序中定义了一个宏而没有调用它,汇编程序将忽略宏定义。

       (4)   宏定义可以写在程序的任何地方,但习惯上总是把宏定义写在程序的最前面。

       (5)   形式参数可以在宏体中的任何位置。

       (6)   宏的形式参数可以作为一个标识符的一部分,这时,必须用符号“&”把形式参数与标识符的其余部分分开。

2.      带标号的宏——LOCAL

9.   常驻内存技术

【驻留方法】在AH中放32H,在DX中放需要驻留的程序的节长度,然后以INT 21H指令调用DOS的结束并驻留子功能。

【说明】

       (1)   驻留前要告诉DOS,驻留程序的长度是多少。方法是把驻留长度放在DX中,长度单位是“节”而不是字节,1节等于16个字节。如果需要驻留的程序长度是n字节,则DX的值可通过下面的计算式算得:
                DX=
n/10H+1+10H
其中(你/10H+1是计算出驻留程序需要多少“节”,加1是为了预防驻留程序以字节计算的长度不是10的整倍数。再加16节是因为每个程序在调用内存时,操作系统都为它安排了一个称为“程序段前缀(PSP)”的专用内存区,并且放在程序的前面,这个程序段前缀的长度是256字节,刚好16节,它必须与需要驻留的程序一起驻留在内存。

10. 修改中断向量技术

【设置中断向量】

入口参数:AH=25H

          AL=中断号

             DSDX=新的中断服务程序的入口地址

调用:INT 21H

 
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值