• 【内核学习】之一、汇编语言


    作者:jofranks 原创作品,转载请标明出处!版权所有,侵权必究!

    来源:http://blog.csdn.net/jofranks


    学习内核,学习写操作系统,我们要了解掌握两门语言,分别是汇编语言和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在循环中的左循环移位指令.
    ROR 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为零时转移.
    JECXZE  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[标号]



    本节主要是整理了大部分常用的寄存器和指令,对以后的学习很有帮助,在下一节【内核学习】之汇编语言续 中还会接着来说一下 中断,寻址方式,内存,端口等知识点。

    这里我附送给大家一本汇编指令集,供大家免费下载使用http://download.csdn.net/detail/jofranks/4435548

    过一段时间我还会上传一份更加全面的,请大家稍后!



    2012.2.19

    -------于烟台

  • 相关阅读:
    Java基本类型和引用类型 分类: Java 2015-08-04 14:51 6人阅读 评论(0) 收藏
    串口通信校验方式(even,odd,space,mark) 分类: 开发工具 2015-07-31 16:01 5人阅读 评论(0) 收藏
    学习SerialPort的笔记 分类: 开发工具 2015-07-31 15:51 5人阅读 评论(0) 收藏
    Java操作串口 分类: Java 2015-07-30 23:18 11人阅读 评论(0) 收藏
    JAVA Swt初识 分类: Java 2015-07-30 10:51 22人阅读 评论(0) 收藏
    用Java Swing编写简单的测试小工具界面(源码) 分类: Java 2015-07-30 10:49 23人阅读 评论(0) 收藏
    Java串口助手(程序源码) 分类: Java 2015-07-30 10:13 16人阅读 评论(0) 收藏
    Android使用蓝牙与PC端进行通信 分类: Android 2015-07-30 09:45 15人阅读 评论(0) 收藏
    Android当无线鼠标,通过蓝牙与pc通信,pc端用java写 分类: Android 2015-07-30 09:24 18人阅读 评论(0) 收藏
    Struts2注解
  • 原文地址:https://www.cnblogs.com/java20130723/p/3211434.html
Copyright © 2020-2023  润新知