免费注册 查看新帖 |

Chinaunix

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

我写了切换任务的程序,但运行错误,请大家帮忙看看。 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-08-11 10:33 |只看该作者 |倒序浏览
%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-11 10:34 |只看该作者
dt.inc是常量和描述符宏的定义

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

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

论坛徽章:
0
3 [报告]
发表于 2007-08-12 13:50 |只看该作者
LZ:
  TSS 是一种系统 desctriptor,NASM 偶不熟悉 desctriptor 应该是个宏吧,没看你 dt.inc 是如何定义的,不知你的 TSS 定义是否正确。还要注意另一个问题:该问权限要设置得当。

偶看 LZ 的代码错误还是挺多的。

1、TSS descriptor 不是这样用法的。TSS 是由 processor 发生在任务切换时自动引用的。获取 TSS 需经由 Task Gate(任务门)或 Call Gate(调用门)来切换,因此要使用 TSS descriptor 还得建立一个 Task Gate descritptor 或 call gate descriptor。象你这样使用 far call 或 far jmp 直接转移控制是不能引用到 TSS 的。关于这方面还是挺复杂的,也不是两三语可以讲明白的。

2、你这段进入保护模式的代码也有问题,应该先设好 GDT 才转到保护模式。当进入保护模式后直接转移控制权就显得有问题了。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

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

清除 Cookies - ChinaUnix - Archiver - WAP - TOP