WEB开发网      婵犵數濮烽弫鍛婄箾閳ь剚绻涙担鍐叉搐绾剧懓鈹戦悩瀹犲闁汇倗鍋撻妵鍕箛閸洘顎嶉梺绋款儑閸犳劙濡甸崟顖氬唨闁靛ě浣插亾閹烘鈷掗柛鏇ㄥ亜椤忣參鏌″畝瀣暠閾伙絽銆掑鐓庣仭缁楁垿姊绘担绛嬪殭婵﹫绠撻、姘愁樄婵犫偓娴g硶鏀介柣妯款嚋瀹搞儱螖閻樺弶鍟炵紒鍌氱Ч瀹曟粏顦寸痪鎯с偢瀵爼宕煎☉妯侯瀳缂備焦顨嗗畝鎼佸蓟閻旈鏆嬮柣妤€鐗嗗▓妤呮⒑鐠団€虫灀闁哄懐濮撮悾鐤亹閹烘繃鏅濋梺闈涚墕濡瑩顢欒箛鏃傜瘈闁汇垽娼ф禒锕傛煕閵娿儳鍩f鐐村姍楠炴﹢顢欓懖鈺嬬幢闂備浇顫夊畷妯肩矓椤旇¥浜归柟鐑樻尭娴滃綊姊虹紒妯虹仸闁挎洍鏅涜灋闁告洦鍨遍埛鎴︽煙閼测晛浠滃┑鈥炽偢閹鈽夐幒鎾寸彇缂備緡鍠栭鍛搭敇閸忕厧绶炴俊顖滅帛濞呭洭姊绘担鐟邦嚋缂佽鍊垮缁樼節閸ャ劍娅囬梺绋挎湰缁嬫捇宕㈤悽鍛婄厽閹兼番鍨婚埊鏇㈡煥濮樿埖鐓熼煫鍥ュ劤缁嬭崵绱掔紒妯肩畺缂佺粯绻堝畷姗€濡歌缁辨繈姊绘担绛嬪殐闁搞劋鍗冲畷顖炲级閹寸姵娈鹃梺缁樻⒒閳峰牓寮崒鐐寸厱闁抽敮鍋撻柡鍛懅濡叉劕螣鐞涒剝鏂€闂佺粯鍔曞Ο濠囧吹閻斿皝鏀芥い鏃囨閸斻倝鎽堕悙鐑樼厱闁哄洢鍔屾晶顖炴煕濞嗗繒绠婚柡灞界Ч瀹曨偊宕熼鈧▍锝囩磽娴f彃浜炬繝銏f硾椤戝洨绮绘ィ鍐╃厵閻庢稒岣跨粻姗€鏌ㄥ☉妯夹fい銊e劦閹瑩顢旈崟顓濈礄闂備浇顕栭崰鏍礊婵犲倻鏆﹂柟顖炲亰濡茶鈹戦埄鍐ㄧ祷妞ゎ厾鍏樺璇测槈閵忕姈鈺呮煏婢跺牆鍔撮柛鏂款槺缁辨挻鎷呯粙搴撳亾閸濄儳鐭撶憸鐗堝笒閺嬩線鏌熼崜褏甯涢柡鍛倐閺屻劑鎮ら崒娑橆伓 ---闂傚倸鍊搁崐鐑芥倿閿旈敮鍋撶粭娑樺幘濞差亜鐓涢柛娑卞幘椤斿棝姊虹捄銊ユ珢闁瑰嚖鎷�
开发学院软件开发汇编语言 汇编教程:控制转移(3) 阅读

