⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 9.txt

📁 对I386硬件平台的详尽分析,对LINUX内核学习有很大帮助
💻 TXT
字号:
08h,0000h ;CS.0 
  > dw 0028h,0000h ;SS.0 
  > dw 0010h,0000h ;DS,0 
  > dw 0010h,0000h ;FS.0 
  > dw 0010h,0000h ;GS.0 
  > dw 0000h,0000h ;LDT.0 
  > dw 0000h,0068h ;0.IOMAP起点 
  > db 1000h dup (0) ;4K IOMAP 表 
  > dw 0ffffh 
  > 
  > 
  > 如果您的程式使用 JMP XXXX:YYYYYYYY 的方式跳到本区节的话 ,原本指定的 
  > YYYYYYYY 将无用途 ,因为所有的暂存器将被替换成此表格的数值(含CS.EIP) ,并 
  > 完成等级切换的动作。 
  > 
  > 
  > -------------------------------------------------------------------------- 
  > ┌───────┐ 
  > │进入 V86 模式│ 
  > └───────┘ 
  > 
  > cli 
  > lgdt fword ptr cs:gdtadds 
  > lidt fword ptr cs:idtadds 
  > mov eax,cr0 
  > or al,01h 
  > mov cr0,eax 
  > mov bx,0018h 
  > ltr bx ;发生工作切换时 ,SS:ESP 将参考 0018 的区段表格 
  > jmp 0020h:0000h ;进入工作切换 ,会跳到此表格内指定的 CS:EIP 
  > (LTR.JMP 不可指向同一表格) 
  > 
  > enter_v86 : ;假设您已将 CS:EIP 指向此处继续执行 
  > xor eax,eax 
  > mov ax,code 
  > push eax ;GS 
  > push eax ;FS 
  > push eax ;DS 
  > push eax ;ES 
  > push eax ;SS 
  > mov ax,0f000h 
  > push eax ;ESP 
  > mov eax,00023000h ;设定VM=1 等级=3 
  > push eax ;Eflag 
  > xor eax,eax 
  > mov ax,code 
  > push eax ;CS 
  > mov ax,offset return_dos 
  > push eax ;EIP 
  > clts ;将 387 切换成 32 位元模式 
  > iretd ;回到 V86 (共弹出24h BYTE) 
  > 
  > 紧接著就程式回到 V86 下继续执行著... 
  > -------------------------------------------------------------------------- 
  > ┌────────┐ 
  > │中断向量表的处理│ 
  > └────────┘ 
  > 在 V86 下产生中断後 ,电脑会自动切回保护模式 ,并从 LTR 所指定的位址取得 
  > TSS 表格 ,然後以表格内的资料重新设定 SS.ESP ,然後把 V86 下的各暂存器值摆入 
  > 此堆叠内 ,在此需注意的是它摆放在堆叠的资料是32位元方式 ,所以对於 DS.ES.... 
  > 这类16位元暂存器摆於堆叠 ,不足部份补 '0000' ,用以凑足 32Bit。 
  > 
  > 简单来说 ,在真实模式下或 V86下使用一组 SS:SP ,一但透过中断i入保护模式 
  > 後 ,原先的 SS:SP 暂存器将被置换另一组数值(定义於TSS表) ,然後再将大部份的暂 
  > 存器值摆放在这个新堆叠区内(包含SS.ESP) ,直到执行 IRETD 回到 V86 後 ,SS:ESP 
  > 暂存器值才会从原先堆叠中弹出。换句话说 ,在 V86下发生中断会使用自己的堆叠 , 
  > 而不会破坏 V86 的堆叠区 ,这也就是为什麽像 S-ICE 除错程式执行 'T' 的命令却 
  > 不会更动 User 的堆叠资料。 
  > 
  > 存於保护模式堆叠内的 CS:EIP 会指向 V86下 "INT_X" 的下一行 ,而 SS:SP 值 
  > 却仍维持原来数值(不像以往产生中断会自动减6 ,然後堆叠内摆入 FLAG.CS.IP),因 
  > 此保护模式下处理中断的程式必需修改 V86 的 SP 值减6 ,并将 V86 的 CS.IP.FLAG 
  > 摆入 V86 的堆叠 ,最後再去查 0000:0000 的表格 ,将保护模式堆叠内的 CS:EIP 值 
  > 修改、指向此中断向量表 ,最後保护模式的程式执行 IRETD 返回 V86 後 ,跳到 V86 
  > 下的中断所指位址 ,这样便完成整个模拟 DOS 中断的效果。 
  > 
  > PS:保护模式下堆叠会存放 EFLAG.EIP.ECS.ESP.SS...... 忘了 ,比 Real Mode 还要 
  > 多好多喔。 
  > 
  > 底下仅列出部份中断的处理方式....您必需处理 256 个中断表。 
  > 
  > new_20 : 
  > push 0020h 
  > jmp int_emu 
  > new_21 : 
  > push 0021h 
  > jmp int_emu 
  > new_22 : 
  > push 0022h 
  > jmp int_emu 
  > new_23 : 
  > push 0023h 
  > jmp int_emu 
  > 
  > int_emu : 
  > push bp 
  > mov bp,sp 
  > add bp,04h 
  > push eax 
  > push ebx 
  > mov ax,0010h ; 
  > mov ds,ax ;(Selector 0010h 的 Base=0) 
  > mov ax,ss:[bp+0ch] ; 
  > sub ax,06h ;改V86的SP-6 
  > mov ss:[bp+0ch],ax ; 
  > xor eax,eax ; 
  > xor ebx,ebx ;修改V86下的SS:SP ,帮它摆入 
  > mov ax,ss:[bp+10h] ;INT_X 後的下一行位址 ,供V86 
  > shl eax,04h ;下的程式IRET返回INT_X的下一行用 
  > mov bx,ss:[bp+0ch] ; 
  > add ebx,eax ; 
  > mov ax,ss:[bp+00h] ; 
  > mov ds:[ebx],ax ; 
  > mov ax,ss:[bp+04h] ; 
  > mov ds:[ebx+02h],ax ; 
  > mov ax,ss:[bp+08h] ; 
  > mov ds:[ebx+04h],ax ; 
  > nop 
  > xor ebx,ebx ; 
  > mov bx,ss:[bp-02h] ; 
  > shl ebx,02h ; 
  > mov ax,ds:[ebx] ;IRETD 後到V86中断表所指的位址继续执行 
  > mov ss:[bp+00h],ax ;(查 0000:0000 的中断表) 
  > mov ax,ds:[ebx+02h] ; 
  > mov ss:[bp+04h],ax ; 
  > mov eax,ss:[bp+08h] 
  > or eax,00032000h ;等级=3 VM=1 
  > and eax,0fffffeffh ;关闭'T'旗标 
  > mov ss:[bp+08h],eax 
  > pop ebx 
  > pop eax 
  > pop bp 
  > add sp,02h 
  > iretd 
  > 
  > -------------------------------------------------------------------------- 
  > ┌──────┐ 
  > │拦 I/O 能力│ 
  > └───w──┘ 
  > 
  > TSS 表格内除了可定义产生工作切换後 ,SS.ESP.DS.ES....各暂存器替换值 ,也 
  > 可以开一块记忆体做 IOMAP ,这块记忆体每个 Bit 代表一个 PORT ,一般习惯是开4K 
  > 大小 (65536埠),当某位元设定为 '1' 後 ,只要不是最高等级的人去读写此埠 ,都会 
  > 发生 GP Err #0D ,当然在最低等级的 V86 程式也不例外 ,发生此错误後 ,就形同拦 
  > 到 I/O 动作了 ,紧接著透过最高等级的处理程式去判断发生错误的原因 ,例如判断 
  > 程式码是否为 『EC IN AL,D

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -