免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2885 | 回复: 9
打印 上一主题 下一主题

我写了个使用任务状态段切换任务的程序,但出错,请大家帮忙看看。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-08-08 17:35 |只看该作者 |倒序浏览
%include "dt.inc"

org        0100h                                                                ;        COM文件
jmp        label_inProtectMode

[SECTION .gdt]                                                                ;        定义描述符
null_GDT:        descriptor        0,0,0                                        ;        空描述符
tast1GDT        descriptor        0, tast1Len - 1, DA_C + DA_32
tast2GDT        descriptor        0, tast2Len - 1, DA_C + DA_32
tssGDT:                descriptor        0, tss_len - 1, DA_E386TSS                ;        TSS描述府
tss2GDT:        descriptor        0, tss2_len - 1, DA_E386TSS               
showGDT:        descriptor        0B8000h, 0ffffh, DA_DRW                        ;        显存

GdtPtr        dw        $ - null_GDT                                                ;        GDTR界限
        dd        0                                                        ;        GDTR基地址

tast1Selector        equ tast1GDT - null_GDT
tast2Selector        equ tast2GDT - null_GDT
tssSelector        equ tssGDT - null_GDT                                        ;        TSS选择子                                                          
tss2Selector        equ tss2GDT - null_GDT                                        ;        TSS2选择子                                                          
showSelector        equ showGDT - null_GDT       

[SECTION .TSS]                                                                ;        任务状态段TSS
[BITS        32]
label_tss:
        DW        0                        ;        链接字段
        DW        0                       
        DD        0                        ;        0级堆栈指针
        DW        0                        ;        SS0
        DW        0
        DD        0                        ;        1级堆栈指针
        DW        0                        ;        SS1
        DW        0
        DD        0                        ;        2级堆栈指针
        DW        0                        ;        SS2
        DW        0
        DD        0                        ;        CR3
        DD        0                        ;        EIP
        DD        0                        ;        EFLAGS
        DD        0                        ;        EAX
        DD        0                        ;        ECX
        DD        0                        ;        EDX
        DD        0                        ;        EBX
        DD        0                        ;        ESP
        DD        0                        ;        EBP
        DD        0                        ;        ESI
        DD        0                        ;        EDI
        DW        0                        ;        ES
        DW        0
        DW        0                        ;        CS
        DW        0
        DW        0                        ;        SS
        DW        0
        DW        0                        ;        DS
        DW        0
        DW        0                        ;        FS
        DW        0
        DW        0                        ;        GS
        DW        0
        DW        0                        ;        LDT
        DW        0
        DW        0                        ;        TSS的特别属性字
        DW        $ - label_tss + 2        ;        指向I/0许可位图区的指针
        DW        0FFH                        ;        I/0许可位图结束字节

tss_len        equ $ - label_tss       

[SECTION .TSS2]                                                                ;        任务状态段TSS2
[BITS        32]
label_tss2:
        DW        0                        ;        链接字段
        DW        0                       
        DD        0                        ;        0级堆栈指针
        DW        0                        ;        SS0
        DW        0
        DD        0                        ;        1级堆栈指针
        DW        0                        ;        SS1
        DW        0
        DD        0                        ;        2级堆栈指针
        DW        0                        ;        SS2
        DW        0
        DD        0                        ;        CR3
        DD        label_tast2                ;        EIP
        DD        0                        ;        EFLAGS
        DD        0                        ;        EAX
        DD        0                        ;        ECX
        DD        0                        ;        EDX
        DD        0                        ;        EBX
        DD        0                        ;        ESP
        DD        0                        ;        EBP
        DD        0                        ;        ESI
        DD        0                        ;        EDI
        DW        0                        ;        ES
        DW        0
        DW        tast2Selector                ;        CS
        DW        0
        DW        0                        ;        SS
        DW        0
        DW        0                        ;        DS
        DW        0
        DW        0                        ;        FS
        DW        0
        DW        0                        ;        GS
        DW        0
        DW        0                        ;        LDT
        DW        0
        DW        0                        ;        TSS的特别属性字
        DW        $ - label_tss2 + 2        ;        指向I/0许可位图区的指针
        DW        0FFH                        ;        I/0许可位图结束字节

tss2_len        equ $ - label_tss2       

