首页
社区
课程
招聘
[求助]保护模式问题
发表于: 2007-12-23 23:55 5266

[求助]保护模式问题

2007-12-23 23:55
5266
电脑启动后,将本程序加载到6200H,运行到TEMPCODESEG2段,最后一条指令jump16  620h,offset going出错,高手指点一下

;============================================================================
INCLUDE         386SCD.INC

OffsetOfLoader                equ        0h        ; LOADER.BIN 被加载到的位置 ---- 偏移地址
RootDirSectors                equ        14        ; 根目录占用空间
SectorNoOfRootDirectory        equ        19        ; Root Directory 的第一个扇区号
SectorNoOfFAT1                equ        1        ; FAT1 的第一个扇区号        = BPB_RsvdSecCnt
DeltaSectorNo                equ        17        ; DeltaSectorNo = BPB_RsvdSecCnt + (BPB_NumFATs * FATSz) - 2

;============================================================================
phkernel32_ad   =       304000h
kernel32ADDR    =       2000H
fileaddr        =       2000h
;============================================================================
callfile macro filename,fileaddr
local d1,d2,next
jmp next
d1 db '&filename' ;11位大写
d2 dw fileaddr
next:
lea bx,d1
push bx
lea bx,d2
push bx
call loaderfile
endm

;============================================================================
RCodeSeg        SEGMENT para USE16                ;实方式的初始化代码和数据
                ASSUME  CS:RCodeSeg,ds:gdtseg
;----------------------------------------------------------------------------
;----------------------------------------------------------------------------
start:
                mov     ax,cs
                mov     nextaddr,ax
                add     ax,gdtseg
                mov     ds,ax
                mov     gdtsegcode.basel,ax
               
                mov     ax,cs
                add     ax,StackSeg
                mov     ss,ax
                mov     stacks.basel,ax
                mov     sp,StackLen
               
               
                mov     ax,cs
                add     ax,rcodeseg
                mov     rcodesegcode.basel,ax
               
                mov     ax,cs
                add     ax,TempCodeSeg1
                mov     tempCode1.BASEL,ax
               
                mov     ax,cs
                add     ax,TempCodeSeg2
                mov     tempCode2.BASEL,ax
                call    InitGDT                   ;初始化全局描述符表GDT
               
                lea     bx,d1
          going:
                push    bx
                lea     bx,d2
                push    bx
                call    loaderfile
               
                EnableA20
                lgdt    ds:VGDTR           ;装载GDTR
                cli                               ;关中断
                mov     eax,cr0
                or      al,1
                mov     cr0,eax
                jump16    TempCode1_sel,0h
        
         toreal:
                mov     ax,cs
                add     ax,gdtseg
                mov     ds,ax
                mov     ax,cs
                add     ax,stackseg
                mov     ss,ax
                DisableA20
                sti         
                lea     bx,d1+11
                jmp     going
;----------------------------------------------------------------------------
InitGDT         PROC
                push    ds
                mov     cx,GDNum
                mov     si,OFFSET EFFGDT
InitG:         
                assume  si:ptr desc
                mov     ax,[si].BaseL
                movzx   eax,ax
                shl     eax,4
                shld    edx,eax,16
                mov     WORD PTR [si].BaseL,ax
                mov     BYTE PTR [si].BaseM,dl
                mov     BYTE PTR [si].BaseH,dh
                add     si,SIZE Desc
                loop    InitG
                pop     ds
                mov     bx,16
                mov     ax,cs
                add     ax,GDTSeg
                mul     bx
                mov     WORD PTR VGDTR.Base,ax
                mov     WORD PTR VGDTR.Base+2,dx
                ret
InitGDT         ENDP

;----------------------------------------------------------------------------

loaderfile proc far pascal,
                      LoaderFileName:word,BaseOfLoader:word
; 清屏
        mov        ax, 0600h                ; AH = 6,  AL = 0h
        mov        bx, 0700h                ; 黑底白字(BL = 07h)
        mov        cx, 0                        ; 左上角: (0, 0)
        mov        dx, 0184fh                ; 右下角: (80, 50)
        int        10h                        ; int 10h

        mov        dh, 0                        ; "Booting  "
        call        DispStr                        ; 显示字符串
       
        xor        ah, ah        ; ┓
        xor        dl, dl        ; ┣ 软驱复位
        int        13h        ; ┛
       
; 下面在 A 盘的根目录寻找 LOADER.BIN
        mov        word ptr[wSectorNo], SectorNoOfRootDirectory
LABEL_SEARCH_IN_ROOT_DIR_BEGIN:
        cmp        word ptr[wRootDirSizeForLoop], 0        ; ┓
        jz        LABEL_NO_LOADERBIN                ; ┣ 判断根目录区是不是已经读完
        dec        word ptr[wRootDirSizeForLoop]        ; ┛ 如果读完表示没有找到 LOADER.BIN
        mov        bx, BaseOfLoader
        mov ax,ds:[bx]
        mov        es, ax                        ; es <- BaseOfLoader
        mov        bx, OffsetOfLoader        ; bx <- OffsetOfLoader        于是, es:bx = BaseOfLoader:OffsetOfLoader
        mov        ax, [wSectorNo]        ; ax <- Root Directory 中的某 Sector 号
        mov        cl, 1
        call        ReadSector

        mov        si, LoaderFileName        ; ds:si -> "LOADER  BIN"
        mov        di, OffsetOfLoader        ; es:di -> BaseOfLoader:0100 = BaseOfLoader*10h+100
        cld
        mov        dx, 10h
LABEL_SEARCH_FOR_LOADERBIN:
        cmp        dx, 0                                                                                ; ┓循环次数控制,
        jz        LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR        ; ┣如果已经读完了一个 Sector,
        dec        dx                                                                                        ; ┛就跳到下一个 Sector
        mov        cx, 11
LABEL_CMP_FILENAME:
        cmp        cx, 0
        jz        LABEL_FILENAME_FOUND        ; 如果比较了 11 个字符都相等, 表示找到
dec        cx
        lodsb                                ; ds:si -> al
        cmp        al, byte ptr es:[di]
        jz        LABEL_GO_ON
        jmp        LABEL_DIFFERENT                ; 只要发现不一样的字符就表明本 DirectoryEntry 不是
; 我们要找的 LOADER.BIN
LABEL_GO_ON:
        inc        di
        jmp        LABEL_CMP_FILENAME        ;        继续循环

LABEL_DIFFERENT:
        and        di, 0FFE0h                                                ; else ┓        di &= E0 为了让它指向本条目开头
        add        di, 20h                                                        ;     ┃
        mov        si, LoaderFileName                                        ;     ┣ di += 20h  下一个目录条目
        jmp        LABEL_SEARCH_FOR_LOADERBIN;    ┛

LABEL_GOTO_NEXT_SECTOR_IN_ROOT_DIR:
        add        word ptr[wSectorNo], 1
        jmp        LABEL_SEARCH_IN_ROOT_DIR_BEGIN

LABEL_NO_LOADERBIN:
        mov        dh, 2                        ; "No LOADER."
        call        DispStr                        ; 显示字符串
%ifdef        _BOOT_DEBUG_
        mov        ax, 4c00h                ; ┓
        int        21h                        ; ┛没有找到 LOADER.BIN, 回到 DOS
%else
        jmp        $                        ; 没有找到 LOADER.BIN, 死循环在这里
%endif

LABEL_FILENAME_FOUND:                        ; 找到 LOADER.BIN 后便来到这里继续
        mov        ax, RootDirSectors
        and        di, 0FFE0h                ; di -> 当前条目的开始
        add        di, 01Ah                ; di -> 首 Sector
        mov        cx, word ptr es:[di]
        push        cx                        ; 保存此 Sector 在 FAT 中的序号
        add        cx, ax
        add        cx, DeltaSectorNo        ; 这句完成时 cl 里面变成 LOADER.BIN 的起始扇区号 (从 0 开始数的序号)
        mov        bx, BaseOfLoader
        mov ax,ds:[bx]
        mov        es, ax                        ; es <- BaseOfLoader
        mov        bx, OffsetOfLoader        ; bx <- OffsetOfLoader        于是, es:bx = BaseOfLoader:OffsetOfLoader = BaseOfLoader * 10h + OffsetOfLoader
        mov        ax, cx                        ; ax <- Sector 号

LABEL_GOON_LOADING_FILE:
        push        ax                        ; ┓
        push        bx                        ; ┃
        mov        ah, 0Eh                        ; ┃ 每读一个扇区就在 "Booting  " 后面打一个点, 形成这样的效果:
        mov        al, '.'                        ; ┃
        mov        bl, 0Fh                        ; ┃ Booting ......
        int        10h                        ; ┃
        pop        bx                        ; ┃
        pop        ax                        ; ┛

        mov        cl, 1
        call        ReadSector
        pop        ax                        ; 取出此 Sector 在 FAT 中的序号
        ;----------------------------------------------------------------------------
; 函数名: GetFATEntry
;----------------------------------------------------------------------------
; 作用:
;        找到序号为 ax 的 Sector 在 FAT 中的条目, 结果放在 ax 中
;        需要注意的是, 中间需要读 FAT 的扇区到 es:bx 处, 所以函数一开始保存了 es 和 bx
GetFATEntry:
        push        es
        push        bx
        push        ax
        mov        bx,BaseOfLoader
        mov ax,ds:[bx]
        sub        ax, 0100h                ; ┣ 在 BaseOfLoader 后面留出 4K 空间用于存放 FAT
        mov        es, ax                        ; ┛
        pop        ax
        mov        byte ptr[bOdd], 0
        mov        bx, 3
        mul        bx                        ; dx:ax = ax * 3
        mov        bx, 2
        div        bx                        ; dx:ax / 2  ==>  ax <- 商, dx <- 余数
        cmp        dx, 0
        jz        LABEL_EVEN
        mov        byte ptr[bOdd], 1
LABEL_EVEN:;偶数
        xor        dx, dx                        ; 现在 ax 中是 FATEntry 在 FAT 中的偏移量. 下面来计算 FATEntry 在哪个扇区中(FAT占用不止一个扇区)
        mov        bx, [BPB_BytsPerSec]
        div        bx                        ; dx:ax / BPB_BytsPerSec  ==>        ax <- 商   (FATEntry 所在的扇区相对于 FAT 来说的扇区号)
                                        ;                                dx <- 余数 (FATEntry 在扇区内的偏移)。
        push        dx
        mov        bx, 0                        ; bx <- 0        于是, es:bx = (BaseOfLoader - 100):00 = (BaseOfLoader - 100) * 10h
        add        ax, SectorNoOfFAT1        ; 此句执行之后的 ax 就是 FATEntry 所在的扇区号
        mov        cl, 2
        call        ReadSector                ; 读取 FATEntry 所在的扇区, 一次读两个, 避免在边界发生错误, 因为一个 FATEntry 可能跨越两个扇区
        pop        dx
        add        bx, dx
        mov        ax,es:[bx]
        cmp        byte ptr[bOdd], 1
        jnz        LABEL_EVEN_2
        shr        ax, 4
LABEL_EVEN_2:
        and        ax, 0FFFh

LABEL_GET_FAT_ENRY_OK:

        pop        bx
        pop        es
;        ret
        cmp        ax, 0FFFh
        jz        LABEL_FILE_LOADED
        push        ax                        ; 保存 Sector 在 FAT 中的序号
        mov        dx, RootDirSectors
        add        ax, dx
        add        ax, DeltaSectorNo
        add        bx, [BPB_BytsPerSec]
        jmp        LABEL_GOON_LOADING_FILE
LABEL_FILE_LOADED:

        mov        dh, 1                        ; "Ready."
        call        DispStr                        ; 显示字符串

; *****************************************************************************************************
; *****************************************************************************************************
ret
loaderfile endp

;----------------------------------------------------------------------------
; 函数名: DispStr
;----------------------------------------------------------------------------
; 作用:
;        显示一个字符串, 函数开始时 dh 中应该是字符串序号(0-based)
DispStr proc
  pusha
        mov        ax, MessageLength
        mul        dh
        add        ax, offset BootMessage
        mov        bp, ax                        ; ┓
        mov        ax, ds                        ; ┣ ES:BP = 串地址
        mov        es, ax                        ; ┛
        mov        cx, MessageLength        ; CX = 串长度
        mov        ax, 01301h                ; AH = 13,  AL = 01h
        mov        bx, 0007h                ; 页号为0(BH = 0) 黑底白字(BL = 07h)
        mov        dl, 0
        int        10h                        ; int 10h
        popa
        ret
       
dispstr endp

;----------------------------------------------------------------------------
; 函数名: ReadSector
;----------------------------------------------------------------------------
; 作用:
;        从第 ax 个 Sector 开始, 将 cl 个 Sector 读入 es:bx 中
ReadSector proc
        ; -----------------------------------------------------------------------
        ; 怎样由扇区号求扇区在磁盘中的位置 (扇区号 -> 柱面号, 起始扇区, 磁头号)
        ; -----------------------------------------------------------------------
        ; 设扇区号为 x
        ;                           ┌ 柱面号 = y >> 1
        ;       x           ┌ 商 y ┤
        ; -------------- => ┤      └ 磁头号 = y & 1
        ;  每磁道扇区数     │
        ;                   └ 余 z => 起始扇区号 = z + 1
        pusha
        mov        bp, sp
        sub        esp, 2                        ; 辟出两个字节的堆栈区域保存要读的扇区数: byte [bp-2]

        mov        byte ptr[bp-2], cl
        push        bx                        ; 保存 bx
        mov        bl,byte ptr[BPB_SecPerTrk]        ; bl: 除数
        div        bl                        ; y 在 al 中, z 在 ah 中
        inc        ah                        ; z ++
        mov        cl, ah                        ; cl <- 起始扇区号
        mov        dh, al                        ; dh <- y
        shr        al, 1                        ; y >> 1 (其实是 y/BPB_NumHeads, 这里BPB_NumHeads=2)
        mov        ch, al                        ; ch <- 柱面号
        and        dh, 1                        ; dh & 1 = 磁头号
        pop        bx                        ; 恢复 bx
        ; 至此, "柱面号, 起始扇区, 磁头号" 全部得到 ^^^^^^^^^^^^^^^^^^^^^^^^
        mov        dl, [BS_DrvNum]                ; 驱动器号 (0 表示 A 盘)
GoOnReading:
        mov        ah, 2                        ; 读
        mov        al, byte ptr[bp-2]                ; 读 al 个扇区
        int        13h
        jc        GoOnReading                ; 如果读取错误 CF 会被置为 1, 这时就不停地读, 直到正确为止

        add        esp, 2
        popa
        ret
ReadSector endp
rcodeseglen = $
RCodeSeg        ENDS
               
GDTSeg          SEGMENT para USE16                ;全局描述符表数据段(16位)
;----------------------------------------------------------------------------
                ;全局描述符表GDT

GDT             LABEL   BYTE
                ;空描述符
DUMMY           Desc    <>
                ;规范段描述符及选择子
Normal          Desc    <0ffffh,,,atdw,,>
Normal_Sel      =       Normal-GDT
                ;页目录表所在段描述符(在保护方式下初始化时用)及选择子

phkernel32       Desc    <0ffffh,phkernel32_ad AND 0ffffh,phkernel32_ad SHR 16,ATDW,,>
phkernel32_Sel      =       phkernel32-GDT
;----------------------------------------------------------------------------
                ;以下是需额外初始化的描述符

EFFGDT          LABEL   BYTE
                ;临时代码段描述符及选择子
rcodesegCode        Desc    <rcodeseglen-1,2222h,,ATCE,,>         ;代码段TempCodeSeg的选择子
rcodesegCode_Sel    =       rcodesegCode-GDT

TempCode1        Desc    <tempcodeseg1len-1,2222h,,ATCE,d32,>         ;代码段TempCodeSeg的选择子
TempCode1_Sel    =       TempCode1-GDT

TempCode2        Desc    <tempcodeseg2len-1,2222h,,ATCE,,>         ;代码段TempCodeSeg的选择子
TempCode2_Sel    =       TempCode2-GDT
                ;演示代码段描述符及选择子

kernel32Code           Desc    <0ffffh,kernel32addr,,ATDW,,>
kernel32Code_Sel       =       kernel32Code-GDT

Stacks          Desc    <StackLen-1,,,ATDW,,>     
Stacks_Sel      =       Stacks-GDT                ;堆栈段描述符选择子

gdtsegcode          Desc    <gdtseglen-1,,,ATdw,,>     
gdtsegcode_Sel      =       gdtsegcode-GDT  
;----------------------------------------------------------------------------
GDTLen          =       $-GDT                     ;全局描述符表长度
GDNum           =       ($-EFFGDT)/(SIZE Desc)    ;需特殊处理的描述符数
;----------------------------------------------------------------------------
VGDTR           PDesc   <GDTLen-1,>

d1 label byte
db 'K1      DLL'
db 'K2      DLL'
d2 dw fileaddr

wRootDirSizeForLoop        dw        RootDirSectors        ; Root Directory 占用的扇区数, 在循环中会递减至零.
wSectorNo                dw        0                ; 要读取的扇区号
bOdd                        db        0                ; 奇数还是偶数

;============================================================================
MessageLength                equ        9
BootMessage                db        "Booting  "; 9字节, 不够则用空格补齐. 序号 0
Message1                db        "Ready.   "; 9字节, 不够则用空格补齐. 序号 1
Message2                db        "No LOADER"; 9字节, 不够则用空格补齐. 序号 2
;============================================================================
BPB_BytsPerSec        DW 512                ; 每扇区字节数
BPB_SecPerTrk        DW 18                ; 每磁道扇区数
BS_DrvNum        DB 0                ; 中断 13 的驱动器号
edinum    dd 0h
nextaddr  dw 0h
gdtseglen = $
GDTSeg          ENDS                              ;全局描述符表段定义结束
;============================================================================
;这部分代码在初始化时被复制到预定的内存区域,其功能是在屏幕上显示提示信息
;----------------------------------------------------------------------------
;============================================================================
TempCodeSeg1     SEGMENT para USE32                ;临时任务的代码段
                ASSUME  CS:TempCodeSeg1
;----------------------------------------------------------------------------
        virtual:
                mov     ax,gdtsegcode_sel
                mov     ds,ax
                mov     edi,edinum
                mov     ax,stacks_sel
                mov     ss,ax
                mov     ax,kernel32code_sel              ;行位于较高线性地址空间中
                mov     ds,ax
                mov     ax,phkernel32_Sel
                mov     es,ax
                mov     esi,0
                mov     ecx,0ffffh                   ;把分页演示代码复制到预定
                cld
                rep     movsb
                mov     ax,gdtsegcode_sel
                mov     ds,ax
                mov     edinum,edi
                jump32  tempcode2_sel,0h
                tempcodeseg1len = word ptr $
TempCodeSeg1     ENDS

tempcodeseg2    segment use16
                assume cs:tempcodeseg2
                mov     ax,Normal_sel
                mov     ds,ax
                mov     es,ax
                mov     ss,ax
                mov     eax,cr0
                and     al,11111110b
                mov     cr0,eax
                JUMP16  651h,OFFSET next
            next:
                assume ds:gdtseg,ss:stackseg
                mov     ax,620h
                add     ax,gdtseg
                mov     ds,ax
                mov     ax,620h
                add     ax,stackseg
                mov     ss,ax
                DisableA20
                sti         
                lea     bx,d1+11
                jump16  620h,offset going
                tempcodeseg2len = $      
;----------------------------------------------------------------------------
TempCodeSeg2     ENDS               

StackSeg        SEGMENT PARA STACK USE16
StackLen        =       256
                DB      StackLen DUP(0)
StackSeg        ENDS

end start

;名称:386SCD.INC
;功能:符号常量等的定义
;----------------------------------------------------------------------------
;IFNDEF         __386SCD_INC
;__386SCD_INC   EQU     1
;----------------------------------------------------------------------------
.386P
;----------------------------------------------------------------------------
;打开A20地址线
;----------------------------------------------------------------------------
EnableA20       MACRO
                push    ax
                in      al,92h
                or      al,00000010b
                out     92h,al
                pop     ax
                ENDM
;----------------------------------------------------------------------------
;关闭A20地址线
;----------------------------------------------------------------------------
DisableA20      MACRO
                push    ax
                in      al,92h
                and     al,11111101b
                out     92h,al
                pop     ax
                ENDM
;----------------------------------------------------------------------------
;16位偏移的段间直接转移指令的宏定义(在16位代码段中使用)
;----------------------------------------------------------------------------
JUMP16          MACRO   Selector,Offset
                DB      0eah     ;操作码
                DW      Offset   ;16位偏移量
                DW      Selector ;段值或段选择子
                ENDM
;----------------------------------------------------------------------------
;32位偏移的段间直接转移指令的宏定义(在32位代码段中使用)
;----------------------------------------------------------------------------
COMMENT <JUMP32>
JUMP32          MACRO   Selector,Offset
                DB      0eah     ;操作码
                DD      OFFSET
                DW      Selector ;段值或段选择子
                ENDM
<JUMP32>
;-------------------------------------------------
JUMP32          MACRO   Selector,Offset
                DB      0eah     ;操作码
                DW      OFFSET
                DW      0
                DW      Selector ;段值或段选择子
                ENDM
;----------------------------------------------------------------------------
;16位偏移的段间调用指令的宏定义(在16位代码段中使用)
;----------------------------------------------------------------------------
CALL16          MACRO   Selector,Offset
                DB      9ah      ;操作码
                DW      Offset   ;16位偏移量
                DW      Selector ;段值或段选择子
                ENDM
;----------------------------------------------------------------------------
;32位偏移的段间调用指令的宏定义(在32位代码段中使用)
;----------------------------------------------------------------------------
COMMENT <CALL32>
CALL32          MACRO   Selector,Offset
                DB      9ah      ;操作码
                DD      Offset
                DW      Selector ;段值或段选择子
                ENDM
<CALL32>
;-------------------------------------------------
CALL32          MACRO   Selector,Offset
                DB      9ah      ;操作码
                DW      Offset
                DW      0
                DW      Selector ;段值或段选择子
                ENDM
;----------------------------------------------------------------------------
;存储段描述符结构类型定义
;----------------------------------------------------------------------------
Desc            STRUC
LimitL          DW      0 ;段界限(BIT0-15)
BaseL           DW      0 ;段基地址(BIT0-15)
BaseM           DB      0 ;段基地址(BIT16-23)
Attributes      DB      0 ;段属性
LimitH          DB      0 ;段界限(BIT16-19)(含段属性的高4位)
BaseH           DB      0 ;段基地址(BIT24-31)
Desc            ENDS
;----------------------------------------------------------------------------
;门描述符结构类型定义
;----------------------------------------------------------------------------
Gate            STRUC
OffsetL         DW      0 ;32位偏移的低16位
Selector        DW      0 ;选择子
DCount          DB      0 ;双字计数
GType           DB      0 ;类型
OffsetH         DW      0 ;32位偏移的高16位
Gate            ENDS
;----------------------------------------------------------------------------
;伪描述符结构类型定义(用于装入全局或中断描述符表寄存器)
;----------------------------------------------------------------------------
PDesc           STRUC
Limit           DW      0 ;16位界限
Base            DD      0 ;32位基地址
PDesc           ENDS
;----------------------------------------------------------------------------
;任务状态段结构类型定义
;----------------------------------------------------------------------------
TSS             STRUC
TRLink          DW      0      ;链接字段
                DW      0      ;不使用,置为0
TRESP0          DD      0      ;0级堆栈指针
TRSS0           DW      0      ;0级堆栈段寄存器
                DW      0      ;不使用,置为0
TRESP1          DD      0      ;1级堆栈指针
TRSS1           DW      0      ;1级堆栈段寄存器
                DW      0      ;不使用,置为0
TRESP2          DD      0      ;2级堆栈指针
TRSS2           DW      0      ;2级堆栈段寄存器
                DW      0      ;不使用,置为0
TRCR3           DD      0      ;CR3
TREIP           DD      0      ;EIP
TREFlag         DD      0      ;EFLAGS
TREAX           DD      0      ;EAX
TRECX           DD      0      ;ECX
TREDX           DD      0      ;EDX
TREBX           DD      0      ;EBX
TRESP           DD      0      ;ESP
TREBP           DD      0      ;EBP
TRESI           DD      0      ;ESI
TREDI           DD      0      ;EDI
TRES            DW      0      ;ES
                DW      0      ;不使用,置为0
TRCS            DW      0      ;CS
                DW      0      ;不使用,置为0
TRSS            DW      0      ;SS
                DW      0      ;不使用,置为0
TRDS            DW      0      ;DS
                DW      0      ;不使用,置为0
TRFS            DW      0      ;FS
                DW      0      ;不使用,置为0
TRGS            DW      0      ;GS
                DW      0      ;不使用,置为0
TRLDTR          DW      0      ;LDTR
                DW      0      ;不使用,置为0
TRTrip          DW      0      ;调试陷阱标志(只用位0)
TRIOMap         DW      $+2    ;指向I/O许可位图区的段内偏移
TSS             ENDS
;----------------------------------------------------------------------------
;存储段描述符类型值说明
;----------------------------------------------------------------------------
ATDR            EQU     90h ;存在的只读数据段类型值
ATDW            EQU     92h ;存在的可读写数据段属性值
ATDWA           EQU     93h ;存在的已访问可读写数据段类型值
ATCE            EQU     98h ;存在的只执行代码段属性值
ATCER           EQU     9ah ;存在的可执行可读代码段属性值
ATCCO           EQU     9ch ;存在的只执行一致代码段属性值
ATCCOR          EQU     9eh ;存在的可执行可读一致代码段属性值
;----------------------------------------------------------------------------
;系统段描述符类型值说明
;----------------------------------------------------------------------------
ATLDT           EQU     82h ;局部描述符表段类型值
ATTaskGate      EQU     85h ;任务门类型值
AT386TSS        EQU     89h ;可用386任务状态段类型值
AT386CGate      EQU     8ch ;386调用门类型值
AT386IGate      EQU     8eh ;386中断门类型值
AT386TGate      EQU     8fh ;386陷阱门类型值
;----------------------------------------------------------------------------
;DPL值说明
;----------------------------------------------------------------------------
DPL0            EQU     00h ;DPL=0
DPL1            EQU     20h ;DPL=1
DPL2            EQU     40h ;DPL=2
DPL3            EQU     60h ;DPL=3
;----------------------------------------------------------------------------
;RPL值说明
;----------------------------------------------------------------------------
RPL0            EQU     00h ;RPL=0
RPL1            EQU     01h ;RPL=1
RPL2            EQU     02h ;RPL=2
RPL3            EQU     03h ;RPL=3
;----------------------------------------------------------------------------
;IOPL值说明
;----------------------------------------------------------------------------
IOPL0           EQU     0000h ;IOPL=0
IOPL1           EQU     1000h ;IOPL=1
IOPL2           EQU     2000h ;IOPL=2
IOPL3           EQU     3000h ;IOPL=3
;----------------------------------------------------------------------------
;其它常量值说明
;----------------------------------------------------------------------------
D32             EQU     40h       ;32位代码段标志
GL              EQU     80h       ;段界限以4K为单位标志
TIL             EQU     04h       ;TI=1(局部描述符表标志)
VMFL            EQU     00020000h ;VMF=1
VMFLW           EQU     0002h
IFL             EQU     00000200h ;IF=1
RFL             EQU     00010000h ;RF=1(重启动标志,为1表示忽略调试故障)
RFLW            EQU     0001h
NTL             EQU     00004000h ;NT=1
;----------------------------------------------------------------------------
;分页机制使用的常量说明
;----------------------------------------------------------------------------
PL              EQU     1     ;页存在属性位
RWR             EQU     0     ;R/W属性位值,读/执行
RWW             EQU     2     ;R/W属性位值,读/写/执行
USS             EQU     0     ;U/S属性位值,系统级
USU             EQU     4     ;U/S属性位值,用户级
;----------------------------------------------------------------------------
;ENDIF

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 1746
活跃值: (287)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
2
jump16  620h,offset going这条指令什么错误提示啊
发生错误时的CPU寄存器环境的环境是什么啊

实模式下,这条指令应该只是简单的设置下
CS=620h
EIP=going
在关A20情况下,现在的机器应该不会触发GP异常

还有你堆栈段和哪个代码段挨一起 会不会有可能堆栈溢出
2007-12-24 01:17
0
雪    币: 321
活跃值: (271)
能力值: ( LV13,RANK:1050 )
在线值:
发帖
回帖
粉丝
3
计算描述符的办法不对吧.

start:
                mov     ax,cs
                mov     nextaddr,ax  ;保存代码段地址

                add     ax,gdtseg     ;这句怎么理解?
                mov     ds,ax
                mov     gdtsegcode.basel,ax ;这个计算方法有问题啊
                ......
2007-12-24 11:15
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
mov     nextaddr,ax  ;保存代码段地址
这行可以去掉,
电脑启动后,本代码被加载到6200H,
ADD AX,GDTSEG即为620H+GDTSEG,将值给DS,
文中‘K1     DLL’为A盘下,文件名为K1.DLL的文件,大小为0FFFFH
2007-12-24 21:57
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不会是堆栈溢出,是为将jump16  620h,offset going这行改为
MOV AX,1111H
MOV AX,2222H
MOV AX,3333H
。。。。。。
问题一样,用BOCH2.3无回显
2007-12-24 22:01
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
我用的是MASM6.11
2007-12-24 22:06
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我顶!!!!!!!!!!!!!!!!!!!!!!!!1
2007-12-25 23:06
0
雪    币: 1746
活跃值: (287)
能力值: (RANK:450 )
在线值:
发帖
回帖
粉丝
8
不懂了~~~~
2007-12-26 23:51
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
有没有人知道,帮我顶
2007-12-27 17:46
0
游客
登录 | 注册 方可回帖
返回
//