目录:

1.进制转换

2.原码、反码、补码

3.寄存器

4.存储器的段结构

5.堆栈

6.传送类指令

7.算术运算类指令(不含乘除)

8.位操作类指令

9.标志位操作指令

10.标识符、常量与变量

11.标号

12.运算符

13.伪指令

14.源程序中段寄存器的装入以及DOS返回

15.分支程序设计

16.循环程序设计

17.子程序设计

18.乘除法运算

19.BCD码校正

20.符号扩展指令

21.串操作指令

内容:

一、进制转换

1.二进制转为十进制:

方法:按权相加法,即将二进制每位上的数乘以权,然后相加之和即是十进制数。

例:(101.101)2=(5.625)10

2.十进制转为二进制:

1)整数部分:

方法:除2取余法(短除法),即每次将整数部分除以2,记录余数,而商继续除以2,继续记录余数,这个步骤一直持续下去,直到商为0为止,最后读数时候,逆序读每一个余数。下面举例: 
例:将十进制的168转换为二进制

得出结果 将十进制的168转换为二进制,(10101000)2 
分析:第一步,将168除以2,商84,余数为0。 
第二步,将商84除以2,商42余数为0。 
第三步,将商42除以2,商21余数为0。 
第四步,将商21除以2,商10余数为1。 
第五步,将商10除以2,商5余数为0。 
第六步,将商5除以2,商2余数为1。 
第七步,将商2除以2,商1余数为0。 
第八步,将商1除以2,商0余数为1。 
第九步,读数,因为最后一位是经过多次除以2才得到的,因此它是最高位,读数字从最后的余数向前读,即10101000

2) 小数部分 
方法:乘2取整法,即将小数部分乘以2,然后取整数部分,剩下的小数部分继续乘以2,然后取整数部分,剩下的小数部分又乘以2,一直取到小数部分 
为零为止。如果永远不能为零,就同十进制数的四舍五入一样,按照要求保留多少位小数时,就根据后面一位是0还是1,取舍,如果是零,舍掉,如果是1,向入一位。换句话说就是0舍1入。读数要从前面的整数读到后面的整数,下面举例: 
例1:将0.125换算为二进制

得出结果:将0.125换算为二进制(0.001)2 
分析:第一步,将0.125乘以2,得0.25,则整数部分为0,小数部分为0.25; 
第二步, 将小数部分0.25乘以2,得0.5,则整数部分为0,小数部分为0.5; 
第三步, 将小数部分0.5乘以2,得1.0,则整数部分为1,小数部分为0.0; 
第四步,读数,从第一位读起,读到最后一位,即为0.001。

3.在二进制与八进制、十六进制转化的时候,三位二进制位对应一位八进制位,四位二进制位对应一位十六进制位。

4.其他进制间的转化可以借助十进制与二进制的转化。

二、原码、反码、补码

1.原码即真值+符号位。反码即原码取反。补码即反码+1。

2.由负数的真值或原码变补码的方法:自最低位向高位逐位检查,遇到第一个‘1’及以前(较低位)的各位‘0’保持不变,以后各高位取反。若是原码变补码,因最高位为符号位,不改变。

3.内存里皆以补码表示。对一个数求补,即求负。

4.反码算数运算若有进位则要回送给最低位,而补码算数运算若有进位则舍弃。

三、寄存器

1、寄存器汇总

AX(AH、AL)累加器;

BX(BH、BL)基址寄存器;

CX(CH、CL)计数寄存器;

DX(DH、DL)数据寄存器;

SP                 堆栈指针;

BP      基址指针;

SI      源变址寄存器;

DI      目的变址寄存器;

IP       指令指针;

FLAGS    标志寄存器;

CS      代码段寄存器;

DS      数据段寄存器;

SS      堆栈段寄存器;

ES      附加段寄存器。

其中,通用寄存器有:AX,BX,CX,DX,SP,BP,SI,DI。

2、标志寄存器的各标志位(复位(0)、置位(1))

1)溢出位OF,置位OV,复位NV。判断运算结果是否超出补码范围。溢出则置位。

2)方向位DF,置位DN,复位UP。决定串操作指令执行时指针寄存器的调整方向。DF=0时,正向处理(低位->高位),SI/DI递增。反之,亦然。

3)中断位IF,置位EI,复位DI。

4)符号位SF,置位NG,复位PL。与运算结果的最高位相一致。

5)零值位ZF,置位ZR,复位NZ。若运算结果为0,置位。否则,清0。

6)辅助进位位AF,置位AC,复位NA。若低4位出现进位或者借位,置位。否则,清0。

7)奇偶位PF,置位PE,复位PO。若运算结果低8位中‘1’个数为偶,则置位。否则,清0。

8)进位位CF,置位CY,复位NC。若最高位进位或者借位,则置位。在移位类指令中用来保存移出的0或1。

四、存储器的段结构

1.逻辑段的开始地址必须是任一小节的首地址。自0地址开始,每16字节为一小节。1MB的存储空间为65536小节。

2.逻辑段最大为1MB,最小为16B。

3.物理地址=16位段基值*16+偏移量

五、堆栈

1.在x86中,堆栈向下增长,是按字组织的,即最小数据单元为一个字。

2.当SP初始化时,它指向栈底+2字节单元,它的值就是这个堆栈的长度。