[SECTION .inProtectMode]                                                ;        进入保护模式
[BITS        16]
label_inProtectMode:
        mov ax, cs                                                        ;        初始化段寄存器                       
        mov ds, ax
               
        cli                                                                ;        清除EFLAGS的IF位(bit9),不响应可屏蔽中断

        in  al, 92h                                                        ;        打开A20地址线(bit1为1)       
        or  al, 00000010b
        out 92h, al

        mov eax, cr0                                                        ;        设置CRO的PE位(bit0)为1
        or  eax, 1
        mov cr0, eax

        xor eax, eax
        mov eax, ds
        shl eax, 4
        add eax, null_GDT                                                ;        初始化GDTR的基地址
        mov dword [GdtPtr + 2], eax
       
        lgdt [GdtPtr]                                                        ;        加载GDTR       

        xor eax, eax
        mov eax, ds
        shl eax, 4
        add eax, label_tast1                                                ;        设置GDT中Tast1描述府的段基址
        mov word [tast1GDT + 2], ax
        shr eax, 16
        mov byte [tast1GDT + 4], al
        mov byte [tast1GDT + 7], ah

        xor eax, eax
        mov eax, ds
        shl eax, 4
        add eax, label_tast2                                                ;        设置GDT中Tast2描述府的段基址
        mov word [tast2GDT + 2], ax
        shr eax, 16
        mov byte [tast2GDT + 4], al
        mov byte [tast2GDT + 7], ah

        xor eax, eax
        mov eax, ds
        shl eax, 4
        add eax, label_tss                                                ;        设置GDT中TSS描述府的段基址
        mov word [tssGDT + 2], ax
        shr eax, 16
        mov byte [tssGDT + 4], al
        mov byte [tssGDT + 7], ah

        xor eax, eax
        mov eax, ds
        shl eax, 4
        add eax, label_tss2                                                ;        设置GDT中TSS2描述府的段基址
        mov word [tss2GDT + 2], ax
        shr eax, 16
        mov byte [tss2GDT + 4], al
        mov byte [tss2GDT + 7], ah

        jmp dword tast1Selector:0                                        ;        调用tast1的代码

[SECTION .tast1]                                                        ;        tast1
[BITS        32]
label_tast1:
        mov ax, tssSelector                                               
        ltr ax

        jmp tss2Selector:0
tast1Len equ $ - label_tast1

[SECTION .tast2]                                                        ;        tast2
[BITS        32]
label_tast2:
        mov ax, showSelector
        mov gs, ax
       
        mov edi, (80 * 10 + 10) * 2
        mov ah, 0Ch
        mov al, '2'
        mov [gs:edi], ax

        jmp $

tast2Len equ $ - label_tast2

论坛徽章:
0
2 [报告]
发表于 2007-08-08 17:36 |只看该作者
dt.inc是常量和描述符宏的定义

这是用NASM写的,编译成COM文件,在虚拟DOS下运行

我觉得问题好像出在TSS和TSS2的定义上面,但我又看不出错误

论坛徽章:
0
3 [报告]
发表于 2007-08-08 18:48 |只看该作者
None help me?

论坛徽章:
0
4 [报告]
发表于 2007-08-10 12:34 |只看该作者
1。进入保护模式时机不对,不能进入保护模式。
2。用任务门进入tss2. 但tss2没有堆栈.
...

论坛徽章:
0
5 [报告]
发表于 2007-08-10 16:43 |只看该作者
lz给你参考下我的代码吧,也是2个任务在切换,不过是at&&t格式的。
http://blog.chinaunix.net/u/15780/showart.php?id=290150

论坛徽章:
0
6 [报告]
发表于 2007-08-11 09:28 |只看该作者
zbbeng :

    1 我是参照杨秀文的《80X86编程》写的,他的书里面有些任务切换的代码,但用MASM写的,我想用NASM写,进入保护模式的步骤和他的一样。“进入保护模式时机不对”何解?
   2 用TSS的选择子和任务门都可以切换任务,而任务门也是存储了TSS的选择子完成切换的,用TSS的选择子尚且完不成任务切换,用任务门也就不成了。我的2个任务并未涉及到参数,因此未用堆栈,“tss2没有堆栈”何意?

论坛徽章:
0
7 [报告]
发表于 2007-08-11 09:43 |只看该作者
W.Z.T :

  赵炯博士的《Linux内核完全注释》里面也有个例子,是用as86编写的,我不会as86和at&&t汇编,因此大体上看了下,比较了我的代码,看不出我的代码的问题。

  我的QQ是:61924472,咱们聊一下。

论坛徽章:
0
8 [报告]
发表于 2007-08-11 11:21 |只看该作者
应在进入保护模式前初始化gdtr

论坛徽章:
0
9 [报告]
发表于 2007-08-12 18:28 |只看该作者
lgdt [GdtPtr]                                                        ;        加载GDTR   

这句完成了GDTR的初始化

论坛徽章:
0
10 [报告]
发表于 2007-08-14 09:12 |只看该作者
晕, 我说的是顺序,你先进保护模式,后加载gdtr,然后初始化描述符表,这个顺序对吗?我看要反过来。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP