80x86(杨季文)一书,实例1。

sum_1 2002-11-06 12:17:36

.386P
INCLUDE 386SCD.ASM

ECHOCH MACRO ascii
MOV AH,2
MOV DL,ascii
INT 21H
ENDM


DSEG SEGMENT USE16
GDT LABEL BYTE
DUMMY DESCRIPTOR<>

CODE DESCRIPTOR<0FFFFH,,,ATCE,>
CODE_SEL=CODE-GDT

;DATAS DESCRIPTOR<0FFFFH,0H,11H,ATDW,0>
;DATAS_SEL=DATAS-GDT

;DATAD DESCRIPTOR<0FFFFH,,,ATDW,>
;DATAD_SEL=DATAD-GDT

GDTLEN=$-GDT
VGDTR PDESC<GDTLEN-1,>

;BUFFERLEN=256
;BUFFER DB BUFFERLEN DUP(0)
DSEG ENDS



CSEG SEGMENT USE16
ASSUME CS:CSEG,DS:DSEG
START:
MOV AX,DSEG
MOV DS,AX
MOV BX,16
MUL BX
ADD AX,OFFSET GDT
ADC DX,0
MOV WORD PTR VGDTR.BASE,AX
MOV WORD PTR VGDTR.BASE+2,DX

MOV AX,CS
MUL BX
MOV CODE.BASEL,AX
MOV CODE.BASEM,DL
MOV CODE.BASEH,DH

;MOV AX,DS
;MUL BX
;ADD AX,OFFSET BUFFER
;ADC DX,0
;MOV DATAD.BASEL,AX
;MOV DATAD.BASEM,DL
;MOV DATAD.BASEH,DH
LGDT VGDTR
CLI
CALL ENABLEA20
MOV EAX,CR0
OR EAX,1
MOV CR0,EAX
JUMP16 <CODE_SEL>,<OFFSET VIRTUAL>
VIRTUAL:
;MOV AX,DATAS_SEL
;MOV DS,AX
;MOV AX,DATAD_SEL
;MOV ES,AX
;CLD
;XOR SI,SI
;XOR DI,DI
;MOV CX,BUFFERLEN/4
;REPZ MOVSD
MOV EAX,CR0
MOV EAX,0FFFFFFFEH
MOV CR0,EAX
JUMP16<SEG REAL>,<OFFSET REAL>
REAL:
CALL DISABLEA20
STI
;MOV AX,DSEG
;MOV DS,AX

MOV AH,4C
INT 21H


ENABLEA20 PROC
PUSH AX
IN AL,92H
OR AL,2
OUT 92H,AL
POP AX
RET

ENABLEA20 ENDP

DISABLEA20 PROC
PUSH AX
IN AL,92H
AND AL,0FDH
OUT 92H,AL
POP AX
RET
DISABLEA20 ENDP




TOASCII PROC
AND AL,0FH
ADD AL,90H
DAA
ADC AL,40H
DAA
RET
TOASCII ENDP

CSEG ENDS
END START


功能是从实模式进入保护模式,什么也不做再回到实模式,可是每次执行到MOV CR0,EAX时机器总是
重启(CR0:PG=0,PE=1,ET=1)GDT的装载经调试是正确的,不知是哪里不对。




;文件名:386SCD.ASM
;内 容:符号常量等的定义(用于保护模式)
;详细注释见80x86汇编(杨季文)一书,p403页

;..........................
;存储段和系统段描述符
DESCRIPTOR STRUC
LIMITL DW 0
BASEL DW 0
BASEM DB 0
ATTRIBUTES DW 0
BASEH DB 0

DESCRIPTOR ENDS
;.........................
;门描述符
GATE STRUC
OFFSETL DW 0
SELECTOR DW 0
DCOUNT DB 0
GTYPE DB 0
OFFSETH DW 0
GATE ENDS
;.........................
;伪描述符
PDESC STRUC
LIMIT DW 0
BASE DD 0
PDESC ENDS
;.........................