3.BP作为基址,一直不变;而SP作为栈顶指针,随栈顶的移动而移动。

4.压栈:PUSH。两步:SP<=SP-2;SP<=数据。

出栈:POP。两步:数据单元<=SP;SP<=SP+2。

PUSHF:将标志寄存器内容压栈。

POPF:将栈顶一个字数据送入标志寄存器。

六、传送类指令:源操作数与目的操作数类型必须一致(即同一个字节或字大小)。

1.MOV:MOV DEST,SRC  功能:DEST<=SRC。

源操作数与目的操作数不可同时为存储单元。对FLAGS没有影响。

2.XCHG:XCHG DEST,SRC  功能:交换DEST与SRC内容。

源操作数与目的操作数不可同时为存储单元。对FLAGS没有影响。

3.LAHF:LAHF  功能:将FLAGS低8位传送至AH,即把SF,ZF,AF,PF,CF分别传送至AH的第7,6,4,2,0位,AH其他位任意值。

对FLAGS没有影响。

4.SAHF:SAHF  功能:将AH的内容送入FLAGS低8位。

只影响SF,ZF,AF,PF,CF位。

5.PUSHF:PUSHF  功能:将标志寄存器内容压栈。

对FLAGS没有影响。

6.POPF:POPF  功能:将栈顶一个字数据送入标志寄存器。

影响FLAGS所有的位。

7.LEA:LEA DEST,SRC  功能:将SRC的有效地址EA送入DEST。其中,SRC必须为一个字节或字的存储器操作数,DEST必须为一个16位的通用寄存器。

对FLAGS没有影响。

8.LDS/LES:LDS/LES DEST,SRC  功能:将SRC所指32位存储单元的低16位送入DEST,而高16位送入DS(LDS指令)或ES(LES指令)。其中,DEST必须为一个16位通用寄存器,SRC必须是一个存储器操作数,该地址单元中存放着32位地址,低16位是偏移量,高16位是段基址。

对FLAGS没有影响。

9.XLAT (OPR):XLAT  (OPR)  功能:AL<=[BX+AL],即将BX与AL相加形成EA,再将地址对应的字节存储单元内容送入AL中。OPR可写可不写,没有实际作用,只是为了增加程序可读性而设置的,其内容为一个偏移量,和BX内容相同,存放一个表格的首地址。

对FLAGS没有影响。

七、算术运算类指令(不含乘除):源操作数与目的操作数类型必须一致(即同一个字节或字大小)。

1.ADD:ADD DEST,SRC  功能:DEST<=DEST+SRC

源操作数与目的操作数不可同时为存储单元。该指令会根据运算结果设置FLAGS的CF、PF、AF、ZF、SF和OF位。

2.ADC:ADC DEST,SRC  功能:DEST<=DEST+SRC+CF。带进位的加法。

源操作数与目的操作数不可同时为存储单元。该指令会根据运算结果设置FLAGS的CF、PF、AF、ZF、SF和OF位。

3.INC:INC DEST  功能:DEST<=DEST+1   其中,DEST可以为通用寄存器,也可以为存储单元。

该指令会根据运算结果设置FLAGS的PF、AF、ZF、SF和OF位,但不影响CF位。

4.SUB:SUB DEST,SRC   功能:DEST<=DEST-SRC

源操作数与目的操作数不可同时为存储单元。该指令会根据运算结果设置FLAGS的CF、PF、AF、ZF、SF和OF位。

5.SBB:SBB DEST,SRC  功能:DEST<=DEST-SRC-CF。带借位的减法。

源操作数与目的操作数不可同时为存储单元。该指令会根据运算结果设置FLAGS的CF、PF、AF、ZF、SF和OF位。

6.DEC:DEC DEST  功能:DEST<=DEST-1   其中,DEST可以为通用寄存器,也可以为存储单元。

该指令会根据运算结果设置FLAGS的PF、AF、ZF、SF和OF位,但不影响CF位。

7.NEG:NEG DEST  功能:DEST<=0-DEST  求补运算,也可以说是求负运算。

若字节操作数为-128(80H)或字操作数为-32768(8000H)时,该指令执行后,操作数不变,OF置位;否则,OF复位。若操作数为0,那么结果不变,CF复位;否则,置位。

该指令会根据运算结果设置FLAGS的CF、PF、AF、ZF、SF和OF位。

8.CMP:CMP DEST,SRC  功能:与SUB基本相同,唯一不同的是目的操作数不变。

源操作数与目的操作数不可同时为存储单元。该指令会根据运算结果设置FLAGS的CF、PF、AF、ZF、SF和OF位。

八、位操作类指令:源操作数与目的操作数类型必须一致(即同一个字节或字大小)

1.AND:AND DEST,SRC  功能:DEST<=DEST&SRC

源操作数与目的操作数不可同时为存储单元。该指令会根据运算结果设置FLAGS的PF、ZF、SF位,CF和OF位总复位,AF位不确定。

2.TEST:TEST DEST,SRC  功能:与AND基本相同,唯一不同的是,DEST不变。常用于测试目的操作数的某一位或某几位的状态。

源操作数与目的操作数不可同时为存储单元。该指令会根据运算结果设置FLAGS的PF、ZF、SF位,CF和OF位总复位,AF位不确定。

3.OR:OR DEST,SRC  功能:DEST<=DEST|SRC

源操作数与目的操作数不可同时为存储单元。该指令会根据运算结果设置FLAGS的PF、ZF、SF位,CF和OF位总复位,AF位不确定。

4.XOR:XOR DEST,SRC  功能:DEST<=DEST^SRC

源操作数与目的操作数不可同时为存储单元。该指令会根据运算结果设置FLAGS的PF、ZF、SF位,CF和OF位总复位,AF位不确定。

5.NOT:NOT DEST  功能:DEST<=~DEST(按位取反)

对FLAGS无影响。

6.SAL:SAL DEST,COUNT  功能:DEST<=DEST<<COUNT   算数左移指令:左移COUNT位,每移动一位,最低位补0,移出的最高位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必须用CL来代替COUNT的位置,移位位数由CL决定。

该指令会根据运算结果设置FLAGS的CF、PF、ZF、SF和OF位,AF位不确定。若移位位数为1次,且移位前后DEST最高位发生变化,则OF置位,否则复位。若移位位数>1,那么OF不确定。

7.SAR:SAR DEST,COUNT  功能:DEST<=DEST>>COUNT   算数右移指令:右移COUNT位,每移动一位,最高位补原有值,移出的最低位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必须用CL来代替COUNT的位置,移位位数由CL决定。

该指令会根据运算结果设置FLAGS的CF、PF、ZF、SF和OF位,AF位不确定。若移位位数为1次,且移位前后DEST最高位发生变化,则OF置位,否则复位。若移位位数>1,那么OF不确定。

8.SHL:SHL DEST,COUNT   功能:与SAL完全相同     逻辑左移指令

9.SHR:SHR DEST,COUNT  功能:逻辑右移指令:将DEST右移COUNT位,每移动一位,最高位补0,移出的最低位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必须用CL来代替COUNT的位置,移位位数由CL决定。

该指令会根据运算结果设置FLAGS的CF、PF、ZF、SF和OF位,AF位不确定。若移位位数为1次,且移位前后DEST最高位发生变化,则OF置位,否则复位。若移位位数>1,那么OF不确定。

10.ROL:ROL DEST,COUNT   功能:循环左移指令:每移动一位,把移出的最高位送入最低位和CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必须用CL来代替COUNT的位置,移位位数由CL决定。

只影响FLAGS的CF和OF位。若移位位数为1次,且移位前后DEST最高位发生变化,则OF置位,否则复位。若移位位数>1,那么OF不确定。

11.ROR:ROR DEST,COUNT   功能:循环右移指令:每移动一位,把移出的最低位送入最高位和CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必须用CL来代替COUNT的位置,移位位数由CL决定。

只影响FLAGS的CF和OF位。若移位位数为1次,且移位前后DEST最高位发生变化,则OF置位,否则复位。若移位位数>1,那么OF不确定。

12.RCL:RCL DEST,COUNT   功能:带进位的循环左移指令:每移动一位,把CF位送入最低位,把移出的最高位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必须用CL来代替COUNT的位置,移位位数由CL决定。

只影响FLAGS的CF和OF位。若移位位数为1次,且移位前后DEST最高位发生变化,则OF置位,否则复位。若移位位数>1,那么OF不确定。

13.RCR:RCR DEST,COUNT   功能:带进位的循环右移指令:每移动一位,把CF位送入最高位,把移出的最低位送入CF位。其中,如果COUNT=1,指令中可直接用1代替COUNT的位置;如果COUNT>1,那么必须用CL来代替COUNT的位置,移位位数由CL决定。

只影响FLAGS的CF和OF位。若移位位数为1次,且移位前后DEST最高位发生变化,则OF置位,否则复位。若移位位数>1,那么OF不确定。

九、标志位操作指令:

1.CLC:CLC   功能:CF=0

2.STC:STC   功能:CF=1

3.CMC:CMC   功能:CF=~CF

4.CLD:CLD   功能:DF=0

5.STD:STD   功能:DF=1

6.CLI:CLI   功能:IF=0

7.STI:STI   功能:IF=1

十、标识符、常量与变量

1.标识符组成规则:(无大小写区分)

(1)最多由31个字符组成;

(2)必须是以字母、‘?’、‘@’或‘_'开始;

(3)除第一个字符外,可以是字母、数字、‘?’、‘@’或‘_';

(4)不能是系统专用保留字。

2.常量表示:

(1)二进制常量:B(b)后缀;

(2)十进制常量:D(d)后缀,可省略;

(3)八进制常量:Q(q)或O(o)后缀;

(4)十六进制常量:H(h)后缀。对于A~F或a~f开头的十六进制数,必须在其前加一个0,以便与标识符区分开。

(5)实数常量:通常以十进制表示,由整数、小数和指数三部分组成。eg:-1.23E-4;9.0E+4。实数必须由伪指令DD、DQ、DT定义,实数不能出现在表达式中。另外,实数也可以用十六进制数直接说明其二进制数编码形式,但是这个十六进制数必须以0~9开头,不带符号,并在用R作后缀。

(6)字符串常量:用单引号括起来的一个或多个字符。有大小写区分。

3.变量定义:DB(字节变量)、DW(字变量)、DD(双字变量)、DQ(四字变量)、DT(五字变量)。

4.变量属性:

(1)SEG:所在段的段基值;

(2)OFFSET:距离段基址的字节数(偏移量);

(3)TYPE:所占存储单元的字节数。

5.变量预置:

(1)数值表达式:eg:VA  DW  1234H,0ABCDH   (依次以小尾方式存储,前一个单元12H放高字节,34H放低字节,后一单元同样)

(2)字符串表达式:每一个字符占一个字节单元。

1)使用DB:字符串不超过255个字符,大尾方式存放。eg:VA  DB  'ABCDEF'    (从’A'至'F'按地址递增排列)

2)使用DW:最多为两个字符组成的字符串分配存储单元,小尾方式存放。eg:VA  DW  'AB','CD','EF'    (地址递增排序为:'BADCFE')

3)使用DD:最多为两个字符组成的字符串分配存储单元,小尾方式存放,且第2个字单元存放0000H。eg:VA  DD  'AB','CD'  (地址递增排序为:'B''A''00''00''D''C''00''00')

(3)?表达式:预置随机值。eg:VA  DB  ?,?

(4)地址表达式:若该地址表达式为一变量名或者标号名,那么DW定义则是用其偏移量预置;DD定义则是用其段基值和偏移量预置,且段基值存高字单元,偏移量存低字单元。eg:VB  DD  VA    (VB的高字单元存放VA的段基值,低字单元存VA的偏移量)

(5)带DUP的表达式:格式:变量名 伪指令 n DUP(表达式)       功能:定义重复数据。

eg:VA      DW  10H DUP(4)     (即分配了10H个字单元,都每个字单元预置4)      VB  DB  10H DUP('ABCD')     (分配了10H个字符串’ABCD‘,共10H*4=40H个字节)

DUP可以嵌套使用。

eg:VA  DB  10H DUP(4 DUP(2),3,4)等价于 VA  DB  10H DUP(2,2,2,2,3,4)

(6)混合使用:eg:VA  DB  2 DUP(1),2 DUP(2,'B'),'123',1,2

十一、标号

1.属性:

(1)SEG:所在段的段基值;

(2)OFFSET:距离段基址的字节数(偏移量);

(3)类型属性Distance:NEAR、FAR。

2.类型属性设置:

(1)缺省默认NEAR。

(2)LABEL伪指令方式:建立新的标号并赋予指定类型属性。

eg:J1  LABEL  FAR

  J2:  MOV  AX,20H

两个标号J1和J2指向同一个地方,但类型属性不同。

十二、运算符

1.算术运算符:+、-、*、/、MOD、[]。

2.移位运算符:SHR(右移),SHL(左移)       eg:MOV  AX,11011011B SHL 3等价于MOV  AX,1101011000B

3.逻辑运算符:NOT、AND、OR、XOR     eg:MOV  AX,NOT  0F0H

4.关系运算符:EQ(相等为真A=B)、NE(不相等为真A!=B)、LT(A<B)、LE(A<=B)、GT(A>B)、GE(A>=B)。表达式都是常数或者同段的偏移量。如果是常数,按照无符号数比较;如果是变量,比较其偏移量。比较结果以真(全1)或假(全0)给出。   eg:MOV  AX,0FH EQ  1111B等价于MOV  AX,0FFFFH

5.数值返回运算符:

(1)SEG:返回变量或者标号的段基值。  eg:MOV  AX,SEG VA

(2)OFFSET:返回变量或标号的偏移量。eg:MOV  AX,OFFSET  VA

(3)TYPE:返回变量或标号的类型属性的数字形式:变量(BYTE(1)、WORD(2)、DWORD(4))、标号(NEAR(-1)、FAR(-2))      eg:MOV  AX,TYPE  VA

(4)LENGTH:仅用于变量之前,返回数组变量的元素个数。如果变量包含DUP,那么返回其重复值n;否则,返回1。  eg:MOV  AX,LENGTH VA

(5)SIZE:仅用于变量之前,返回数组变量所占的总字节数,即等价于LENGTH与TYPE的乘积。  eg:MOV  AX,SIZE VA

6.属性修改运算符:

(1)PTR:格式:类型 PTR 地址表达式       其中,地址表达式是指要修改或指定类型属性的标号、变量或用做地址指针的寄存器。不过,此修改仅在PTR语句里生效,临时修改而已。              eg:MOV  AX,WORD PTR DATA_BYTE[10]                    MOV  WORD PTR [SI],30H

(2)HIGH和LOW:只放在一个常数或在能确定其段基值或偏移量的地址表达式前面,用来分离运算对象的高字节和低字节。

eg:CONST  EQU  0ABCDH

  MOV  AH,HIGH  CONST

eg2:MOV  BH,HIGH(SEG  DA1)

十三、伪指令

1.EQU:等值伪指令:格式:符号名 EQU 表达式       其中,表达式可以是常数、数值表达式、字符串、地址表达式、标号、变量、指令助记符或关键字等。

eg:CONT EQU 5  ADR EQU ES:10H[BX]  VA EQU AX  VA EQU ADD。

不能重复定义,除非解除原先定义。

PURGE:用来解除EQU的定义。eg:PURGE CONT,ADR  注意:不能用PURGE解除被PUBLIC说明的符号的定义

2.=:格式:符号名=表达式。eg:CONT=5

