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

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

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

Q:为什么要设置GDTR?

A:应为需要他来找到GDT

Q:

  1. mul bx

什么意思?

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

Q:

  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:

  1. shr al, 4

啥意思?

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

Q:

  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

《80x86汇编语言程序设计》保护模式第一个例题的更多相关文章

  1. 《80x86汇编语言程序设计教程》第二章课后题答案

    2.5 习题 2.1 数据寄存器 1. 八个通用寄存器除了各自规定的专门用途外,它们均可以用于传送和暂存数据,可以保存算术逻辑运算中的各种操作数和运算结果. 2.1 AX和Al寄存器又称为累加器(ac ...

  2. 《汇编语言程序设计》——仿windows计算器

    <汇编语言程序设计> ——计算器程序设计 目录 一.     题目与目标 1.      题目 2.      学习目的 二.     分析与设计 1.      系统分析 2.      ...

  3. Intel汇编语言程序设计学习-第一章 基本概念

    第一章基本概念 1.1  简单介绍 本书着重讲述MS-Windows平台上IA-32(Intel Architecture 32bit,英特尔32位体系架构)兼容微处理器的汇编语言程序设计,可以使用I ...

  4. ASM:《X86汇编语言-从实模式到保护模式》第15章:任务切换

    15章其实应该是和14章相辅相成的(感觉应该是作者觉得14章内容太多了然后切出来了一点).任务切换和14章的某些概念是分不开的. ★PART1:任务门与任务切换的方法 1. 任务管理程序 14章的时候 ...

  5. 存储器的保护(三)——《x86汇编语言:从实模式到保护模式》读书笔记20

    存储器的保护(三) 修改本章代码清单,使之可以检测1MB以上的内存空间(从地址0x0010_0000开始,不考虑高速缓存的影响).要求:对内存的读写按双字的长度进行,并在检测的同时显示已检测的内存数量 ...

  6. 存储器的保护(一)——《x86汇编语言:从实模式到保护模式》读书笔记18

    本文是原书第12章的学习笔记. 说句题外话,这篇博文是补写的,因为让我误删了,可恶的是CSDN的回收站里找不到! 好吧,那就再写一遍,我有坚强的意志.司马迁曰:“文王拘而演<周易>:仲尼厄 ...

  7. 进入保护模式(二)——《x86汇编语言:从实模式到保护模式》读书笔记14

    首先来段题外话:之前我发现我贴出的代码都没有行号,给讲解带来不便.所以从现在起,我要给代码加上行号.我写博客用的这个插入代码的插件,确实不支持自动插入行号.我真的没有找到什么好方法,无奈之下,只能按照 ...

  8. 进入保护模式(一)——《x86汇编语言:从实模式到保护模式》读书笔记12

    之前已经做了一些理论上的铺垫,这次我们就可以看代码了. 一.代码清单 ;代码清单11-1 ;文件名:c11_mbr.asm ;文件说明:硬盘主引导扇区代码 ;创建日期:2011-5-16 19:54 ...

  9. 《linux 内核全然剖析》 chapter 4 80x86 保护模式极其编程

    80x86 保护模式极其编程       首先我不得不说.看这章真的非常纠结...看了半天.不知道这个东西能干嘛.我感觉唯一有点用的就是对于内存映射的理解...我假设不在底层给80x86写汇编的话.我 ...

随机推荐

  1. 【CS Round #48 (Div. 2 only)】8 Divisible

    [链接]h在这里写链接 [题意] 给你一个长度为n的数字(n<=1000) 然后让你任意组合这个数字. 使得这个数字能被8整除. (不能出现前导0) [题解] 只要后三位能被8整除就可以了. 则 ...

  2. SVGALib

    SVGALib是一套运行于Linux及FreeBSD下的开放源代码低阶绘图函式库,它允许程式设计人员变更视讯模式及全屏幕图像,许多热门的电脑游戏如Quake及Doom都源自此技术. 范例 编辑 #in ...

  3. Mac 环境下svn服务器的配置

    Mac 环境下svn服务器的配置 本文目录 • 一.创建代码仓库,用来存储客户端所上传的代码 • 二.配置svn的用户权限 • 三.使用svn客户端功能 在Windows环境中,我们一般使用Torto ...

  4. Spring 定时器 No qualifying bean of type [org.springframework.scheduling.TaskScheduler] is defined(转)

    最近项目里面,用了spring的定时任务,一直以来,项目运行的不错.定时器也能正常使用.可是,今天启动项目测试的时候,盯着启动Log看了一阵子,突然间发现,启动的Log中居然有一个异常,虽然一闪而过, ...

  5. PHP Filesystem 函数(文件系统函数)(每日一课的内容可以从php参考手册上面来)

    PHP Filesystem 函数(文件系统函数)(每日一课的内容可以从php参考手册上面来) 一.总结 1.文件路径中的正反斜杠:当在 Unix 平台上规定路径时,正斜杠 (/) 用作目录分隔符.而 ...

  6. ZOJ 1914 Arctic Network (POJ 2349 UVA 10369) MST

    ZOJhttp://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=1914 POJhttp://poj.org/problem?id=23 ...

  7. [Redis专辑][1]ubuntu12.04下安装php-redis的方法和步骤

    首次公布路径:phpredis的安装 非常久非常久没有写博文了,好多博文都没有整理完成,今天才抽时间整理完这一篇博文,希望能对大家有一定的帮助 首先对redis做个简单的介绍: Redis 是全然开源 ...

  8. Java中的日期操作 分类: B1_JAVA 2015-02-16 17:55 6014人阅读 评论(0) 收藏

    在日志中常用的记录当前时间及程序运行时长的方法: public void inject(Path urlDir) throws Exception { SimpleDateFormat sdf = n ...

  9. Kinect for Xbox one(v2) + Ubuntu 14.04 +ROS 安装

    相比于kinect for xbox 360(v1)通过结构光来获取深度,Kinect for Xbox one(v2) 采用time flight技术,极大改善了深度图像的性能. kinect fo ...

  10. BZOJ 1588 HNOI2002 营业额统计 裸Treap

    题目大意:...题目描写叙述不全看这里好了 给定一个序列 对于每一个元素我们定义该数的最小波动值为这个数与前面全部数的差中的最小值(第一个数的最小波动值为第一个数本身) 求最小波动值之和 找近期的数仅 ...