;TSS任务状态段内容
TASKSS STRUC
TRLINK DW ?,0
TRESP0 DD ?
TRSS0 DW ?,0
TRESP1 DD ?
TRSS1 DW ?,0
TRESP2 DD ?
TRSS2 DW ?,0
TRCR3 DD ?
TREIP DD ?
TREFLAG DW ?,?
TREAX DD ?
TRECX DD ?
TREDX DD ?
TREBX DD ?
TRESP DD ?
TREBP DD ?
TRESI DD ?
TREDI DD ?
TRES DW ?,0
TRCS DW ?,0
TRSS DW ?,0
TRDS DW ?,0
TRFS DW ?,0
TRGS DW ?,0
TRLDT DW ?,0
TRFLAG DW 0
TRIOMAP DW $+2
TASKSS ENDS
;..........................
;存储段描述符类型值说明
ATDR =90H
ATDW =92H
ATDWA =93H
ATCE =98H
ATCER =9AH
ATCCO =9CH
ATCCOR =9EH
;系统段描述符和门描述符类型值说明
ATLDT =82H
ATTASKGAT =85H
AT386TSS =89H
AT386CGAT =8CH
AT386IGAT =8EH
AT386TGAT =8FH
;DPL和RPL值说明
;..........................

DPL1 =20H
DPL2 =40H
DPL3 =60H
RPL1 =01H
RPL2 =02H
RPL3 =03H
IOPL1 =1000H
IOPL2 =2000H
IOPL3 =3000H
;.............................



;其它常量说明
D32 =4000H
TIL =04H
VMFL =0002H
IFL =0200H
;.............................

;段间转移及段间调用宏
JUMP32 MACRO selector,offsetv
DB 0EAH
DW offsetv
DW 0
DW selector
ENDM
CALL32 MACRO selector,offsetv
DB 09AH
DW offsetv
DW 0
DW selector
ENDM

JUMP16 MACRO selector,offsetv
DB 0EAH
DW offsetv
DW selector
ENDM
CALL16 MACRO selector,offsetv
DB 9AH
DW offsetv
DW selector
ENDM

;................................



...全文
37 27 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
27 条回复
切换为时间正序
请发表友善的回复…
发表回复
RichardStevens 2002-12-26
  • 打赏
  • 举报
回复
关注!
sum_1 2002-12-26
  • 打赏
  • 举报
回复
我在WIN98,用SoftIce对VXD的服务调用进行跟踪时也发生同样的情况?
970361 2002-12-18
  • 打赏
  • 举报
回复
关注
xxxxy 2002-12-17
  • 打赏
  • 举报
回复
就是说,进入保护模式之后,不能用调试软件来调试,你让程序直接运行试试,如果正常退出说明没问题,否则就检查程序,可能输入错了.
sum_1 2002-12-17
  • 打赏
  • 举报
回复
还没说清是怎么回事哪,
giantzz 2002-12-16
  • 打赏
  • 举报
回复
结贴吧
giantzz 2002-12-15
  • 打赏
  • 举报
回复
to sum_1(正在喝水):
怎么又扯到流水线技术,你要知道流水线技术中一个时钟内执行两条指令是有条件的,即两条指令的执行必须无依赖性.
atm2001 2002-12-15
  • 打赏
  • 举报
回复
MOV CR0,EAX执行后就已经到保护模式啦,寻址方式已改变,
????
mov cr0,eax只是设置了实模式到保护模式的寻址开始,此时还在实模式下

需要jump16只不过是跳到保护模式代码而已。jump16本身也是一个宏,它其实是0eah(jump),selector,offset。显然他是一个保护模式的跳转。
这个说法比较好理解。
djygrdzh 2002-11-24
  • 打赏
  • 举报
回复
我从书上知道 MOV CR0,EAX执行后还是在实模式下,只有执行了JUMP16后(清指令预取队列,置CS),才进入了保护模式.
MOV CR0,EAX执行后就已经到保护模式啦,寻址方式已改变,需要jump16只不过是跳到保护模式代码而已。jump16本身也是一个宏,它其实是0eah(jump),selector,offset。显然他是一个保护模式的跳转。
sum_1 2002-11-24
  • 打赏
  • 举报
回复
我从书上知道 MOV CR0,EAX执行后还是在实模式下,只有执行了JUMP16后(清指令预取队列,置CS),才进入了保护模式.
你的意思是不是CV是单步调试,而实际情况是在一个时钟周期内同时完成以上二条指令(流水线技术).
如我说的不对请在详细解释一下.

giantzz 2002-11-23
  • 打赏
  • 举报
回复
to Asimov(阿西莫夫):
这个例子没问题,是你理解的有问题
to sum_1(正在喝水):
这个程序本身当然符合规定(如果你在运行时出现问题,请核对代码),我是指你想把CV也带到保护模式时不符合规定,因为MOV CR0,EAX后的指令还在实模式下(指令队列中),不要以为该指令后就是JUMP16 <CODE_SEL>,<OFFSET VIRTUAL>,这是运行时的情况;调试时CV等调试工具还要用单步中断来显示一条指令执行后的各寄存器的情况.而这单步中断... 你明白了吗
Asimov 2002-11-22
  • 打赏
  • 举报