与EQU的区别:(1)=允许重复定义;(2)=后的表达式不能是指令助记符或关键字。

3.DB(字节变量)、DW(字变量)、DD(双字变量)、DQ(四字变量)、DT(五字变量)

4.LABEL:与PTR功能相同,并且作用不受限制。

(1)改变标号属性:见前面的(十一.2.(2))。

(2)改变变量属性:

eg:VA  LABEL  BYTE

  VB  DW    20H DUP(0)

VA与VB段基值、偏移量都相同,但类型不相同。

5.段定义伪指令

格式:段名 SEGMENT [定位类型][组合类型][类别名]

     ......

   段名 ENDS

6.ASSUME:段寻址伪指令,指定逻辑段与段寄存器之间的关系。eg:ASSUME CS:CODE,DS:DATA

注意:(1)该指令不产生机器码。

   (2)若不指定,程序中使用变量名或地址表达式时要加上段前缀。eg:MOV  AX,ES:VA

   (3)该指令也可以取消或修改指定关系。

eg:ASSUME  ES:NOTHING  ;删除对ES的关联                ASSUME NOTHING  ;删除所有关联

7.PROC/ENDP:过程定义伪指令。

格式:过程名 PROC [NEAR/FAR]

   ......

   RET

   ......

   过程名 ENDP

8.ORG/$:定位伪指令和当前位置计数器。

eg:ORG  30H;该语句之后的指令或数据以当前值30H作为起始偏移量。       eg:ORG  $+20H  ;$即当前位置计数器

注意:ORG后的表达式以65536为模进行计算,即两个字节;而$与变量做减法时值为一个字节,如:VA2 EQU $-VA    此时VA2占据一个字节的内存。

9.TITLE:标题伪指令。格式:TITLE 标题名

10.END:程序结束伪指令。格式:END 起始地址              功能:一方面表示什么时候结束程序,一方面指定程序装入内存时根据起始地址对CS和IP装入对应的段基值和偏移量。

11.PUBLIC/EXTRN:前者用来定义全局符号,后者用来标明当前模块中要访问的本模块之外的符号。

十四、源程序中段寄存器的装入以及DOS返回

1.DS和ES的装入:

DS:MOV AX,DATA         MOV DS,AX

ES:MOV AX,DATA2         MOV ES,AX

2.SS的装入:

(1)系统自动装入:在定义堆栈逻辑段时,指定其组合类型为STACK,并在ASSUME中关联。eg:STACK1 SEGMENT STACK    ........

(2)手动法:

 STACK1    SEGMENT
DW 20H DUP(?)
TOP LABEL WORD
STACK1 ENDS CODE SEGMENT
......
MOV AX,STACK1
MOV SS,AX
MOV SP,OFFSET TOP
.......

3.CS的装入:

一般方法:程序结束伪指令END直接搞定,装入CS和IP。格式:END 起始地址

4.DOS返回:

(1)用4CH系统功能调用实现返回:即在程序结束时加上:MOV  AH,4CH                 INT  21H

(2)用程序段前缀实现返回:三步:1)把程序编制成一个过程,设置为FAR。2)把PSP起始地址压栈。3)程序结束时RET。

 CODE    SEGMENT
PROC1 PROC FAR
ASSUME CS:CODE,...
START: PUSH DS ;保存PSP首地址,RET返回时将其装入CS
MOV AX,
PUSH AX ;RET返回时把00H作为偏移量装入IP
...
RET
PROC1 ENDP
CODE ENDS
END START

十五、分支程序设计

1.无条件转移指令JMP:不影响FLAGS。

(1)段内转移:只需要修改IP值。

1)直接寻址:JMP TARGET  (TARGET为标号)    指令编码2~3字节。

2)间接寻址:JMP REG或者JMP ADDR   (REG为寄存器,ADDR为字存储单元,存储着目标地址)  指令编程2~4字节

eg:JMP CX;             JMP WORD PTR [BX];              JMP VA;

(2)段间转移:需要修改CS和IP值。

1)直接寻址:JMP TARGET  指令编码5字节。

2)间接寻址:JMP ADDR  (ADDR为双字存储单元,存储目标地址)      指令编码2~4字节             eg:JMP DWORD PTR VA[BX]

2.条件转移指令:格式:JXX TARGET    (TARGET为标号)      执行的操作:IP<=TARGET的偏移量                  指令编码都是2字节。

该系列指令只能在段内直接寻址,并且转移范围在从下一条指令算起的-128~127个字节的地址范围内。且不影响FLAGS。

(1)简单条件转移指令:

JC     CF=1  有进位/借位

JNC     CF=0  无进位/借位

JE/JZ     ZF=1  相等/等于0

JNE/JNZ   ZF=0  不相等/不等于0

JS      SF=1  为负数

JNS    SF=0  为正数

JO      OF=1  有溢出

JNO    OF=0  无溢出

JP/JPE     PF=1  有偶数个1

JNP/JPO   PF=0  有奇数个1

(2)无符号数条件转移指令:假设此指令前进行无符号数A、B的比较,指令的操作为A-B

JA/JNBE  CF=0&&ZF=0  A>B

JAE/JNB  CF=0||ZF=1   A>=B

JB/JNAE  CF=1&&ZF=0  A<B

JBE/JNA  CF=1||ZF=1    A<=B

(3)有符号数条件转移指令:假设此指令前进行有符号数A、B的比较,指令的操作为A-B

JG/JNLE  SF=OF&&ZF=0  A>B

JGE/JNL  SF=OF||ZF=1   A>=B

JL/JNGE  SF!=OF&&ZF=0  A<B

JLE/JNG  SF!=OF||ZF=1  A<=B

3.对于多路分支,可以使用跳转表法。

(1)跳转表由入口地址构成:

 DATA    SEGMENT
ATABLE DW V1,V2
DW V3,V4
N DB
Y DW 0F786H
DATA ENDS
STACK1 SEGMENT STACK
DW 20H DUP(?)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK1
START: MOV AX,DATA
MOV DS,AX
MOV BX,OFFSET ATABLE
XOR AH,AH
MOV AL,N
DEC AL
SHL AL,
ADD BX,AX
JMP WORD PTR [BX]
V1:
ADD Y,
JMP DONE
V2:
ADD Y,
JMP DONE
V3:
ADD Y,
JMP DONE
V4:
ADD Y,
JMP DONE
DONE: MOV AH,4CH
INT 21H
CODE ENDS
END START

(2)跳转表由JMP指令构成:

 DATA    SEGMENT
N DB
Y DW 0F786H
DATA ENDS
STACK1 SEGMENT STACK
DW 20H DUP(?)
STACK1 ENDS
CODE SEGMENT
ASSUME CS:CODE,DS:DATA,SS:STACK1
START: MOV AX,DATA
MOV DS,AX
MOV CX,OFFSET ATABLE
XOR BH,BH
MOV BL,N
DEC BL
MOV AL,BL
SHL BL,
ADD BX,CX
JMP BX
ATABLE:
JMP V1
JMP V2
JMP V3
JMP V4
V1:
ADD Y,
JMP DONE
V2:
ADD Y,
JMP DONE
V3:
ADD Y,
JMP DONE
V4:
ADD Y,
JMP DONE
DONE: MOV AH,4CH
INT 21H
CODE ENDS
END START

 十六、循环程序设计

循环控制指令:使用CX作为计数器,采用段内直接寻址,操作数为标号,不影响FLAGS。格式都是:LOOP TARGET。指令编码2字节。并且转移范围在从下一条指令算起的-128~127个字节的地址范围内。

LOOP:     首先CX<=CX-1。如果CX!=0,则IP<=TARGET的偏移量;否则,顺序执行。

LOOPZ/LOOPE:首先CX<=CX-1。如果CX!=0&&ZF=1,则IP<=TARGET的偏移量;否则,顺序执行。

LOOPNZ/LOOPNE:首先CX<=CX-1。如果CX!=0&&ZF!=1,则IP<=TARGET的偏移量;否则,顺序执行。

JCXZ:      测试CX==0,但不修改其值。如果CX=0,则IP<=TARGET的偏移量;否则,顺序执行。

十七、子程序设计

1.子程序定义格式:

过程名 PROC [NEAR/FAR]

   ......

   RET

   ......

过程名 ENDP

2.段内调用:

(1)直接调用:CALL PROC_NAME(过程名)      指令操作:将IP压栈,IP<=子程序入口偏移量                指令编码3字节

(2)间接调用:CALL REG或者CALL W_ADDR  (操作数为通用寄存器或者变量、标号)            指令操作:将IP压栈,IP<=REG/W_ADDR.     指令编码2~4字节

3.段间调用:

(1)直接调用:CALL PROC_NAME(FAR属性)           指令操作:依次将CS、IP压栈,CS<=子程序段基值,IP<=子程序偏移量。         指令编码5字节。

(2)间接调用:CALL DW_ADDR        (操作数为变量或标号)             指令操作:依次将CS、IP压栈,IP<=第一个字存储单元内容,CS<=第二个字存储单元内容。         指令编码2~4字节。

4.返回指令RET:

(1)段内返回:RET 或 RET n(n为偶数)。     指令操作:对IP出栈。如果带有n,则SP<=SP+n。           不带操作数时编码为C3,单字节;带操作数时3字节。

(2)段间返回:RET 或 RET n(n为偶数)。     指令操作:先对IP出栈,再对CS出栈。如果带有n,则SP<=SP+n。  不带操作数时编码为CB,单字节;带操作数时3字节。

其中,RET n的作用是将call指令前压栈的参数数据占据的空间释放。

5.子程序与主程序之间的参数传递可以通过寄存器、堆栈或者地址表实现。这里不表。

十八、乘除法运算

1.无符号数乘法MUL:MUL OPRD     只影响FLAGS中的CF和OF。若乘积的高半部分不为0,则CF=OF=1;否则,CF=OF=0。其他标志位不确定。

字节乘法:AX=AL*OPRD     乘积放入AX中。

字乘法:   DX:AX=AX*OPRD      乘积的高字放入DX,低字放入AX。

2.带符号数乘法IMUL:IMUL OPRD         只影响FLAGS中的CF和OF。如果乘积的高半部分不是低半部分的符号扩展,则CF=OF=1;否则,CF=OF=0。其他标志位不确定。

字节乘法:AX=AL*OPRD     乘积放入AX中。

字乘法:   DX:AX=AX*OPRD      乘积的高字放入DX,低字放入AX。

3.无符号数除法DIV:DIV OPRD     不影响FLAGS。

字节除法:被除数AX  除数OPRD  商AL  余数AH

字除法:   被除数DX:AX除数OPRD  商AX  余数DX

如果除数为0或者商AL>0FFH或者AL>0FFFFH,转入0型中断。

4.带符号数除法IDIV:IDIV OPRD    不影响FLAGS。

字节除法:被除数AX  除数OPRD  商AL  余数AH

字除法:   被除数DX:AX除数OPRD  商AX  余数DX

如果除数为0或者商AL>7FH或者AL>7FFFH,转入0型中断。

十九、BCD码校正:需要注意的是,除法校正指令写在除法运算指令之前,而其他指令都是写在相应运算指令之后。

1.x86采用先用二进制运算指令进行算术运算,再用BCD码校正。

2.组合型BCD码:一个字节表示两个十进制数;

非组合型BCD码:一个字节只表示一位十进制数。

3.非组合型加法校正指令AAA:若AL中低4位的数>9,或AF=1,则AL<=AL+6,AH<=AH+1,且AL中高4位清0,AF、CF置一。

4.组合型加法校正指令DAA:若AL中低4位>9或者AF=1,则AL<=AL+6,并置AF=1。

              若AL中高4位>9或者CF=1,则AL<=AL+60H,并置CF=1。

5.非组合型减法校正指令AAS:若AL中低4位>9或者AF=1,则依次执行:AL<=AL-6,AH<=AH-1,AL高4位清0,CF=AF=1。

6.组合型减法校正指令DAS:若AL中低4位>9或者AF=1,则AL<=AL-6,并置AF=1。

              若AL中高4位>9或者CF=1,则AL<=AL-60H,并置CF=1。

7.非组合型乘法校正指令AAM:对在AL中的积(由两个组合的BCD码相乘的结果)进行校正,产生两个非组合的BCD码。

               指令的操作:把AL的值除以10,商放在AH中,余数放在AL中。

该指令影响FLAGS的SF、ZF和PF。

8.非组合型除法校正指令AAD:把存放在AH和AL中的两位非组合BCD码调整为一个二进制数,存放在AL中。

               指令的操作:AL<=AH*10+AL,AH=0。

该指令影响FLAGS的SF、ZF和PF。

二十、符号扩展指令

1.字节扩展为字 CBW:CBW   功能:当AL最高位为1,则AH变为1111B;当AL最高位为0,则AH变为0000B。

不影响FLAGS。

2.字扩展为双字 CWD:CWD   功能:当AX最高位为1,则DX变为FFFFH;当AX最高位为0,则DX变为0000H。

不影响FLAGS。

二十一、串操作指令

1.串操作指令的源操作数地址由DS:[SI]提供,目的串操作数地址由ES:[DI]提供。每条串操作指令每次仅对串中的一个字或字节单元进行操作,且同时自动修改SI或者DI。若DF=0,则SI/DI递增1个字节或字;若DF=1,则SI/DI递减1个字节或字。还有重复前缀指令,重复次数由CX决定。

2.1.取串指令LODS:LODS 源串

                 LODSB   ;取源串一个字节         等价于:MOV  AL,[SI]                             INC/DEC  SI

              LODSW  ;取源串一个字            等价于:MOV  AX,[SI]              ADD/SUB  SI,2

不影响FLAGS。

2.2.存串指令STOS:STOS 目的串

                 STOSB   ;送入目的串一个字节         等价于:MOV  [DI],AL                             INC/DEC  DI

             STOSW  ;送入目的串一个字            等价于:MOV    [DI],AX              ADD/SUB  DI,2

不影响FLAGS。

2.3.串传送指令MOVS:MOVS 目的串,源串

                    MOVSB   ;字节传送                     等价于:把BYTE PTR [SI]传给[DI],并修改SI和DI。

             MOVSB   ;字传送                     等价于:把WORD PTR [SI]传给[DI],并修改SI和DI。

不影响FLAGS。

2.4.串比较指令CMPS:CMPS 源串,目的串

             CMPSB     ;字节比较

             CMPSW    ;字比较

影响FLAGS。

需要注意的是:串比较指令在比较时是源操作数减目的操作数,而一般比较指令是目的操作数减源操作数。

2.5.串搜索指令SCAS:SCAS 目的串

       SCASB

         SCASW

影响FLAGS。

查找方法:在目的串中找AX或AL指定的内容。用AX或AL内容减去目的串中一个字或字节,相减结果反映在FLAGS中。每查找一次,按照DF修改DI。

3.重复前缀指令REP:前面的指令都是操作一个字节或字,若操作一个字符串,则可用REP指令。每执行一次串操作指令,CX减1,直到CX=0为止。

REP:重复执行条件是:CX!=0                           用于LODS、STOS、MOVS对应指令之前。

REPE/REPZ:重复执行条件是:CX!=0&&ZF=1。  用于CMPS、SCAS对应指令之前。

REPNE/REPNZ:重复执行条件是:CX!=0&&ZF=0。  用于CMPS、SCAS对应指令之前。

实验部分:可以参考http://wenku.baidu.com/view/8d9f9aef0975f46527d3e10b.html。

