【原创】uC/OS 中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理

1     LES    BX, DWORD PTR DS:_OSTCBCur     ;OSTCBCur->OSTCBStkPtr = SS:SP!!!
2     MOV    ES:[BX+2], SS                  ;将当前SS(栈的基地址)寄存器值存放至当前任务控制块的2,3内存单元
3     MOV    ES:[BX+0], SP                  ;将当前SP(栈顶的偏移量)存放至当前任务控制块的0,1内存单元
    首先讲讲LES指针的功能:LES的功能有点像C语言的*。
    LES REG,MEM
    
    参与操作的寄存器不仅有REG,还有ES寄存器。在16位系统中,寄存器为16位,很显然,MEM所指向的内存大小应是4字节。运行这个命令,将MEM地址所指向的内存单元的低16位存放于REG寄存器,将MEM地址所指向的内存单元的高16位存放于ES寄存器。
    注意:REG和ES寄存器存放的值不是MEM这个地址值,而是这个地址所指向的内存单元的值,类似C语言的指针的*操作。
    
    明白了LES指针的功能,接下来我们探讨一下uC/OS任务切换中LES BX,DWORD PTR DS:_OSTCBCur的作用及原理。
    
    首先先要说明的是uC/OS编译的时候,使用的是Large模式,每个段大小可达1MB,Large模式下,FAR 指针的长度为32位,然而在FAR指针中存放的不是变量的绝对地址,仍是段地址+偏移量。FAR指针的高16位为变量的段地址,低16位存放变量的段内偏移。
   
     _OSTCBCur为一个指向当前任务的任务控制块的指针变量,存放的是任务控制块结构体的地址,等于结构体第1个成员变量的地址。同时由于任务控制块的第1个成员变量是OS_STK        *OSTCBStkPtr,所以任务堆栈指针变量的地址值和任务控制块的地址值相同。
    
    因此通过LES BX,DWORD PTR DS:_OSTCBCur指令,得到了任务控制块的段地址和段内偏移,得到了任务堆栈指针变量的段地址和段内偏移。
 
    MOV    ES:[BX+2], SS中的ES:[BX+2],是任务堆栈指针变量的第3字节内存单元的地址,所以该指令的作用是,将SS寄存器的16位值的低8位存放至任务堆栈指针变量的第3字节内存单元,高8位存放至任务堆栈指针变量的第4自己内存单元。第二条MOV指令作用也是一样。
 
    这样便实现了将CPU的堆栈指针保存进任务控制块的第1个成员任务堆栈指针变量中。
 
参考链接:

本文链接:http://www.cnblogs.com/cposture/p/4291885.html

原文地址:https://www.cnblogs.com/cposture/p/4291885.html