主题:一些常用汇编指令的注意事项
我学习的时候整理出来的,希望对新手有所帮助,我总时犯这方面的错误
[b]数据传送指令[/b]
[b]MOV:[/b]寄存器之间传送注意,源和目的不能同时是段寄存器;代码段寄存器CS不能作为目的;指令指针IP不能作为源和目的。立即数不能直接传送段寄存器。源和目的操作数类型要一致;除了串操作指令外,源和目的不能同时是存储器操作数。
[b]XCHG[/b]交换指令:操作数可以是通用寄存器和存储单元,但不包括段寄存器,也不能同时是存储单元,还不能有立即数。
[b]LEA 16位寄存器 存储器操作数 [/b]传送有效地址指令:必须是一个16位寄存器和存储器操作数。
[b]LDS 16位寄存器 存储器操作数 [/b] 传送存储器操作数32位地址,它的16位偏移地址送16位寄存器,16位段基值送入DS中。
[b]LES[/b] :同上,只是16位段基址送ES中。
[b]堆栈操作指令[/b]
[b]PUSH 操作数[/b],操作数不能使用立即数,
[b]POP 操作数,[/b] 操作数不能是CS和立即数
[b]标志操作指令[/b]
[b]LAHF:[/b]把标志寄存器低8位,符号SF,零ZF,辅助进位AF,奇偶PF,进位CF传送到AH指定的位。不影响标志位。
[b]SAHF:[/b]与上相反,把AH中的标志位传送回标志寄存器。
[b]PUSHF:[/b]把标志寄存器内容压入栈顶。
[b]POPF:[/b]把栈顶的一个字节传送到标志寄存器中。
[b]CLC:[/b]进位位清零。
[b]STC:[/b]进位位为1。
[b]CMC:[/b]进位位取反。
[b]CLD:[/b]使方向标志DF为零,在执行串操作中,使地址按递增方式变化。
[b]STD:[/b]DF为1。
[b]CLI:[/b]清中断允许标志IF。Cpu不相应来自外部装置的可屏蔽中断。
[b]STI:[/b]IF为1。
[b]加减运算指令[/b]
[b]注意: 对于此类运算只有通用寄存器和存储单元可以存放运算结果。如果参与运算的操作数有两个,最多只能有一个存储器操作数并且它们的类型必须一致。[/b]
[b]ADD[/b]。
[b]ADC[/b]:把进位CF中的数值加上去。
[b]INC:[/b]加1指令
[b]SUB。[/b]
[b]SBB:[/b]把进位CF中数值减去。
[b]DEC:[/b]减1指令。
[b]NEG 操作数:[/b]取补指令,即用0减去操作数再送回操作数。
[b]CMP:[/b]比较指令,完成操作数1减去操作数2,结果不送操作数1,但影响标志位。可根据ZF(零)是否被置1判断相等;如果两者是无符号数,可根据CF判断大小;如果两者是有符号数,要根据SF和OF判断大小。
乘除运算指令
[b]MUL 操作数 :[/b]无符号数乘法指令。操作数不能是立即数。操作数是字节与AL中的无符号数相乘,16位结果送AX中。若字节,则与AX乘,结果高16送DX,低16送AX。如乘积高半部分不为零,则CF、OF为1,否则为0。所以CF和OF表示AH或DX中含有结果的有效数。
[b]IMUL 操作数 :[/b]有符号数乘法指令。基本与MUL相同。
[b]DIV 操作数 :[/b]被除数是在AX(除数8位)或者DX和AX(除数16位),操作数不能是立即数。如果除数是0,或者在8(16)位除数时商超过8(16)位,则认为是溢出,引起0号中断。IDIV:有符号除法指令,当除数为0,活着商太大,太小(字节超过127,-127字超过32767,-32767)时,引起0号中断。
[b]符号扩展指令[/b]
[b]CBW,CWD:[/b] 把AL中的符号扩展到寄存器AH中,不影响各标志位。CWD则把AX中的符号扩展到DX,同样不影响标志位。[b]注意:在无符号数除之前,不宜用这两条指令,一般采用XOR清高8位或高16位。[/b]
[b]逻辑运算指令与位移指令[/b]
[b]注意:只能有一个存储器操作数;只有通用寄存器或存储器操作数可作为目的操作数,用于存放结果;操作数的类型必须一致。[/b]
[b]NOT:[/b]取反,不影响标志位。
[b]AND 操作数1 操作数2:[/b]操作结果送错作数1,标志CF(进位)、OF(溢出)清0,PF(奇偶)ZF(0标志) SF(符号)反映运算结果,AF(辅助进位)未定义。自己与自己AND值不变,她主要用于将操作数中与1相与的位保持不变,与0相与清0。(都为1时为1)
[b]OR 操作数1 操作数2:[/b]自己与自己OR值不变,CF(进位)、OF(溢出)清0,PF(奇偶)ZF(0标志)SF(符号)反映运算结果,AF(辅助进位)未定义。她使用于将若干位置1:与1相或为1,保持不变的位与0相或。(都为0时为0)
[b]XOR 操作数1 操作数2:[/b]自己与自己异或结果为0,标志CF(进位)、OF(溢出)清0,PF(奇偶)ZF(0)SF(符号)反映运算结果,AF(辅助进位)未定义。主要用于将若干位取反的操作:与1异或取反,与0异或保持不变。(相同为0,不同为1)
[b]TEST 操作数1 操作数2:[/b]测试指令,和AND相同,但结果不送操作数1,各标志位同AND操作。
[b]位移指令[/b]
[b]SAL/SHL 操作数 1或CL:[/b]算术左移与逻辑左移进行相同的动作,操作数是通用寄存器或者存储器操作数,位移数为1或为CL;最高位移CF(进位),右边用0补位。左移一次相当源操作数乘2。
[b]SAR 操作数 1或CL:[/b]算术右移,位移数为1或为CL;操作数是通用寄存器或者存储器操作数,左符号位保持不变,移出最低位进CF(进位)。相当源操作数除2。
[b]SHR 操作数 1或CL :[/b]逻辑右移,操作数是通用寄存器或者存储器操作数,位移数为1或为CL;左边用0补足,移出的最低位进CF(进位)对于无符号数,右移一位相当于除2。
[b]ROL/ROR 操作数 1或CL: [/b]不带进位左移/右移,操作数是通用寄存器或者存储器操作数,位移数为1或为CL。
[b]RCL/RCR 操作数 1或CL:[/b] 带进位左移/右移,CF(进位)参与循环。操作数是通用寄存器或者存储器操作数,位移数为1或为CL。
[b]转移指令
注意:由于代码段可分为多个段,所以根据转移时是否重置代码段寄存器CS内容,可分为段内转移和段间转移。段内转移仅重置IP的转移,转移后指令仍在同一代码段中。段间转移重置CS,所以转移后继续执行的指令在另一个段中。[/b]
[b]JMP 标号 :[/b]无条件跳转到标号位置执行,段内直接转移指令。地址差用一个字节表示为短转移,用一个字表示为近转移。
[b]JMP 通用寄存器/存储单元:[/b]无条件段间间接转移指令,操作数给定的是目标地址处。
[b]JMP FAR PTR 标号:[/b]无条件段间直接转移指令,她的具体动作是把指令中包含的目标地址的段值和偏移分别置茹CS和IP。
[b]JMP 操作数:[/b]无条件段间间接转移指令,操作数是双字存储单元,给定目标地址,低字节送IP,高字节送CS。
[b]条件转移指令:[/b]所有的条件转移指令都是段内转移。她是由J加上相应的含义字母组合成。有符号数关系G(大于),E(等于),L(小于);无符号数关系A(高于)、E(等于)和B(低于);字母N表示“不”:NB(不小于),NE(不等于)。
[b]循环指令[/b]
[b]LOOP 标号[/b]:她使寄存器CX减1,若结果不等于0则转到标号,否则顺序执行LOOP指令后的指令。最多循环65536次。
[b]LOOPE/LOOPZ 标号:[/b]等于/全零循环指令。CX的值减1,如果结果不等于0,并且ZF(0标志)等于1,则转移到标号。
[b]LOOPNE/LOOPNZ 标号:[/b]不等于/非零循环指令,CX的值减1,如果结果不等于0,并且ZF(0标志)等于0,则跳转到标号。
[b]JCXZ 标号:[/b] 该指令实现当寄存器CX的值等于0转移到标号,否则顺序执行。通常该指令用在循环开始前,以便在循环次数位0时,跳过循环体。
另外如果有整理错误的地方,还请各位前辈指正。谢谢了。
[b]数据传送指令[/b]
[b]MOV:[/b]寄存器之间传送注意,源和目的不能同时是段寄存器;代码段寄存器CS不能作为目的;指令指针IP不能作为源和目的。立即数不能直接传送段寄存器。源和目的操作数类型要一致;除了串操作指令外,源和目的不能同时是存储器操作数。
[b]XCHG[/b]交换指令:操作数可以是通用寄存器和存储单元,但不包括段寄存器,也不能同时是存储单元,还不能有立即数。
[b]LEA 16位寄存器 存储器操作数 [/b]传送有效地址指令:必须是一个16位寄存器和存储器操作数。
[b]LDS 16位寄存器 存储器操作数 [/b] 传送存储器操作数32位地址,它的16位偏移地址送16位寄存器,16位段基值送入DS中。
[b]LES[/b] :同上,只是16位段基址送ES中。
[b]堆栈操作指令[/b]
[b]PUSH 操作数[/b],操作数不能使用立即数,
[b]POP 操作数,[/b] 操作数不能是CS和立即数
[b]标志操作指令[/b]
[b]LAHF:[/b]把标志寄存器低8位,符号SF,零ZF,辅助进位AF,奇偶PF,进位CF传送到AH指定的位。不影响标志位。
[b]SAHF:[/b]与上相反,把AH中的标志位传送回标志寄存器。
[b]PUSHF:[/b]把标志寄存器内容压入栈顶。
[b]POPF:[/b]把栈顶的一个字节传送到标志寄存器中。
[b]CLC:[/b]进位位清零。
[b]STC:[/b]进位位为1。
[b]CMC:[/b]进位位取反。
[b]CLD:[/b]使方向标志DF为零,在执行串操作中,使地址按递增方式变化。
[b]STD:[/b]DF为1。
[b]CLI:[/b]清中断允许标志IF。Cpu不相应来自外部装置的可屏蔽中断。
[b]STI:[/b]IF为1。
[b]加减运算指令[/b]
[b]注意: 对于此类运算只有通用寄存器和存储单元可以存放运算结果。如果参与运算的操作数有两个,最多只能有一个存储器操作数并且它们的类型必须一致。[/b]
[b]ADD[/b]。
[b]ADC[/b]:把进位CF中的数值加上去。
[b]INC:[/b]加1指令
[b]SUB。[/b]
[b]SBB:[/b]把进位CF中数值减去。
[b]DEC:[/b]减1指令。
[b]NEG 操作数:[/b]取补指令,即用0减去操作数再送回操作数。
[b]CMP:[/b]比较指令,完成操作数1减去操作数2,结果不送操作数1,但影响标志位。可根据ZF(零)是否被置1判断相等;如果两者是无符号数,可根据CF判断大小;如果两者是有符号数,要根据SF和OF判断大小。
乘除运算指令
[b]MUL 操作数 :[/b]无符号数乘法指令。操作数不能是立即数。操作数是字节与AL中的无符号数相乘,16位结果送AX中。若字节,则与AX乘,结果高16送DX,低16送AX。如乘积高半部分不为零,则CF、OF为1,否则为0。所以CF和OF表示AH或DX中含有结果的有效数。
[b]IMUL 操作数 :[/b]有符号数乘法指令。基本与MUL相同。
[b]DIV 操作数 :[/b]被除数是在AX(除数8位)或者DX和AX(除数16位),操作数不能是立即数。如果除数是0,或者在8(16)位除数时商超过8(16)位,则认为是溢出,引起0号中断。IDIV:有符号除法指令,当除数为0,活着商太大,太小(字节超过127,-127字超过32767,-32767)时,引起0号中断。
[b]符号扩展指令[/b]
[b]CBW,CWD:[/b] 把AL中的符号扩展到寄存器AH中,不影响各标志位。CWD则把AX中的符号扩展到DX,同样不影响标志位。[b]注意:在无符号数除之前,不宜用这两条指令,一般采用XOR清高8位或高16位。[/b]
[b]逻辑运算指令与位移指令[/b]
[b]注意:只能有一个存储器操作数;只有通用寄存器或存储器操作数可作为目的操作数,用于存放结果;操作数的类型必须一致。[/b]
[b]NOT:[/b]取反,不影响标志位。
[b]AND 操作数1 操作数2:[/b]操作结果送错作数1,标志CF(进位)、OF(溢出)清0,PF(奇偶)ZF(0标志) SF(符号)反映运算结果,AF(辅助进位)未定义。自己与自己AND值不变,她主要用于将操作数中与1相与的位保持不变,与0相与清0。(都为1时为1)
[b]OR 操作数1 操作数2:[/b]自己与自己OR值不变,CF(进位)、OF(溢出)清0,PF(奇偶)ZF(0标志)SF(符号)反映运算结果,AF(辅助进位)未定义。她使用于将若干位置1:与1相或为1,保持不变的位与0相或。(都为0时为0)
[b]XOR 操作数1 操作数2:[/b]自己与自己异或结果为0,标志CF(进位)、OF(溢出)清0,PF(奇偶)ZF(0)SF(符号)反映运算结果,AF(辅助进位)未定义。主要用于将若干位取反的操作:与1异或取反,与0异或保持不变。(相同为0,不同为1)
[b]TEST 操作数1 操作数2:[/b]测试指令,和AND相同,但结果不送操作数1,各标志位同AND操作。
[b]位移指令[/b]
[b]SAL/SHL 操作数 1或CL:[/b]算术左移与逻辑左移进行相同的动作,操作数是通用寄存器或者存储器操作数,位移数为1或为CL;最高位移CF(进位),右边用0补位。左移一次相当源操作数乘2。
[b]SAR 操作数 1或CL:[/b]算术右移,位移数为1或为CL;操作数是通用寄存器或者存储器操作数,左符号位保持不变,移出最低位进CF(进位)。相当源操作数除2。
[b]SHR 操作数 1或CL :[/b]逻辑右移,操作数是通用寄存器或者存储器操作数,位移数为1或为CL;左边用0补足,移出的最低位进CF(进位)对于无符号数,右移一位相当于除2。
[b]ROL/ROR 操作数 1或CL: [/b]不带进位左移/右移,操作数是通用寄存器或者存储器操作数,位移数为1或为CL。
[b]RCL/RCR 操作数 1或CL:[/b] 带进位左移/右移,CF(进位)参与循环。操作数是通用寄存器或者存储器操作数,位移数为1或为CL。
[b]转移指令
注意:由于代码段可分为多个段,所以根据转移时是否重置代码段寄存器CS内容,可分为段内转移和段间转移。段内转移仅重置IP的转移,转移后指令仍在同一代码段中。段间转移重置CS,所以转移后继续执行的指令在另一个段中。[/b]
[b]JMP 标号 :[/b]无条件跳转到标号位置执行,段内直接转移指令。地址差用一个字节表示为短转移,用一个字表示为近转移。
[b]JMP 通用寄存器/存储单元:[/b]无条件段间间接转移指令,操作数给定的是目标地址处。
[b]JMP FAR PTR 标号:[/b]无条件段间直接转移指令,她的具体动作是把指令中包含的目标地址的段值和偏移分别置茹CS和IP。
[b]JMP 操作数:[/b]无条件段间间接转移指令,操作数是双字存储单元,给定目标地址,低字节送IP,高字节送CS。
[b]条件转移指令:[/b]所有的条件转移指令都是段内转移。她是由J加上相应的含义字母组合成。有符号数关系G(大于),E(等于),L(小于);无符号数关系A(高于)、E(等于)和B(低于);字母N表示“不”:NB(不小于),NE(不等于)。
[b]循环指令[/b]
[b]LOOP 标号[/b]:她使寄存器CX减1,若结果不等于0则转到标号,否则顺序执行LOOP指令后的指令。最多循环65536次。
[b]LOOPE/LOOPZ 标号:[/b]等于/全零循环指令。CX的值减1,如果结果不等于0,并且ZF(0标志)等于1,则转移到标号。
[b]LOOPNE/LOOPNZ 标号:[/b]不等于/非零循环指令,CX的值减1,如果结果不等于0,并且ZF(0标志)等于0,则跳转到标号。
[b]JCXZ 标号:[/b] 该指令实现当寄存器CX的值等于0转移到标号,否则顺序执行。通常该指令用在循环开始前,以便在循环次数位0时,跳过循环体。
另外如果有整理错误的地方,还请各位前辈指正。谢谢了。