​​​​


学习内核,学习写操作系统,我们要了解掌握两门语言,分别是汇编语言和C语言,汇编语言是低级语言,由许许多多看不懂的指令组成,而我们的C语言就不一样了,他是介于高级语言与低级语言之间的一种语言,现在在世界语言排行榜上C语言已经跃居世界第一,他的效率是毋庸置疑的。


本人初学乍练,在这里也献丑了,就是把平时学习和积累的东西拿出来和大家分享一下,希望大家多多指正,须向学习,共同进步!



这篇文章是内核学习入门汇编语言,以后还会专门写一些C语言方面的博客跟大家分享交流。




1、寄存器register(有限存贮容量的高速存贮部件)

8086 有14个16位寄存器,我们先来认识一下这14个寄存器:通用寄存器((数据寄存器,由(XH&XL)组成)AX、BX、CX、DX,(指针寄存器和变址寄存器)SP,BP,SI,DI)、 段寄存器(CS代码段,SS堆栈段,DS数据段,ES附加段)、指令指针寄存器(IP)、 标志寄存器(FLAGS)。


通用寄存器:



1、数据寄存器:AX(accumulator)、累加寄存器,常用于运算。





BX(base)、基址寄存器,常用于地址索引。









作为偏移地址与DS配合!









CX(count)、计数寄存器,常用于计数。









loop 和 Cx 合作!









DX(data)、数据寄存器,常用于数据传递。




下面来看一下16位寄存器分为两个8位寄存器:


2、指针寄存器和变址寄存器: SP(Stack Pointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置。

BP(Base Pointer):基址指针寄存器,可用作SS的一个相对基址位置。

SI(Source Index):源变址寄存器,可用来存放相对于DS段之源变址指针。

DI(Destination Index):目的变址寄存器,可用于存放相对于ES段之目的变址指针。

段寄存器:



8086设有4个段寄存器,专门用来保存段地址。在程序要执行的时候,我们需要确定各代码等在内存中的位置,通过这些寄存器来指向这些起始位置。



8086CPU用“基地址(段地址×16)+偏移地址=物理地址”方式给出内存段元的物理地址,我们就可以用分段的方式来管理内存。


1、CS(Code Segment)、代码段寄存器

2、DS(Data Segment)、数据段寄存器


mov ax, 1233H
mov ds, ax
mov bx, [0]

上面的代码意思是我们把12330(1233:0)中的数据送到了bx这个寄存器中。


3、SS(Stack Segemt)、堆栈段寄存器

堆栈这个概念相信学过高级语言(C/C++等)的同学都应该知道,栈是一个后进先出的数据结构,先进来的最后出去,和他对比的是队列,队列是先进先出的数据结构,先进来的最后出去。

在栈中常见的漏洞是溢出错误,这里不是介绍数据结构,大家去参考一下数据结构的教材详细的了解一下。

在这里要说的就是SS:SP,他在任意时刻总是指向栈顶元素。在这里,栈顶的段地址存放在SS中,偏移地址存放在SP中。

说到栈,汇编中涉及到两个指令,分别是push和pop。

入栈:push ax,它分为两步完成:1、SP = SP - 2, SS:SP指向当前栈顶最前面的单元。






2、将ax中的内容送入SS:SP指向的内存单元处,SS:SP此时指向新栈顶。






出栈: pop ax, 它也是分两步来完成:1、将SS:SP指向的内存单元处的数据送入ax中。







2、SP = SP+2, SS:SP指向当前栈顶下面的单元,以当前栈顶下面的单元作为新的栈顶.








这里需要注意的是:pop出栈后,栈内的数据还是存在的,并没有删除掉.


4、ES(Extra Segment)、附加段寄存器


指令指针寄存器IP:



需要知道的是,IP是指令地址的段内地址偏移量,即偏移地址,有时候也叫他是有效地址。


我们拿CS:IP来说一下:



 CS:IP是指向内存单元。即:段地址:偏移地址,我们算出内存中的物理地址。





如果我们要修改CS:IP的值,我们不能像修改AX一样用:mov ax,100(mov指令下面会介绍)。我们必须用jmp指令来修改。




先来看看同时修改CS:IP: jmp 段地址:偏移地址



如:jmp 23E4:3 执行后CS = 23E4H , IP = 0003H CPU 会从 23E43H处读取数据。




现在我们就想修改IP的值: 我们可以用:jmp 某一合法寄存器



如:jmp ax 执行前是:ax = 1000H, cs = 2000H , IP = 3000H



执行后是:ax = 1000H, CS = 2000H, IP = 1000H



我们可以这么理解 jmp 某一合法寄存器: mov IP, ax


标志寄存器FR:


来看一下标志寄存器的结构图:







2、汇编指令集合(这里部分常用的指令会讲解,主要是查询使用)

(1)、数据传送指令


通用数据传送指令





mov     传送字或数据(这个指令比较常用,大家需掌握)

格式: MOV OPRD1,OPRD2

功能: 本指令将一个源操作数送到目的操作数中,即OPRD1<--OPRD2.


mov ax, [2]



我们可以这样描述: (ax) = ((ds)*16+2)    表示将ds:0处的数据送入al中!(应为内存单元是一个字节8位,ax是一个16位的,同位的进行存储)



push   入栈指令

pop   出栈指令

格式:push ax    pop ax

功能:实现压入操作的指令是push指令,弹出操作的指令是pop指令

push和pop的操作过程在上文有图示,大家可以参阅。


xchg  交换字或字节(至少有一个操作数为寄存器,段寄存器不可作为操作数)

格式:  XCHG OPRD1, OPRD2      目的操作数,源操作数

功能:将两个操作数相互交换位置,该指令把源操作数OPRD2与目的操作数OPRD1交换


xlat   字节查表转换

格式:XLAT TABLE      table为一待查表格的手地址

功能:把待查表格的一个字节内容送到AL累加器中



目的地址传送指令





lea  装入有效地址                                      lea dx,string ; 把偏移地址存到dx中

功能:将源操作数给出的有效地址送到指定的寄存器中


LEA BX,DATA1



上面指令的功能是将变量DATA1的地址送至BX,而不是将变量DATA1的值送BX,它等价于:



mov bx,offset data





lds  传送目标指针,吧指针内容装入ds                    lds  si,string  ; 把段地址:偏移地址存到 ds:si

功能:从存储器中取出32位地址的指令


LDS DI,[BX]



上面的指令的功能是把BX所指的32位地址指针的段地址送入DS,偏移地址送入DI



les  传送目标指针,把指针内容装入ES                   les di,sring   ;  把段地址:偏移地址存到es:di

功能:从存储器取出32位地址的指令


LES DI,[BX]



上面的指令的功能是把BX所指的32位地址指针的段地址送入ES,偏移地址送入DI




标志传送指令




lahf  标志寄存器传送,把标志装入AH

功能:取FLAG标志寄存器低8位至AH寄存器。他不影响FLAG的原来内容,AH只是复制了原FLAG的低8位内容。


sahf 标志寄存器传送,把AH内容装入标志寄存器

功能:将AH存至FLAG低8位。   用AH的内容改写FLAG标志寄存器中的SF,ZF,AF,PF,CF标志,从而改变原来的标志位。


pushf  标志入栈

功能:可以把标志寄存器的内容保存到堆栈中去

popf  标志出栈

功能:与pushf相反,在子程序调用和终端服务程序中,往往用pushf指令保护FLAG的内容,用popf指令将保护的FLAG内容恢复。

pushd  32位标志入栈

popd   32位标志出栈



(2)、逻辑运算指令


AND  逻辑与运算指令

功能:对两个操作时实现按位逻辑与运算,结果送到目的操作数中。

指令影响标志位PF、SF、ZF,使CF=0、OF=0.


AND AL,0FH            ;(AL)<--(AL) AND 0FH 
AND AX,BX ;(AX)<--(AX) AND (BX)
AND DX,BUFFER[SI+BX] 
AND BETA[BX],00FFH


注意:两个数与运算,有一个数为假则值为假。



OR  逻辑或指令

功能:按位或运算。

注意:两个数或运算,有一个数为真则结果为真。


XOR   逻辑异或运算指令

功能:实现两个操作数按位异或运算。结果送到目的操作数中

相异为真,相同为假。


NOT  逻辑非运算指令

功能:完成对操作数按位求饭运算。结果返回原操作数。


TEST    测试指令

功能:其中寄存器的含义和AND指令相同。也是对两个操作数进行按位与运算。唯一不同的是不讲与的结果送到目的操作数。即本指令对两个操作数的内同均不进行修改,仅在逻辑与操作后对标志位重新置位。


SHL   逻辑左移指令

功能:对给定的目的操作数左移COUNT次,每次移位时最高位移入标志位CF中,最低位补0.


SHL AL,1 
SHL CX,1 ;都是左移1位
SHL ALFA[DI] 或者:
MOV CL,3
SHL DX,CL
SHL ALFA[DI],CL ;都是左移3位




SHR   逻辑右移指令

功能能:同SHL想法。   它每次移位时,最高位补0,最低位移至标志位CF中。

影响标志位:OF, PF, SF, ZF CF.


SAL  算术左移指令

功能:与SHL功能相同,因为逻辑左移指令与算术左移指令所要完成的操作是一样的。


SAR  算术右移指令。

功能:本指令通常用于对带符号数减半的运算中,因为在每次右移时保持最高位不变,最低位右移到CF中。


ROL   循环移位指令

功能:循环移位指令时指操作数首位相连的移位操作,按进位标志CF是否参加循环移位,又可分为不带CF的循环移位和带CF的循环移位两类,每一类都进行左移或右移,循环移位的次数由count操作数给出。

例:将AL中的组合的两个BCD分解为两个未组合的BCD数,存于BH及BL寄存器中           程序为:


MOV AH,AL  ;保存AL内容至AH中 
MOVCL,4 ;循环次数4送CL
SHR AL,CL ;将AL右移4次,高4位移至低4位
MOV BH,AL ;高位BCD送BH中
AND AH,0FH ;得到低位BCD数
MOV BL,AH ;低位BCD数送BL中

注意: 以上程序中的指令SHR AL,CL如改为SAR AL,CL,虽然最高4位可移入低4位 ,但最高位不为0,故应加入一条指令AND AL,0FH.否则,若最高位不为0时,将得到错误结果.



ROR 循环移位指令

RCL  循环移位指令

RCR 循环移位指令

这些指令只影响标志CF,OF.  由移入CF的内容决定,OF取决于移位一次后符号位是否改变,如改变则OF=1


ROL OPRD1,COUNT ;不含进位标志位CF在循环中的左循环移位指令.
RCL OPRD1,COUNT ;带进位的左循环移位指令.
RCR OPRD1,COUNT ;带进位的右循环移位指令.






(3)、算术运算指令

.组合的十进制数和未组合的十进制数:在计算中,十进制数可用四位二进制数编码,称为BCD码.当一个节(8位)中存放一位BCD码,且放在字节的低4位, 高4位称为未组合的BCD码.显然,一个字节中也可以存放两位BCD码,称一个字节中的两位BCD数为组合的BCD数.


ADD    加法指令

功能:两数相加

加法指令运算的结果对CF、SF、OF、PF、ZF、AF都会有影响.


ADC  带进位加法指令

格式:ADC OPRD1,OPRD2

功能:OPRD1<--OPRD1 + OPRD2 + CF

OPRD1为任一通用寄存器或存储器操作数,可以是任意一个通用寄存器

   OPRD2为立即数,也可以是任意一个通用寄存器操作数.立即数只能用于源操作数


ADC AL,CL          ; (AL)<--(AL)+(CL)+CF 
ADC AX,SI ; (AX)<--(SI)+CF
ADC DX,MEMA ;(DX)<--(DX)+[(DS)*16+MEMA]+CF
ADC CL,15 ; (CL)<--(CL)+15+CF
ADC WORD PTR[BX][SI],25


INC  

加1指令


功能:相当于C中的++操作符

这条指令执行结果影响AF、OF、PF、SF、ZF标志位,但不影响CF标志位.


INC SI                    ;(SI)<--(SI)+1


SUB

减法指令


功能:两个操作数的相减,即从前一个寄存器中减去后一个寄存器,结果放在前一个寄存器中,指令的类型及对标志位的影响与ADD指令相同,注意立即数不能用于目的操作数,两个存储器操作数之间不能直接相减,操作数可为8位或16位的无符号数或带符号数。


SBB  带借位减法指令

功能:是进行两个操作数的相减再减去CF进位标志位。即AX<--AX - BX - CF,其结果放在AX中,指令的类型及对标志位的影响与ADD指令相同,注意立即数不能用于目的操作数,两个寄存器操作数之间不能直接相减,操作数可为8位或16位的无符号数或带符号数。


DEC  减一指令

功能:相当于C中的--操作符。

这条指令执行结果影响AF、OF、PF、SF、ZF标志位,但不影响CF标志位.


NEG   取补指令

格式:NEG OPRD

功能:对操作数OPRD进行取补操作,然后将结果送回OPRD,取补操作也叫做求补操作,就是求一个数的相反数的补。


(AL)=44H,取补后,(AL)=0BCH(-44H).

本指令影响标志位CF、OF、SF、PF、ZF及AF. 



CMP   比较指令

功能:对两个数进行比较,该指令不改变寄存器的值,只是用于改变标志位。

以CMP DX,CX为例,对标志位的影响如下:
          (1) (DX)=(CX)时,则ZF=1;

(2) 两相无符号数比较:
              若(DX)>=(CX)时,则CF=0,即无借位.
              若(DX)<(CX)时,则CF=1.

  (3) 两个带符号数比较
              对带符号数判断大小可通过溢出标志OF及符号标志SF共同判断.
              当 OF=0,即无溢出时,若SF=0,则(DX)>(CX)
                                 若SF=1,则(DX)<(CX)
              当 OF=1,即有溢出时,若SF=1,则(DX)>(CX) 
                                 若SF=0,则(DX)<(CX)


MUL  无符号数乘法指令

功能:乘法操作

 本指令影响标志位CF及OF.

操作过程:字节相乘:(AX)<--(AL)*OPRD,当结果的高位字节(AH)不等于0时,则  CF=1、OF=1.

字相乘:(DX)(AX)<--(AX)*OPRD,当(DX)不等0时,则CF=1、OF=1


IMUL   带符号数乘法指令

功能:完成两个带符号数的相乘


DIV   无符号数除法指令

功能:实现两个无符号二进制数除法运算


DIV BETA [BX] 
DIV CX;商在AX中,余数在DX中
DIV BL;商在AL中,作数在AH中




IDIV   带符号数除法制定

功能:是想两个带符号数的二进制除法运算


CBW  字节扩展指令

功能:将字节扩展为字,即把AL寄存器的符号位扩展到AH中

两个字节相除时,先使用本指令形成一个双字节长的被除数。


MOV AL,25 
CBW
IDIV BYTE PTR DATA1


CWD  

字扩展指令


功能:将字扩展为双字长,即把AX寄存器的符号位扩展到DX中。

两个字或字节相除时,先用本指令形成一个双字长的被除数。

例:在B1、B2、B3字节类型变量中,分别存有8位带符号数a、b、c,实现(a*b+c)/a运算。


MOV AL,B1 ;   a-->(AL) 
IMUL B2 ; 实现a*b-->(AX)
MOV CX,AX ; (AX)-->(CX)
MOV AL,B3 ; c-->(AL)
CBW ; 扩展符号位至AH中
ADD AX,CX ; (AX)+(CX)-->(AX),完成a*b+c
IDIV B1 ; 完成(a*b+c)/a,商-->(AL),余数-->(AH)





AAA  未组合十进制加法调整指令

功能:对两个组合的十进制数相加运算(存于AL中)的结果进行调整,产生一个未组合的十进制数放在AN中。

调整操作:  若(AL) and 0FH>9 或 AF=1,则调整如下:
          (AL)<--(AL)+6,(AH)<--(AH)+1,AF=1,CF<--AF,(AL)<--(AL) and 0FH


DAA  组合的十进制加法调整指令

功能:对AL中的两个组合进制数相加的结果进行调整,调整结果仍放在AL中,进位标志放在CF中

调整操作:若(AL) and 0FH>9 或 AF=1,则(AL)<--(AL)+6,AF<--1,对低四位的调整.

若(AL) and 0F0H>90H 或 CF=1,则(AL)<--(AL)+60H,CF<--1.

列:

(AL)=18H,(BL)=06H
ADD AL,BL ; (AL)<--(AL)+(BL)
; (AL)=1EH
DAA ; (AL)=24H,AF=1

注意:  本指令影响标志位AF,CF,SF,ZF



DAS      组合十进制减法调整指令

功能:对两个组合十进制数相减后存于AL中的结果进行调整,调整后产生一个组合的十进制数且仍存于AL中。

调整操作:若(AL) and 0FH > 9 或 AF=1,则(AL)<--(AL)-6,AF=1
       若(AL) and 0F0H > 90H 或 CF=1,则(AL)<--(AL)-60,CF=1


AAS    未组合十进制减法调整指令

功能:对两个未组合十进制数相减后存于AL中的结果进行调整,调整后产生一个未组合的十进制数,且仍存于AL中。

注意:本指令影响标志位CF,AF

调整操作:  若(AL) and 0FH > 9 或 AF=1
           则(AL)<--(AL)-6,(AH)<--(AH)-1,CF<--AF,(AL)<--(AL) and 0FH,否则 (AL)<--(AL) and 0FH



AAM   未组合十进制数乘法调整指令

功能:对来年改革未组合的十进制数相乘后存于ax中的结果进行调整,产生一个未组合的十进制数存于AL中。

       乘积: (AH)<--(AL)/10 
                (AL)<--(AL)MOD10 

注意:本指令应跟在MUL指令后使用。乘积的两位十进制结果,高位放在AH中,地位放在AL中。

           本指令影响标志为:PF,SF,ZF



AAD    未组合十进制数除法调整指令

功能:在除法指令前对AX中的两个未组合十进制数进行调整,以便能用DIV指令实现两个未组合的十进制数的除法运算,其结果为未组合的十进制数,商(在AL中)和余数(在AH中)。

     AAM与AAD不同是,AAD指令在执行除法DIV之前使用的,以便得到二进制结果存于AL中。

调整操作: (AL)<--(AH)*10+(AL),(AH)<--0  

注意:ADD指令执行后,AL中的内容已成为二进制数。

             本指令影响标志为PF,SF,ZF


(4)、控制转移指令


无条件转移指令 (长转移)





JMP 无条件转移指令

功能:jmp指令将无条件地控制程序转移到目的地址去执行,当目的地址仍在同一个代码段内,成为段内转移。当目标地址不在同一个代码段内,称为段间转移,这两种情况都将产生不同的指令代码。以便能正确地生成目的地址。在段内转移时指令只要能提供目的地址的段内便宜量即够了。而在段间转移时,指令能提供目的地址的段地址及段内便宜地址值。

段内直接转移指令: JMP NEAR 标号 
              即: JMP NEAR  标号;  (IP)<--disp16+(IP) 
                  JMP SHORT 标号;  (IP)<--disp8+(IP) 

段内间接转移指令: JMP OPRD 
              例如: JMP BP               ; 转向(SS):(BP) 
                    JMP JNEAR[BX]        ; 转向(CS):(BX)+JNEAR 
                    JMP WORD PTR[BX][DI] ; 转向(CS):(BX)+(DI) 

段间直接转移指令: JMP FAR 标号 

 段间间接转移指令:JMP OPRD


CALL 过程调用

功能:过程调用指令

 过程调用可分为段内调用和段间调用两种.寻址方式也可以分为直接寻址和间接 寻址两种.

段内直接调用: CALL NEAR类型的过程名

段内间接调用: CALL OPRD 

段间直接调用: CALL FAR 类型的过程名 

段间间接调用: CALL DWOPRD


RET/RETF过程返回.

功能:当调用的过程结束后实现从过程返回到原调用程序的下一条指令,本指令不影响标志位。





条件转移指令 (短转移,-128到+127的距离内)





JA/JNBE不小于或不等于时转移.

功能:为高于/不低于等于的转移指令

该指令用于无符号数进行条件转移

 例如两个符号数a,b比较时,a>b(即CF=0,ZF=0)时转移.因为单一标志位CF=0,只 表示a>=b.


JAE/JNB大于或等于转移.

功能:为高于等于/不低于的转移指令

该指令用于无符号数进行条件转移


JB/JNAE小于转移.

功能:低于/不高于等于时转移

该指令用于无符号数的条件转移


JBE/JNA 小于或等于转移.

功能:低于等于/不高于时转移

该指令用于无符号数的条件转移


JG/JNLE大于转移.

功能:大于/不小于等于时转移

用于带符号数的条件转移指令

JGE/JNL大于或等于转移.

功能:大于等于/不小于时转移

用于带符号数的条件转移指令


JL/JNGE小于转移.

功能:小于/不大于等于时转移

用于带符号数的条件转移指令



JLE/JNG

小于或等于转移.


功能:小于等于/不大于时转移

用于带符号数的条件转移指令


JE/JZ 等于转移.

功能:ZF=1转至标号处执行

根据标志位ZF来进行转移,他们是一条指令的两种助记符表示方法。


JNE/JNZ不等于时转移.

功能:ZF=0转至表好处执行。


JC有进位时转移.

功能:CF=1转至标号处执行


JNC无进位时转移.

功能:CF=0转至标号处执行


JNO不溢出时转移.

功能:OF=0转至标号处执行


JNP/JPO奇偶性为奇数时转移.

功能:PF=0转至标号处执行


JNS符号位为 "0" 时转移.

功能:SF=0转至标号处执行


JO溢出转移.

功能:OF=1转至标号处执行


JP/JPE 奇偶性为偶数时转移.

功能:OF=1转至标号处执行


JS符号位为 "1" 时转移.

功能:SF=1转至标号处执行






循环控制指令(短转移)





LOOP   CX不为零时循环.

功能: (CX)<--(CX)-1,(CX)<>0,则转移至标号处循环执行, 直至(CX)=0,继续执行后继指令.

它属于段内SHORT短类型转移,目的地址必须距本指令在-128到+127个字节的范围内. 


LOOPE/LOOPZ   CX不为零且标志Z=1时循环.

功能: (CX)<--(CX)-1,(CX)<>0 且ZF=1时,转至标号处循环

它属于段内SHORT短类型转移,目的地址必须距本指令在-128到+127个字节的范围内. 


LOOPNE/LOOPNZ   CX不为零且标志Z=0时循环.

功能: (CX)<--(CX)-1,(CX)<>0 且ZF=0时,转至标号处循环


它属于段内SHORT短类型转移,目的地址必须距本指令在-128到+127个字节的范围内. 



JCXZ  

CX为零时转移.



JECXZ

E  CX为零时转移.







中断指令





INT中断指令

功能:本指令将产生一个软中断,把控制转向一个类型号为r的软中断,该中断处理程序入口地址在中断向量表的n*4地址处的两个存储器字(4个单元)中。

他的操作过程与INTO指令雷同,只需要将10H改为n*4即可,           ,本指令也将影响标志位IF及TF.


INTO溢出中断

功能:本指令检测OF标志位,当OF=1时,说明已发生溢出,立即产生一个中断类型4的中断,当OF=0时,本指令不起作用。

 操作过程: 如果OF=1,则(SP)<--(SP)-2, 标志寄存器入栈,IF、TF清0, (SP)<--(SP)-2,将当前CS入栈,00010H地址的第二个字的内容送入CS,即 00013H及00012H单元内容送CS,(SP)<--(SP)-2,IP内容入栈,将00010H的第一个字的内容送IP, 从而实现向中断类型4中断处理程序的转移.如果CF=0,则立即执行一条指令. 

这条指令影响标志位IF,TF

当用于溢出处理,当OF=1时,产生一个类型4的软中断,在中断处理程序中完成溢出的处理操作。



IRET

中断返回


功能:用于中断处理程序中,从中断程序的断点处返回,继续执行原程序。

 操作过程: 将当前堆栈弹出一个字送IP,(SP)<--(SP)+2,再弹出一个字送CS,(SP)<--(SP)+2,最后从堆栈弹出一个字送FLAG寄存器,(SP)<--(SP) +2.

它影响所有的标志位。

无论是软中断,还是硬中断,本指令均可使其返回到中断程序的断点处继续执行 原程序.





(5)、串操作指令


MOVS串传送.

将存储器中变量A开始的200个数据串传送至B开始的存储区,可用以下程序段实现:


MOV SI,OFFSET A  ; SI指向源串首址 
MOV DI,OFFSET B ; DI指向目的串首址
MOV CX,200 ; 字节串或字串长度200送CX
CLD;0-->DF
ATOB:MOVS B,A ; 对字节串传送可用MOVSB
DEC CX ; (CX)<--(CX)-1
JNZ ATOB ; (CX)<>0,转至ATOB



用指令MOVS B,A究竟是字节传送,还是字传送,取决于A,B的类型定义.若DF=0,则在字传送时,(SI)<--(SI)+2,(DI)<--(DI)+2.


CMPS串比较.

 功能: 由SI寻址的源串中数据与由DI寻址的目的串中数据进行比较,比较结果送标志位,而不改变操作数本身.同时SI,DI将自动调整.

例如: 对两个字节串进行比较,若一致,则AL内容置为0;若不一致,则AL内容置为0FFH.程序段如下:


MOV SI,OFFSET ST1 
MOV DI,OFFSET ST2
MOV CX,N
CLD
NEXT:CMPSB
JNZ FIN
DEC CX
JNZ NEXT
MOV AL,0
JMP OVR FIN:MOV AL,0FFH
OVR:MOV RSLT,AL


与MOVS相似,CMPS指令也可以不使用操作数,此时可用指令CMPSB或CMPSW分别表示字节串比较或字串比较.


SCAS串扫描

功能: 把AL(字节串)或AX(字串)的内容与由DI寄存器寻址的目的串中的数据相减,结果置标志位,但不改变任一操作数本身.地址指针DI自动调整.

 指令中不使用操作数时,可用指令格式SCASB,SCASW,分别表示字节串或字串搜索指令.

LODS装入串.

 功能: 把SI寻址的源串的数据字节送AL或数据字送AX中去, 并根据DF的值修改地址指针SI进行自动调整.


STOS保存串.

 功能: 把AL(字节)或AX(字)中的数据存储到DI为目的串地址指针所寻址的存储器单元中去,指针DI将根据DF的值进行自动调整.


(6)、伪指令


DB定义字节(1字节)

DW定义字(2字节).

DD定义双字(4字节)




DB: 定义字节变量
DW: 定义字变量

DD: 定义双字变量

DF: 定义6字节变量
DQ: 定义四字变量
DT: 定义10字节变量


格式: [<变量名>]{DB|DW|DD|DF|DQ|DT}<表达式>,<表达式>







PROC定义过程.

ENDP 过程结束.

 格式: <过程名>PROC[NEAR或FAR] 
       RET 
       <过程名>ENDP
 

ASSUME建立段寄存器寻址.

 格式: ASSUME<段寄存器>:<段名>[,<段寄存器>:<段名>]
  例如: ASSUME CS:CSEGH,DS:DSEG,SS:SSEG,ES:ESEG 


SEGMENT定义段.

 功能: SEGMENT和ENDS伪操作命令可用来把程序分成若干逻辑段,这些逻辑段按用途不同,通常包括代码段、数据段、堆栈和附加段,它分别装入由CS、DS、SS和ES寄存器所指定的物理段中。

ENDS段结束.

格式:<段名>SEGMENT[<定位类型>],[<组合类型>],[<'类别名'>] 
 ----   …:段体 
     <段名>ENDS 

功能:SEGMENT和ENDS伪操作命令可用来把程序费城若干逻辑段,这些逻辑段按用途不同,通常包括代码段,数据段,堆栈段,附加段。它分别装入由CS,DX,SS

,ES寄存器所指定的物理段中。

END程序结束.

 格式: [NAME<模块名>]
 ----     ...
       END[标号]