x86汇编知识点汇总的更多相关文章

  1. 清华大学OS操作系统实验lab1练习知识点汇总

    lab1知识点汇总 还是有很多问题,但是我觉得我需要在查看更多资料后回来再理解,学这个也学了一周了,看了大量的资料...还是它们自己的80386手册和lab的指导手册觉得最准确,现在我就把这部分知识做 ...

  2. C# inline-asm / 嵌入x86汇编

    C#可不可以嵌入汇编 可以 在我眼中C#作为一个介于中上层语言是不可能不可以 置入汇编代码的 为什么会被我认为中上层语言呢 从C#保留指针就可以看出 我知 道有很多人一定不会相信C#可以使用汇编代码 ...

  3. 为什么X86汇编中的mov指令不支持内存到内存的寻址?

    在X86汇编中,MOV [0012H], [0016H]这种指令是不允许的,至少得有一个操作数是寄存器.当然,这种问题在用高级语言的时候看不到,感觉好像基本上都是从内存到内存啊,为毛到了汇编就不行了? ...

  4. nginx几个知识点汇总

    WHY? 为什么用Nginx而不用LVS? 7点理由足以说明一切:1 .高并发连接: 官方测试能够支撑 5 万并发连接,在实际生产环境中跑到 2 - 3 万并发连接数.?2 .内存消耗少: 在 3 万 ...

  5. 对X86汇编的理解与入门

    本文描述基本的32位X86汇编语言的一个子集,其中涉及汇编语言的最核心部分,包括寄存器结构,数据表示,基本的操作指令(包括数据传送指令.逻辑计算指令.算数运算指令),以及函数的调用规则.个人认为:在理 ...

  6. 寄存器理解 及 X86汇编入门

    本文整理自多材料源,感谢原址分享,请查看末尾Url I, 汇编语言分类: 汇编语言和CPU息息相关,但是不能把汇编语言完全等同于CPU的机器指令.不同架构的CPU指令并不相同,如x86,powerpc ...

  7. python全栈开发 * 10知识点汇总 * 180612

    10 函数进阶 知识点汇总 一.动态参数 形参的第三种1.动态接收位置传参 表达:*args (在参数位置编写 * 表⽰接收任意内容) (1)动态位置参数def eat(*args): print(a ...

  8. X86汇编概要

    来自:https://www.cnblogs.com/jiftle/p/8453106.html 本文翻译自:http://www.cs.virginia.edu/~evans/cs216/guide ...

  9. x86汇编之十(使用字符串)

    x86汇编之十(使用字符串) 转自网络,出处不详 一.传送字符串 Intel提供了完整的字符串传送指令,就像是MOV指令一样. 1.MOVS指令 1)movs指令格式 把字符串从一个位内存位置传送到另 ...

随机推荐

  1. PHP简单查询界面

    <html> <style type='text/css'> table {border-collapse:collapse;} td {border:solid 1px #d ...

  2. phpstorm使用教程

    phpstorm包含了webstorm的全部功能,更能够支持php代码.PhpStorm是一个轻量级且便捷的PHP IDE,其旨在提供用户效率,可深刻理解用户的编码,提供智能代码补全,快速导航以及即时 ...

  3. td高度不随内容变化display:block;display:block;display:block;display:block;display:block;

    在TD里加个DIV就可以解决!CSS对应改成#aaa td div{ height:236px; overflow:hidden; 在TD里加个DIV就可以解决!CSS对应改成#aaa td div{ ...

  4. JAVA的非对称加密算法RSA——加密和解密

    原文转载至:https://www.cnblogs.com/OnlyCT/p/6586856.html 第一部分:RSA算法原理与加密解密 一.RSA加密过程简述 A和B进行加密通信时,B首先要生成一 ...

  5. VS:error C3872: '0xe044': this character is not allowed in an identifier解决方法

     从网上粘贴代码到编译器中直接编译的话,会报这个错误,但是代码看上去是没有问题的,实际的原因是因为我们粘贴代码的时候粘贴了中文字符进来. 解决方法:就是把这段代码放到记事本里,选择替换把中文输入空 ...

  6. CSS3基础知识(一)

    结构选择器 :nth-child(n) 第几个元素 从1开始设置 :nth-child(2n) 偶数元素 从0开始设置 :nth-child(2n+1) 奇数元素 :nth-of-type(n) :f ...

  7. 讨论Android开发中的MVC设计思想

    最近闲着没事,总是想想做点什么.在时间空余之时给大家说说MVC设计思想在Android开发中的运用吧! MVC设计思想在Android开发中一直都是一套比较好的设计思想.很多APP的设计都是使用这套方 ...

  8. PHP笔记(配置UPUPW环境)

    一,首先修改HOSTS将127.0.0.1 gzt.com加入,前面不要# 二,GZT.COM的数据库文件在--------------配置在: - 三,配置 主要修改这几个  $BASIC=arra ...

  9. OpenACC 计算规约时发现的小坑

    ▶ 使用 OpenACC 的 parallel 构件来计算规约,主要想说的是 win10 pgi 和 win10 WSL pgi 结果的不同和关于 for 循环的一个小坑 ● 正常的代码 #inclu ...

  10. ASCII和万国码

    ASCII和万国码 什么是ASCII 计算机的起初是使用内存中的0101来表示数和机器码.如何用内存中的bit来表示文本一直困扰着人们,毕竟人类主要的信息展示是文字,而不是苦涩的0101.后来ASCI ...