汇编教程:控制转移(3)

 2009-10-12 09:36:41 来源:WEB开发网 闂傚倸鍊搁崐椋庢濮橆兗缂氱憸宥堢亱闂佸湱铏庨崰鏍不椤栫偞鐓ラ柣鏇炲€圭€氾拷闂傚倸鍊搁崐椋庣矆娓氣偓楠炲鏁撻悩鎻掔€梺姹囧灩閻忔艾鐣烽弻銉︾厵闁规鍠栭。濂告煕鎼达紕校闁靛洤瀚伴獮鎺楀箣濠靛啫浜鹃柣銏⑶圭壕濠氭煙閻愵剚鐏辨俊鎻掔墛缁绘盯宕卞Δ鍐冣剝绻涘畝濠佺敖缂佽鲸鎹囧畷鎺戭潩閹典焦鐎搁梻浣烘嚀閸ゆ牠骞忛敓锟�婵犵數濮烽弫鍛婃叏椤撱垹绠柛鎰靛枛瀹告繃銇勯幘瀵哥畼闁硅娲熷缁樼瑹閳ь剙岣胯鐓ら柕鍫濇偪濞差亜惟闁宠桨鑳堕崝锕€顪冮妶鍡楃瑐闁煎啿鐖奸崺濠囧即閵忥紕鍘梺鎼炲劗閺呮稒绂掕缁辨帗娼忛埡浣锋闂佽桨鐒﹂幑鍥极閹剧粯鏅搁柨鐕傛嫹闂傚倸鍊搁崐椋庢濮橆兗缂氱憸宥堢亱闂佸湱铏庨崰鏍不椤栫偞鐓ラ柣鏇炲€圭€氾拷  闂傚倸鍊搁崐鐑芥嚄閼哥數浠氱紓鍌欒兌缁垶銆冮崨鏉戠厺鐎广儱顦崡鎶芥煏韫囨洖校闁诲寒鍓熷铏圭磼濡搫顫嶅銈嗗姉閸樠囧煡婢跺á鐔兼煥鐎n兘鍋撴繝姘拺鐟滅増甯掓禍浼存煕閹惧鈽夐柍缁樻煥椤繈鎳滅喊妯诲闂備礁鎲$粙鎴︺偑閺夋垟鏋旈柡鍐e亾缂佺粯绋撴禒锕傚磼濮橆剦鐎抽梻浣哥-缁垶骞戦崶顒傚祦閻庯綆浜栭弨浠嬫煙闁箑澧い鏂垮€规穱濠囨倷椤忓嫧鍋撻弽褜娼栧┑鐘宠壘閸屻劎鎲歌箛娑樼疅闁圭虎鍠楅弲鎼佹煥閻曞倹瀚�
核心提示:<五>任务切换利用段间转移指令JMP或者段间调用指令CALL,通过任务门或直接通过任务状态段,汇编教程:控制转移(3)(2),可以切换到别的任务,此外,在切换过程中把原任务置为“可用”,目标任务仍保持“忙”,在中断/异常或者执行IRET指令时也可能发生任务切换

<五>任务切换

利用段间转移指令JMP或者段间调用指令CALL,通过任务门或直接通过任务状态段,可以切换到别的任务。此外,在中断/异常或者执行IRET指令时也可能发生任务切换。需要注意的是,因为RET指令的目标地址只能使用代码段描述符,所以,不能通过RET指令实现任务切换。

1.直接通过TSS进行任务切换

段间转移指令JMP或段间调用指令CALL所含指针的选择子指示一个可用任务状态段TSS描述符时,正常情况下就发生从当前任务到由该可用TSS对应任务(目标任务)的切换。目标任务的入口点由目标任务TSS内的CS和EIP字段所规定的指针确定。这样的JMP或CALL指令内的偏移被丢弃。另外,对于段间调用指令CALL,若目标选择子指示一TSS段描述符或任务门时,则返回地址和外层栈指针并不压入堆栈。

处理器采用与访问数据段相同的特权级规则控制对TSS段描述符的访问。TSS段描述符的DPL规定了访问该描述符的最外层特权级,只有在相同级别或更内层级别的程序才可以访问它。同时,还要求指示它的选择子的RPL必须满足RPL<=TSS的DPL的条件。当这些条件满足时,就开始任务切换。

2.通过任务门进行任务切换

任务门内的选择子指示某个任务的TSS描述符。当段间转移指令JMP或段间调用指令CALL所含指针的选择子指示一个任务门时,正常情况下就发生任务切换,即从当前任务切换到由任务门内的选择子所指示的TSS描述符对应的任务(目标任务)。这样的JMP或CALL指令内的偏移被丢弃;任务门内的偏移也无意义。

处理器采用与访问数据段相同的特权级规则控制对任务门的访问。任务门的DPL规定了访问该任务门的最外层特权级,只有在同级或更内层级别的程序才可以访问它。同时,还要求指示任务门的选择子RPL必须满足RPL<=任务门的DPL的条件。在这些条件满足时,再检查任务门内的选择子,要求该选择子指示GDT中的可用的TSS描述符。对于任务门所指向的TSS描述符的DPL不进行特权级检查。检查通过以后,就开始任务切换。

3.任务切换过程

根据指示目标任务TSS描述符的选择子进行任务切换的一般过程如下:

第一,测试目标任务状态段的界限。TSS用于保存任务的各种状态信息,不同的任务,TSS中可以有数量不等的其他信息,根据任务状态段的基本格式,TSS的界限应大于或等于103(104-1)。

第二,把寄存器现场保存到当前任务的TSS。把通用寄存器、段寄存器、EIP及EFLAGS的当前值保存到当前TSS中。保存的EIP值是返回地址,指向引起任务切换指令的下一条指令。但不把LDTR和CR3的内容保存到TSS中。

第三,把指示目标任务TSS的选择子装入TR寄存器中。同时把对应TSS的描述符装入TR的高速缓冲寄存器中。此后,当前任务改称为原任务,目标任务改称为当前任务。

第四,基本恢复当前任务(目标任务)的寄存器现场。根据保存在TSS中的内容,恢复各通用寄存器、段寄存器、EFLAGS及EIP。在装入寄存器的过程中,为了能正确地处理可能发生的异常,只把对应选择子装入各段寄存器。此时选择子的P位为0。还装载CR3寄存器。

第五,进行链接处理。如果需要链接,那么将指向原任务TSS的选择子写入当前任务TSS的链接字段,把当前任务TSS描述符类型改为“忙”(并不修改原任务状态段描述符的“忙”位),并将标志寄存器EFLAGS中的NT位置1,表示是嵌套任务。如果需要解链,那么把原任务TSS描述符类型改为“可用”。如果无解链处理,那么将原任务TSS描述符类型置为“可用”,当前任务TSS描述符类型置为“忙”。由于JMP指令引起的任务切换不实施链接/解链处理;由CALL指令、中断、IRET指令引起的任务切换要实施链接/解链处理。

第六,把CR0中的TS标志置为1,这表示已发生过任务切换,在当前任务使用协处理器指令时,产生自陷。由自陷处理程序完成有关协处理器现场的保存和恢复。这有利于快速地进行任务切换。

第七,把TSS中的CS选择子的RPL作为当前任务特权级设置为CPL。又因为装入CS高速缓冲寄存器时要检测CPL=代码段描述符的DPL,所以TSS中的选择子所指示的代码段描述符的DPL必须等于该选择子的RPL。任务切换可以在一个任务的任何特权级发生,并且可以切换到另一任务的任何特权级。

第八,装载LDTR寄存器。一个任务可以有自己的LDT,也可以没有。当任务没有LDT时,TSS中LDT选择子为0。如果TSS中LDT选择子非空,则从GDT中读出对应的LDT描述符,在经过测试后,把所读的LDT描述符装入LDTR高速缓冲寄存器。如果LDT选择子为空,则将LDT的存在位置为0,表明任务不使用LDT。

第九,装载代码段寄存器CS、堆栈段寄存器SS和各数据段寄存器及其高速缓冲寄存器。在装入代码段高速缓存之前,也要进行特权检查,处理器调整TSS中的CS选择子的RPL=0,装入之后,调整CS的RPL等于目标代码段的DPL。堆栈段使用的是TSS中的SS和SP字段的值,而不是使用内层栈保存区中的指针,即使发生了向内层特权级的变换。这与任务内的通过调用门的转移不同。

第十,把调试寄存器DR7中的局部启用位置为0,以清除局部于原任务的各个断点和方式。

4.关于任务状态和嵌套的说明

需要注意的是,任务切换不能递归。

在段间转移指令JMP引起任务切换时,不实施链接,不导致任务的嵌套。它要求目标任务是可用任务。切换过程中把原任务置为“可用”,目标任务置为“忙”。

在段间调用指令CALL引起任务切换时,实施链接,导致任务的嵌套。它要求目标任务是可用的任务。在切换过程中把目标任务置为“忙”,原任务仍保持“忙”;标志寄存器EFLAGS中的NT位被置为1,表示任务是嵌套任务。

在由中断异常引起任务切换时,实施链接,导致任务的嵌套。要求目标任务是可用的任务。在切换过程中把目标任务置为“忙”,原任务仍保持“忙”;标志寄存器EFLAGS中的NT位被置为1,表示任务是嵌套任务。

在执行IRET指令时引起任务切换,那么实施解链。要求目标任务是忙的任务。在切换过程中把原任务置为“可用”,目标任务仍保持“忙”。关于中断/异常如何引起任务切换和指令IRET如何考虑任务切换的内容将在后面的文章中论述。

上一页  1 2 3 4  下一页

Tags:汇编 教程 控制

编辑录入:爽爽 [复制链接] [打 印]
赞助商链接