日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

调用门

發(fā)布時(shí)間:2025/6/15 44 豆豆
生活随笔 收集整理的這篇文章主要介紹了 调用门 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

門,顧名思義它是一扇門通向令一個(gè)地方,看一下門的結(jié)構(gòu)里面有一個(gè)描述符和一個(gè)偏移值,門中定義了這扇門通向的目的地,當(dāng)我們調(diào)用一個(gè)門的時(shí)候會(huì)到達(dá)這個(gè)地方:

門中的選擇子:門中的偏移值,也即下圖的selector:offset

這是我們代碼中國定義的門的數(shù)據(jù)結(jié)構(gòu):

#define Gate(Selector,Offset,PCount,Attr)\
.2byte (Offset&0xffff);\
.2byte (Selector);\
.2byte (PCount&0x1f)|((Attr<<8)&0xff00);\
.2byte ((Offset>>16)&0xffff)

?

假設(shè)Selector_Gate_Call是調(diào)用門的描述符,執(zhí)行l(wèi)call $Selector_Gate_Call,$0語句時(shí)偏移值($0)無意義,執(zhí)行此語句后

CS=調(diào)用門中的選擇子
IP=調(diào)用門中偏移值
CS:IP=全局描述符表中第(調(diào)用門中的選擇子>>3)項(xiàng)描述符給出的段基址+調(diào)用門中偏移值


調(diào)用門的使用

定義調(diào)用門的描述符和選擇子,如下面代碼

/*門描述符*/
Descriptor_Gate_Call:Gate(Selector_Code_Gate,0,0,(DA_386CGate+DA_PL0))

/*調(diào)用門選擇子*/
.set?Selector_Gate_Call,(Descriptor_Gate_Call-GDT_START)

?

其中調(diào)用門中的選擇子和描述符如下:

Descriptor_CODE_GATE:Descriptor(0x0,CodeGLen,DA_C+DA_32)

.set? Selector_Code_Gate,(Descriptor_CODE_GATE-GDT_START)

?

Descriptor_CODE_GATE的初始化和代碼段如下:

InitDescrptor(Descriptor_CODE_GATE,LABEL_CODE_G);

LABEL_CODE_G:?

??? movl $((80*12+0)*2),%edi/*第10行,0列*/?
??? movb $0x0c,%ah/*高四位0000表示黑底,低四位1100表示紅字*/?
??? movb $'G',%al/*要顯示的字符*/?
??? movw %ax,%gs:(%edi)????
jmp .
?.set CodeGLen,(. - LABEL_CODE_G)

?

這時(shí)lcall $Selector_Gate_Call,$0就會(huì)看到紅色的'G’打印出來,和ljmp Selector_Code_Gate,$0的效果是一樣的,但是這并不是多此一舉的,這涉及的特權(quán)級(jí)轉(zhuǎn)換的問題,這里我們先不關(guān)心這些。

?

/*初始全局描述符Descriptor_CODE_GATE*/?
InitDescrptor(Descriptor_CODE_GATE,LABEL_CODE_G);

具體代碼如下:

