zoukankan      html  css  js  c++  java
  • 《80x86汇编语言程序设计》保护模式第一个例题

    《80x86汇编语言程序设计》保护模式第一个例题的一些个人理解和注视

    [cpp] view plain copy
     
    1. ; 16位偏移的段间直接转移指令的宏定义  
    2. jump macro selector, offsetv  
    3.   
    4.     db 0eah                 ; jmp far 的操作码  
    5.     dw offsetv  
    6.     dw selector  
    7.       
    8. endm  
    9.   
    10. ; 字符显示宏指令定义  
    11. echoch macro ascii  
    12.   
    13.     mov ah, 2  
    14.     mov dl, ascii  
    15.     int 21h  
    16.       
    17. endm  
    18.   
    19. ; 存储段描述符结构类型的定义  
    20. descriptor struc  
    21.   
    22. limitl      dw 0                ; 段界限低16位  
    23. basel       dw 0                ; 基地址低16位  
    24. basem       db 0                ; 基地址中8位  
    25. attributes  dw 0                ; 段属性,包含段界限高4位  
    26. baseh       db 0                ; 基地址高8位  
    27.   
    28. descriptor ends  
    29.   
    30. ; 伪描述符结构类型的定义  
    31. pdesc struc  
    32.   
    33. limit       dw 0                ; 16位段界限  
    34. base        dd 0                ; 32位基地址  
    35.   
    36. pdesc ends  
    37.   
    38. ; 常量定义  
    39. atdw = 92h                      ; 存在的可读写数据段属性值  
    40. atce = 98h                      ; 存在的只执行代码段属性值  
    41.   
    42. .386p  
    43.   
    44. ; 数据段  
    45. dseg segment use16  
    46.   
    47. gdt     label byte              ; 全局描述符表GDT  
    48. dummy       descriptor <>             ; 空描述符  
    49. code        descriptor <0ffffh, , , atce, >         
    50. code_sel    = code - gdt                ; 代码段描述的选择子  
    51. datas       descriptor <0ffffh, 0h, 11h, atdw, 0>   
    52. datas_sel   = datas - gdt               ; 源数据段描述符的选择子  
    53. datad       descriptor <0ffffh, , , atdw, >         
    54. datad_sel   = datad - gdt               ; 目标数据段描述符的选择子  
    55. gdtlen      = $ - gdt             
    56.   
    57. vgdtr       pdesc <gdtlen - 1, >          ; 伪描述符  
    58.   
    59. bufferlen   = 256                   ; 缓冲区字节长度  
    60. buffer      db bufferlen dup (0)            ; 缓冲区  
    61.   
    62. dseg ends  
    63.   
    64. ; 代码段  
    65. cseg segment use16  
    66.   
    67.         assume cs:cseg, ds:dseg  
    68.           
    69. start:  
    70.   
    71.         mov ax, dseg  
    72.         mov ds, ax  
    73.           
    74.         ; 准备要加载到gdtr的伪描述符  
    75.         mov bx, 16  
    76.         mul bx  
    77.         add ax, offset gdt                        
    78.         adc dx, 0  
    79.         mov word ptr vgdtr.base, ax               
    80.         mov word ptr vgdtr.base + 2, dx           
    81.           
    82.         ; 设置代码段描述符  
    83.         mov ax, cs  
    84.         mul bx                                    
    85.         mov code.basel, ax    
    86.         mov code.basem, dl  
    87.         mov code.baseh, dh  
    88.           
    89.         ; 设置目标数据段描述符  
    90.         mov ax, ds                                
    91.         mul bx  
    92.         add ax, offset buffer  
    93.         adc dx, 0  
    94.         mov datad.basel, ax  
    95.         mov datad.basem, dl  
    96.         mov datad.baseh, dh  
    97.           
    98.         ; 加载gdtr  
    99.         lgdt fword ptr vgdtr  
    100.           
    101.         cli   
    102.         call enablea20  
    103.           
    104.         ; 切换到保护方式  
    105.         xchg bx, bx  
    106.         mov eax, cr0  
    107.         or eax, 1  
    108.         mov cr0, eax  
    109.           
    110.         ; 清指令欲取队列,并真正进入保护方式  
    111.         jump <code_sel>, <offset virtual>  
    112.           
    113. virtual:  
    114.         mov ax, datas_sel  
    115.         mov ds, ax  
    116.         mov ax, datad_sel  
    117.         mov es, ax  
    118.         cld  
    119.         xor si, si  
    120.         xor di, di  
    121.         mov cx, bufferlen / 4  
    122.         repz movsd  
    123.           
    124.         ; 切换回实方式  
    125.         mov eax, cr0  
    126.         and eax, 0fffffffeh  
    127.         mov cr0, eax  
    128.           
    129.         ; 清指令预取队列,进入实方式  
    130.         jump <seg real>, <offset real>  
    131.           
    132. real:  
    133.         call disablea20  
    134.         sti  
    135.           
    136.         mov ax, dseg  
    137.         mov ds, ax  
    138.         mov si, offset buffer  
    139.         cld   
    140.         mov bp, bufferlen / 16  
    141.           
    142. nextline:  
    143.         mov cx, 16  
    144.           
    145. nextch:  
    146.         lodsb  
    147.         push ax  
    148.         shr al, 4  
    149.         call toascii  
    150.         xchg bx, bx  
    151.         echoch al  
    152.         xchg bx, bx  
    153.         pop ax  
    154.         call toascii  
    155.         echoch al  
    156.         echoch ' '  
    157.         loop nextch  
    158.         echoch 0dh  
    159.         echoch 0ah  
    160.         dec bp  
    161.         jnz nextline  
    162.           
    163.         mov ax, 4c00h  
    164.         int 21h  
    165.           
    166. toascii  proc  
    167.   
    168.         and al, 0fh  
    169.         add al, 30h  
    170.         cmp al, '9'  
    171.         jbe quit  
    172.         add al, 7  
    173.           
    174. quit:  
    175.         ret  
    176.           
    177. toascii endp  
    178.           
    179. enablea20 proc  
    180.   
    181.         push ax  
    182.         in al, 92h  
    183.         or al, 2  
    184.         out 92h, al  
    185.         pop ax  
    186.         ret  
    187.           
    188. enablea20 endp  
    189.   
    190. disablea20 proc  
    191.           
    192.         push ax  
    193.         in al, 92h  
    194.         and al, 0fdh  
    195.         out 92h, al  
    196.         pop ax  
    197.         ret  
    198.           
    199. disablea20 endp  
    200.   
    201. cseg ends  
    202.   
    203. end start                 


    我自己以前的疑问与我自己的答案:

    Q:为什么要设置GDTR?

    A:应为需要他来找到GDT

    Q:

    [cpp] view plain copy
     
    1. mul bx  

    什么意思?

    A:转换为物理地址,就是段值*16

    Q:

    [cpp] view plain copy
     
    1. jump <code_sel>, <offset virtual>  

    什么意思?

    A:这条指令是在转换到保护模式之前预取到指令队列的,如果不预取,转换到保护模式后系统会把cs中的值以为是选择子,但其实他是段值,就无法执行下一条指令,也就是jmp,所以要预取这条宏,然后执行时把cs设置为选择子,刷新预取指令队列,引用:

    “由此可见,执行这条jmp指令时CPU已经处于“保护方式”了(因为cr0中的PE已经被置成“保护方式”)。如果此条jmp指令如果不是在“实方式”下被预取到指令队列中,就无法执行到它,因为“cr0中的PE被置成保护方式”之后,cs中的值仍为实方式的段值,此时将当前ip加1,然后用cs:ip去取下面的这条jmp指令显然会失败,因为此时处于“保护方式”下的cpu会把cs中的内容理解为“选择子”,所以自然无法取得“紧接着的”jmp指令。”

    Q:

    [cpp] view plain copy
     
    1. shr al, 4  

    啥意思?

    A:是要显示其高4位,然后下面pop后显示低四位

    Q:

    [plain] view plain copy
     
    1. mov ax, datas_sel  


    什么意思?

    A:datas_sel为选择子,值为8,换为二进制是1000,低三位分别是0位、1位为RPL,2位为TI,3~15位是描述符表索引,也即第一个描述符

    >>>>>>>>>>>>>>>琐碎记忆>>>>>>>>>>>>>>>>>

    保护方式下通过选择子的3~15位来定位在描述符表中的描述符,然后获得基地址、界限、属性

    http://blog.csdn.net/programmingring/article/details/7385140

  • 相关阅读:
    互联网+总决赛有感
    PyQt QListWidget修改列表项item的行高
    virtualenv 安装不同版本的虚拟环境的办法
    OpenDayLight Helium实验三 OpenDaylight二层转发机制实验
    OpenDayLight Helium实验一 OpenDaylight的C/S模式实验
    数据结构上机 经典进出栈问题
    【转载】解决telnet无法连接 Connection refused
    【Python初学者】准备
    OpenDayLight Helium安装
    Mininet实验 测量路径损耗率
  • 原文地址:https://www.cnblogs.com/findumars/p/8299252.html
Copyright © 2011-2022 走看看