回复
我觉得他给出的例子是不是有问题?比如adc dx,0 之前的dx根本没有清零,而且后面再次adc dx,0还是没有清零。
btw他书上的例子有下载的吗?总不至于要手工输入吧
sum_1 2002-11-22
  • 打赏
  • 举报
回复
那怎样才符合规定哪?


MOV EAX,CR0
OR EAX,1
MOV CR0,EAX
giantzz 2002-11-21
  • 打赏
  • 举报
回复
异常是指不符合保护模式的规定,重启正常
sum_1 2002-11-21
  • 打赏
  • 举报
回复
masm 6.11 的CV.EXE
giantzz 2002-11-19
  • 打赏
  • 举报
回复
用什么调试的
sum_1 2002-11-19
  • 打赏
  • 举报
回复
up
sum_1 2002-11-16
  • 打赏
  • 举报
回复
真是出奇了,我按照书上的做了。(开机,F8,进入DOS,DOS未安装任何驱动。编译用MASM LINK 和TASM,TLINK 都试过了,我想本例中没有32位段 TLINK /3就用不着了)就是在MOV CR0 EAX(EAX以置好)这步时系统重启(冷启动)


giantzz 2002-11-13
  • 打赏
  • 举报
回复
你把书翻到第361页,第二段,按上面说的做.
sum_1 2002-11-13
  • 打赏
  • 举报
回复
up
加载更多回复(7)
本书分为三部分。第一部分是基础部分,以8086/8088为背景,以DOS和PC兼容机为软硬件平台,以MASM和TASM为汇编器,介绍汇编语言的有关概念,讲解汇编语言程序设计技术。第二部分是提高部分,以80386为背景,以新一代微处理器Pentium为目标,细致和通俗地介绍了保护方式下的有关概念,系统和详细地讲解了保护方式下的编程技术,真实和生动地展示了保护方式下的编程细节。第三部分是上机实验指导。 本书的第一部分适合初学者,可作为学习汇编语言程序设计的教材。本书的第二部分适合已基本掌握8086/8088汇编语言的程序员,可作为学习保护方式编程技术的教材或参考书,也可作为其他人员了解高档微处理器和保护方式编程技术的参考书,还可作为程序员透彻地了解Windows程序设计技术的参考书。 第一部分 基础部分 第1章 绪论 1.1 汇编语言概述 1.1.1 汇编语言 1.1.2 汇编语言的特点 1.1.3 恰当地使用汇编语言 1.2 数据的表示和类型 1.2.1 数值数据的表示 1.2.2 非数值数据的表示 1.2.3 基本数据类型 1.3 Intel系列CPU简介 1.3.1 8位微处理器 1.3.2 16位微处理器 1.3.3 32位微处理器 1.3.4 Pentium和Pentium Pro 1.4 习题 第2章 8086/8088寻址方式和指令系统 2.1 8086/8088寄存器组 2.1.1 8086/8088 CPU寄存器组 2.1.2 标志寄存器 2.2 存储器分段和地址的形成 2.2.1 存储单元的地址和内容 2.2.2 存储器的分段 2.2.3 物理地址的形成 2.2.4 段寄存器的引用 2.3 8086/8088的寻址方式 2.3.1 立即寻址方式 2.3.2 寄存器寻址方式 2.3.3 直接寻址方式 2.3.4 寄存器间接寻址方式 2.3.5 寄存器相对寻址方式 2.3.6 基址加变址寻址方式 2.3.7 相对基址加变址寻址方式 2.4 8086/8088指令系统 2.4.1 指令集说明 2.4.2 数据传送指令 2.4.3 堆栈操作指令 2.4.4 标志操作指令 2.4.5 加减运算指令 2.4.6 乘除运算指令 2.4.7 逻辑运算和移位指令 2.4.8 转移指令 2.5 习题 第3章 汇编语言及其程序设计初步 3.1 汇编语言的语句 3.1.1 语句的种类和格式 3.1.2 数值表达式 3.1.3 地址表达式 3.2 变量和标号 3.2.1 数据定义语句 3.2.2 变量和标号 3.3 常用伪指令语句和源程序组织 3.3.1 符号定义语句 3.3.2 段定义语句 3.3.3 汇编语言源程序的组织 3.4 顺序程序设计 3.4.1 顺序程序举例 3.4.2 简单查表法代码转换 3.4.3 查表法求函数值 3.5 分支程序设计 3.5.1 分支程序举例 3.5.2 利用地址表实现多向分支 3.6 循环程序设计 3.6.1 循环程序举例 3.6.2 多重循环程序举例 3.7 习题 第4章 子程序设计和DOS功能调用 4.1 子程序设计 4.1.1 过程调用和返回指令 4.1.2 过程定义语句 4.1.3 子程序举例 4.1.4 子程序说明信息 4.1.5 寄存器的保护与恢复 4.2 主程序与子程序间的参数传递 4.2.1 利用寄存器传递参数 4.2.2 利用约定存储单元传递参数 4.2.3 利用堆栈传递参数 4.2.4 利用CALL后续区传递参数 4.3 DOS功能调用及应用 4.3.1 DOS功能调用概述 4.3.2 基本I/O功能调用 4.3.3 应用举例 4.4 磁盘文件管理及应用 4.4.1 DOS磁盘文件管理功能调用 4.4.2 应用举例 4.5 子程序的递归和重入 4.5.1 递归子程序 4.5.2 可重入子程序 4.6 习题 第5章 输入输出与中断 5.1输 入和输出的基本概念 5.1.1 I/O端口地址和I/O指令 5.1.2 数据传送方式 5.1.3 存取RT/CMOS RAM 5.2 查询方式传送数据 5.2.1 查询传送方式 5.2.2 读实时钟 5.2.3 查询方式打印输出 5.3 中断 5.3.1 中断和中断传送方式 5.3.2 中断向量表 5.3.3 中断响应过程 5.3.4 外部中断 5.3.5 内部中断 5.3.6 中断优先级和中断嵌套 5.3.7 中断处理程序的设计 5.4 基本输入输出系统BIOS 5.4.1 基本输入输出系统BIOS概述 5.4.2 键盘输入 5.4.3 显示输出 5.4.4 打印输出 5.5 软中断处理程序举例 5.5.1 打印I/O程序 5.5.2 时钟显示程序 5.6 习题 第6章 简单应用程序的设计 6.1 字符串处理 6.1.1 字符串操作指令 6.1.2 重复前缀 6.1.3 字符串操作举例 6.2 十进制数算术运算调整指令及应用 6.2.1 组合BCD码的算术运算调整指令 6.2.2 未组合BCD码的算术运算调整指令 6.2.3 应用举例 6.3 DOS程序段前缀和特殊情况处理程序 6.3.1 DOS程序段前缀PSP 6.3.2 对Ctrl+C键和Ctrl+Break键的处理 6.4 TSR程序设计举例 6.4.1 驻留的时钟显示程序 6.4.2 热键激活的TSR程序 6.5 习题 第7章 高级汇编语言技术 7.1 结构和记录 7.1.1 结构 7.1.2 记录 7.2 宏 7.2.1 宏指令的定义和使用 7.2.2 宏指令的用途 7.2.3 宏指令中参数的使用 7.2.4 特殊的宏运算符 7.2.5 宏与子程序的区别 7.2.6 与宏有关的伪指令 7.2.7 宏定义的嵌套 7.3 重复汇编 7.3.1 伪指令REPT 7.3.2 伪指令IRP 7.3.3 伪指令IRPC 7.4 条件汇编 7.4.1 条件汇编伪指令 7.4.2 条件汇编与宏结合 7.5 源程序的结合 7.5.1 源程序的结合 7.5.2 宏库的使用 7.6 习题 第8章 模块化程序设计技术 8.1 段的完整定义 8.1.1 完整的段定义 8.1.2 关于堆栈段的说明 8.1.3 段组的说明和使用 8.2 段的简化定义 8.2.1 存储模型说明伪指令 8.2.2 简化的段定义伪指令 8.2.3 存储模型说明伪指令的隐含动作 8.3 模块间的通信 8.3.1 伪指令PUBLIC和伪指令EXTRN 8.3.2 模块间的转移 8.3.3 模块间的信息传递 8.4 子程序库 8.4.1 子程序库 8.4.2 建立子程序库 8.4.3 使用举例 8.5 编写供Turbo C调用的函数 8.5.1 汇编格式的编译结果 8.5.2 汇编模块应该遵守的约定 8.5.3 参数传递和寄存器保护 8.5.4 举例 8.6 习题 第二部分 提高部分 第9章 80386程序设计基础 9.1 80386寄存器 9.1.1 通用寄存器 9.1.2 段寄存器 9.1.3 指令指针和标志寄存器 9.2 80386存储器寻址 9.2.1 存储器寻址基本概念 9.2.2 灵活的存储器寻址方式 9.2.3 支持各种数据结构 9.3 80386指令集 9.3.1 数据传送指令 9.3.2 算术运算指令 9.3.3 逻辑运算和移位指令 9.3.4 控制转移指令 9.3.5 串操作指令 9.3.6 高级语言支持指令 9.3.7 条件字节设置指令 9.3.8 位操作指令 9.3.9 处理器控制指令 9.4 实方式下的程序设计 9.4.1 说明 9.4.2 实例 9.5 习题 第10章 保护方式下的80386及其编程 10.1 保护方式简述 10.1.1 存储管理机制 10.1.2 保护机制 10.2 分段管理机制 10.2.1 段定义和虚拟地址到线性地址转换 10.2.2 存储段描述符 10 2.3 全局和局部描述符表 10.2.4 段选择子 10.2.5 段描述符高速缓冲寄存器 10.3 80386控制寄存器和系统地址寄存器 10.3.1 控制寄存器 10 3.2 系统地址寄存器 10.4 实方式与保护方式切换实例 10.4.1 演示实方式和保护方式切换的实例实例一) 10.4.2 演示32位代码段和16位代码段切换的实例实例二) 10.5 任务状态段和控制门 10.5.1 系统段描述符 10.5.2 门描述符 10.5.3 任务状态段 10.6 控制转移 10.6.1 任务内无特权级变换的转移 10.6.2 演示任务内无特权级变换转移的实例实例三) 10.6.3 任务内不同特权级的变换 10.6.4 演示任务内特权级变换的实例实例四) 10.6.5 任务切换 10.6.6 演示任务切换的实例实例五) 10.7 80386的中断和异常 10.7.1 80386的中断和异常 10.7.2 异常类型 10.7.3 中断和异常的转移方法 10.7.4 演示中断处理的实例实例六) 10.7.5 演示异常处理的实例实例七) 10.7.6 各种转移途径小结 10.8 操作系统类指令 10.8.1 实方式和任何特权级下可执行的指令 10.8.2 实方式及特权级0下可执行的指令 10 8.3 只能在保护方式下执行的指令 10.8.4 显示关键寄存器内容的实例实例八) 10.8.5 特权指令 10.9 输入/输出保护 10.9.1 输入/输出保护 10.9.2 重要标志保护 10.9.3 演示输入/输出保护的实例实例九) 10.10 分页管理机制 10.10.1 存储器分页管理机制 10.10.2 线性地址到物理地址的转换 10.10.3 页级保护和虚拟存储器支持 10.10.4 页异常 10.10.5 演示分页机制的实例实例十) 10.11 虚拟8086方式 10.11.1 V86方式 10.11.2 进入和离开V86方式 10.11.3 演示进入和离开V86方式的实例实例十一) 10.11.4 V86方式下的敏感指令 10.12 习题 第11章 80486及Pentium程序设计基础 11.1 80486程序设计基础 11.1.1 寄存器 11.1.2 指令系统 11.1.3 片上超高速缓存 11.2 80486对调试的支持 11 2.1 调试寄存器 11.2.2 演示调试故障/陷阶的实例 11.3 Pentium程序设计基础 11.3.1 寄存器 11.3.2 指令系统 11.3.3 处理器的识别 11.3.4 片上超高速缓存 11.4 基于Pentium的程序优化技术 11.4.1 流水线优化技术 11.4.2 分支优化技术 11.4.3 超高速缓存代化技术 11.5 习题 第三部分 上机实验指导 第12章 实验指导 12.1 实验的一般步骤 12.2 汇编器和连接器的使用 12.2.1 MASM的使用 12.2.2 LINK的使用 12.2.3 TASM的使用 12.2.4 TLINK的使用 12.3 调试器DEBUG的使用 12.3.1 启动和退出DEBUG 12.3.2 命令一览 12.3.3 利用DEBUG调试程序 12.4 Turbo Debugger的使用 12.4.1 启动和退出TD 12.4.2 利用TD调试汇编程序 参考文献 附录 Pentium指令与标志参考表

21,497

社区成员

发帖
与我相关
我的任务
社区描述
汇编语言(Assembly Language)是任何一种用于电子计算机、微处理器、微控制器或其他可编程器件的低级语言,亦称为符号语言。
社区管理员
  • 汇编语言
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