[html] view plaincopy
  • #define?Descriptor(base,lim,attr)\??
  • .word?lim&0xffff;\??
  • .word?base&0xffff;\??
  • .byte?(base>>16)&0xff;\??
  • .word?((lim>>8)&0xf00)|(attr&0x0f0ff);\??
  • .byte?((base>>24)&0xff)????
  • ????
  • /*????
  • *InitDescrptor(Descriptor,SegBase)初始化描述符函數(shù)????
  • *Descriptor:要初始化的描述符????
  • *SegBase:段基址????
  • */????
  • #define?InitDescrptor(Descriptor,SegBase)\??
  • xor?????%eax,%eax;?\??
  • mov?????%cs,%ax??;?\??
  • shl?????$4,%eax??;?\??
  • addl????$(SegBase),?%eax?;\??
  • movw????%ax,?(Descriptor?+?2);\??
  • shr?????$16,?%eax;\??
  • movb????%al,?(Descriptor?+?4);\??
  • movb????%ah,?(Descriptor?+?7)????
  • ??
  • #define?Gate(Selector,Offset,PCount,Attr)\??
  • .2byte?(Offset&0xffff);\??
  • .2byte?(Selector);\??
  • .2byte?(PCount&0x1f)|((Attr<<8)&0xff00);\??
  • .2byte?((Offset>>16)&0xffff)????
  • ??
  • DA_386CGate?=?0x8c??
  • DA_PL0?=?0x00??
  • DA_C???=?0x98????
  • DA_32??=?0x4000????
  • DA_DRW?=?0x92????
  • SA_TIL?=?0x4????
  • DA_LDT?=?0x82????
  • ????
  • .text????
  • .globl?start????
  • .code16????
  • start:????
  • ?jmpl?$0x0,?$code?????
  • ?????
  • /**-----------------------------------------------------------------????
  • ?*?全局描述符表:?GDT????
  • ?*-------------------------------*/?????????
  • GDT_START:??????
  • Descriptor_DUMMY:?Descriptor(0x0,0x0,0x0)????
  • Descriptor_CODE32:Descriptor(0x0,0xffffffff,DA_C+DA_32)????
  • Descriptor_VIDEO:?Descriptor(0xb8000,0x0ffff,DA_DRW)????
  • Descriptor_CODE_GATE:Descriptor(0x0,CodeGLen,DA_C+DA_32)??
  • ??
  • /*門描述符*/???
  • Descriptor_Gate_Call:Gate(Selector_Code_Gate,0,0,(DA_386CGate+DA_PL0))????
  • GDT_END:????
  • ????
  • GdtPtr:????
  • ????.word?(GDT_END-GDT_START)-1?#?so?does?gdt?????
  • ????.long?GDT_START?????#?This?will?be?rewrite?by?code.????
  • ??
  • .set????selector_Code32,(Descriptor_CODE32-GDT_START)??
  • .set????Selector_Video,(Descriptor_VIDEO-GDT_START)???????
  • .set??Selector_Code_Gate,(Descriptor_CODE_GATE-GDT_START)??
  • /*調(diào)用門選擇子*/??
  • .set????Selector_Gate_Call,(Descriptor_Gate_Call-GDT_START)??
  • ???
  • msg:????
  • ?.string?"Hello?world!"????
  • ?????
  • ?????
  • code:????
  • ????mov?????%cs,%ax???????
  • ????mov?????%ax,%ds?????
  • ????mov?????%ax,%es????????
  • ????mov?????%ax,%ss??????
  • ????mov??$0x8000,%sp??????
  • ????/*顯示HelloWorld字符串*/????
  • ????mov?$msg???,%ax????
  • ????mov?%ax????,%bp????
  • ????mov?$12????,%cx????
  • ????mov?$0x1301,%ax????
  • ????mov?$0x000c,%bx????
  • ????mov?$0?????,%dl????
  • ????????
  • ????int?$0x10????
  • ????????
  • ????
  • /*初始全局描述符Descriptor_CODE32*/????
  • InitDescrptor(Descriptor_CODE32,LABEL_SEG_CODE32);????
  • ????
  • /*初始全局描述符Descriptor_CODE_GATE*/????
  • InitDescrptor(Descriptor_CODE_GATE,LABEL_CODE_G);????
  • ??
  • /*加載gdtr即將全局描述符表gdt的首地址和gdt的界限賦給gdtr寄存器*/???????????
  • ????lgdt?GdtPtr????
  • ????
  • /*關(guān)中斷*/????
  • ????cli????
  • ????
  • /*打開地址線A20*/????
  • ????inb?$0x92,%al????
  • ????or??$0x02,%al????
  • ????outb?%al,$0x92????
  • ????
  • /*設(shè)置cr0寄存器,切換到保護(hù)模式*/????
  • ????movl?%cr0,%eax????
  • ????or???$1,%eax????
  • ????movl?%eax,%cr0????
  • ????
  • ????
  • /*真正進(jìn)入保護(hù)模式,執(zhí)行此命令后CS=0x8,IP=0*/????
  • ????ljmp?$selector_Code32,$0????
  • ????
  • ??
  • LABEL_SEG_CODE32:????
  • .align??32????
  • .code32????
  • ????
  • ????movw?$Selector_Video,%ax????
  • ????movw?%ax,%gs/*?視頻段選擇子(目的)*/????
  • ????movl?$((80*11+79)*2),%edi/*第11行,79列*/????
  • ????movb?$0x0c,%ah/*高四位表示黑底,低四位表示紅字*/????
  • ????movb?$'P',%al/*顯示的字符*/????
  • ????movw?%ax,%gs:(%edi)????
  • ?????????
  • ????#ljmp?$Selector_Gate_Call,$0??
  • ????lcall?$Selector_Gate_Call,$0????
  • ????
  • ????????
  • jmp?.????
  • ????????
  • LABEL_CODE_G:????
  • ??
  • ????movl?$((80*12+0)*2),%edi/*第10行,0列*/????
  • ????movb?$0x0c,%ah/*高四位0000表示黑底,低四位1100表示紅字*/????
  • ????movb?$'G',%al/*要顯示的字符*/????
  • ????movw?%ax,%gs:(%edi)????
  • ??????
  • jmp?.??
  • ???
  • .set?CodeGLen,(.?-?LABEL_CODE_G)????
  • ????
  • .org?0x1fe,?0x90?????
  • .word?0xaa55???
  • 執(zhí)行結(jié)果如下圖,可以看到紅色的‘G’打印出來


    在LABEL_CODE_G中我們打印完字符就讓程序挺在了這里,這時(shí)候如下兩段代碼的效果是一樣的。

    ljmp $Selector_Gate_Call,$0
    ?lcall $Selector_Gate_Call,$0

    但ljmp和lcall是不一樣的,它們都會(huì)改變寄存器CS和IP實(shí)現(xiàn)程序的跳轉(zhuǎn),但lcall還會(huì)影響堆棧?,段內(nèi)跳轉(zhuǎn)回將ip如棧段間跳轉(zhuǎn)回將cs和ip入棧,等到lret執(zhí)行時(shí)這個(gè)ip(或者cs和ip)會(huì)從堆棧中彈出。

    下面我們就實(shí)現(xiàn)一個(gè)帶返回的調(diào)用門:

    [plain] view plaincopy
  • #define?Descriptor(base,lim,attr)\??
  • .word?lim&0xffff;\??
  • .word?base&0xffff;\??
  • .byte?(base>>16)&0xff;\??
  • .word?((lim>>8)&0xf00)|(attr&0x0f0ff);\??
  • .byte?((base>>24)&0xff)????
  • ????
  • /*????
  • *InitDescrptor(Descriptor,SegBase)初始化描述符函數(shù)????
  • *Descriptor:要初始化的描述符????
  • *SegBase:段基址????
  • */????
  • #define?InitDescrptor(Descriptor,SegBase)\??
  • xor?????%eax,%eax;?\??
  • mov?????%cs,%ax??;?\??
  • shl?????$4,%eax??;?\??
  • addl????$(SegBase),?%eax?;\??
  • movw????%ax,?(Descriptor?+?2);\??
  • shr?????$16,?%eax;\??
  • movb????%al,?(Descriptor?+?4);\??
  • movb????%ah,?(Descriptor?+?7)????
  • ??
  • #define?Gate(Selector,Offset,PCount,Attr)\??
  • .2byte?(Offset&0xffff);\??
  • .2byte?(Selector);\??
  • .2byte?(PCount&0x1f)|((Attr<<8)&0xff00);\??
  • .2byte?((Offset>>16)&0xffff)????
  • ??
  • DA_386CGate?=?0x8c??
  • DA_PL0?=?0x00??
  • DA_C???=?0x98????
  • DA_32??=?0x4000????
  • DA_DRW?=?0x92????
  • SA_TIL?=?0x4????
  • DA_LDT?=?0x82????
  • ????
  • .text????
  • .globl?start????
  • .code16????
  • start:????
  • ?jmpl?$0x0,?$code?????
  • ?????
  • /**-----------------------------------------------------------------????
  • ?*?全局描述符表:?GDT????
  • ?*-------------------------------*/?????????
  • GDT_START:??????
  • Descriptor_DUMMY:?Descriptor(0x0,0x0,0x0)????
  • Descriptor_CODE32:Descriptor(0x0,0xffffffff,DA_C+DA_32)????
  • Descriptor_VIDEO:?Descriptor(0xb8000,0x0ffff,DA_DRW)????
  • Descriptor_CODE_GATE:Descriptor(0x0,CodeGLen,DA_C+DA_32)??
  • Descriptor_LDT:???Descriptor(0x0,LDTLen?-?1,?DA_LDT)??
  • ??
  • /*門描述符*/???
  • Descriptor_Gate_Call:Gate(Selector_Code_Gate,0,0,(DA_386CGate+DA_PL0))????
  • GDT_END:????
  • ????
  • GdtPtr:????
  • ????.word?(GDT_END-GDT_START)-1?#?so?does?gdt?????
  • ????.long?GDT_START?????#?This?will?be?rewrite?by?code.????
  • ??
  • /**-----------------------------------------------------------------????
  • ?*?GDT中的選擇子??
  • ?*-------------------------------*/???
  • .set????selector_Code32,(Descriptor_CODE32-GDT_START)??
  • .set????Selector_Video,(Descriptor_VIDEO-GDT_START)???????
  • .set??Selector_Code_Gate,(Descriptor_CODE_GATE-GDT_START)??
  • .set????SelectorLDT,(Descriptor_LDT-GDT_START)??
  • /*調(diào)用門選擇子*/??
  • .set????Selector_Gate_Call,(Descriptor_Gate_Call-GDT_START)??
  • ??
  • /**-----------------------------------------------------------------??
  • ?*?局部描述符表:?LDT??
  • ?*-------------------------------*/??
  • LDT_START:??
  • /*???????????????????????段基址????段界限??????屬性*/??
  • Descriptor_LDT_CODEA:?Descriptor(0,?CodeALen?-?1,?DA_C?+?DA_32)#?Code,?32?位??
  • ??
  • .set????LDTLen,(.?-?LDT_START)??
  • ??
  • #LDT?選擇子??
  • .set??SelectorLDTCodeA,(0x0?+?SA_TIL)??
  • ???
  • msg:????
  • ?.string?"Hello?world!"????
  • ?????
  • ?????
  • code:????
  • ????mov?????%cs,%ax???????
  • ????mov?????%ax,%ds?????
  • ????mov?????%ax,%es????????
  • ????mov?????%ax,%ss??????
  • ????mov??$0x8000,%sp??????
  • ????/*顯示HelloWorld字符串*/????
  • ????mov?$msg???,%ax????
  • ????mov?%ax????,%bp????
  • ????mov?$12????,%cx????
  • ????mov?$0x1301,%ax????
  • ????mov?$0x000c,%bx????
  • ????mov?$0?????,%dl????
  • ????????
  • ????int?$0x10????
  • ????????
  • ????
  • /*初始全局描述符Descriptor_CODE32*/????
  • InitDescrptor(Descriptor_CODE32,LABEL_SEG_CODE32);???
  • ??
  • /*初始全局描述符Descriptor_LDT*/??
  • InitDescrptor(Descriptor_LDT,LDT_START);??
  • ????
  • /*初始全局描述符Descriptor_CODE_GATE*/????
  • InitDescrptor(Descriptor_CODE_GATE,LABEL_CODE_G);????
  • ??
  • /*初始LDT?中的描述符Descriptor_LDT_CODEA*/??
  • InitDescrptor(Descriptor_LDT_CODEA,LABEL_CODE_A);??
  • ??
  • /*加載gdtr即將全局描述符表gdt的首地址和gdt的界限賦給gdtr寄存器*/???????????
  • ????lgdt?GdtPtr????
  • ????
  • /*關(guān)中斷*/????
  • ????cli????
  • ????
  • /*打開地址線A20*/????
  • ????inb?$0x92,%al????
  • ????or??$0x02,%al????
  • ????outb?%al,$0x92????
  • ????
  • /*設(shè)置cr0寄存器,切換到保護(hù)模式*/????
  • ????movl?%cr0,%eax????
  • ????or???$1,%eax????
  • ????movl?%eax,%cr0????
  • ????
  • ????
  • /*真正進(jìn)入保護(hù)模式,執(zhí)行此命令后CS=0x8,IP=0*/????
  • ????ljmp?$selector_Code32,$0????
  • ????
  • ??
  • ??
  • LABEL_SEG_CODE32:????
  • .align??32????
  • .code32????
  • ????
  • ????movw?$Selector_Video,%ax????
  • ????movw?%ax,%gs/*?視頻段選擇子(目的)*/????
  • ????movl?$((80*11+79)*2),%edi/*第11行,79列*/????
  • ????movb?$0x0c,%ah/*高四位表示黑底,低四位表示紅字*/????
  • ????movb?$'P',%al/*顯示的字符*/????
  • ????movw?%ax,%gs:(%edi)????
  • ?????????
  • ????lcall?$Selector_Gate_Call,$0????
  • ????
  • ??
  • ????movw?$SelectorLDT,%ax??
  • ????????lldt?%ax/*加載lgtr*/??
  • ??
  • ????????ljmp????$SelectorLDTCodeA,$0????/*?跳入局部任務(wù)?LABEL_CODE_A*/??
  • ????????
  • jmp?.????
  • ????????
  • LABEL_CODE_G:????
  • ??
  • ????movl?$((80*12+0)*2),%edi/*第10行,0列*/????
  • ????movb?$0x0c,%ah/*高四位0000表示黑底,低四位1100表示紅字*/????
  • ????movb?$'G',%al/*要顯示的字符*/????
  • ????movw?%ax,%gs:(%edi)????
  • ??????????
  • ????????lret??
  • .set?CodeGLen,(.?-?LABEL_CODE_G)????
  • ??
  • LABEL_CODE_A:??
  • ????movw?$0x10,%ax??
  • ????movw?%ax,%gs/*?視頻段選擇子(目的)*/??
  • ????movl?$((80*12+10)*2),%edi/*第10行,0列*/??
  • ????movb?$0x0c,%ah/*高四位0000表示黑底,低四位1100表示紅字*/??
  • ????movb?$'A',%al/*要顯示的字符*/??
  • ????movw?%ax,%gs:(%edi)??
  • ??????
  • loop3:??
  • ????jmp?loop3??
  • .set?CodeALen,(.?-?LABEL_CODE_A)??
  • ????
  • .org?0x1fe,?0x90?????
  • .word?0xaa55???

  • 其結(jié)果是打印完'G'后返回,然后又打印出'A'如下圖:

    ?

    門也是一個(gè)描述符,我們放到了GDT中,我們通過門的選擇子訪問門,門通過它記錄的選擇子和偏移值又把我們傳送到了目的地。

    ?

    總結(jié)

    以上是生活随笔為你收集整理的调用门的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。