高手,小弟求救!!!
时间:2010-12-13
来源:互联网
这是杨季文书中的代码,小弟有个问题不明白,为什么用masm5.0编译、连接生成abc.exe文件,
在用debug调试时遇到LGDT FWORD PTR VGDTR,便自动退出?我在网上搜了,说是lgdt是特权指令,
难道这段代码只是实模式与保护模式的切换,不能执行吗???
;16位偏移的段间直接转移指令的宏定义
JUMP MACRO selector,offsetv
DB 0EAH ;操作码
DW offsetv ;16位偏移
DW selector ;段值或者选择子
ENDM
;字符显示宏指令的定义
ECHOCH MACRO ascii
MOV AH,2
MOV DL,ascii
INT 21H
ENDM
;存储段描述符结构类型的定义
DESCRIPTOR STRUC
LIMITL DW 0
BASEL DW 0
BASEM DB 0
ATTRIBUTES DW 0
BASEH DB 0
DESCRIPTOR ENDS
;为描述符结构类型的定义
PDESC STRUC
LIMIT DW 0
BASE DD 0
PDESC ENDS
;常量定义
ATDW = 92H ;存在的可读写数据段属性值
ATCE = 98H ;存在的只执行代码段属性值
.386P
DSEG SEGMENT USE16
GDT LABEL BYTE ;全局描述符表GDT
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
;准备要加载到GDTR的伪描述符
MOV BX,16
MUL BX ;计算并设置GDT基地址 ;
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
;加载GDTR
LGDT FWORD PTR VGDTR ;书中为QWORD,FWORD-6字节, QWORD-8字节, TBYTE-10字节
CLI ;表示将处理器标志寄存器的中断标志位清0,不允许中断
CALL EA20 ;打开地址线A20
;切换到保护方式
MOV EAX,CR0
OR EAX,1
MOV CR0,EAX
;清指令预取队列,并真正进入保护方式
JUMP <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 ;设置4字节为单位的缓冲区长度
REPZ MOVSD ;传递
;切换回实方式
MOV EAX,CR0
AND EAX,0FFFFFFFEH
MOV CR0,EAX
;请指令预取队列,进入实方式
JUMP <SEG REAL>,<OFFSET REAL>
REAL: ;现在又回到实方式
CALL DA20 ;关闭地址线A20
STI ;开中断
MOV AX,DSEG ;重置数据寄存器
MOV DS,AX
MOV SI,OFFSET BUFFER
CLD ;显示缓冲区内容
MOV BP,BUFFERLEN/16
NEXTLINE:
MOV CX,16
NEXTCH:
LODSB
PUSH AX
SHR AL,4
CALL TOASCII
ECHOCH AL
POP AX
CALL TOASCII
ECHOCH AL
ECHOCH ' '
LOOP NEXTCH
ECHOCH 0DH
ECHOCH 0AH
DEC BP
JNZ NEXTLINE
MOV AX,4C00H
INT 21H
TOASCII PROC
and al,0fh
add al,90h
daa
add al,40h
daa
RET
TOASCII ENDP
EA20 PROC
PUSH AX
IN AL,92H
OR AL,2
OUT 92H,AL
POP AX
RET
EA20 ENDP
DA20 PROC
PUSH AX
IN AL,92H
AND AL,0FDH
OUT 92H,AL
POP AX
RET
DA20 ENDP
CSEG ENDS
END START
在用debug调试时遇到LGDT FWORD PTR VGDTR,便自动退出?我在网上搜了,说是lgdt是特权指令,
难道这段代码只是实模式与保护模式的切换,不能执行吗???
;16位偏移的段间直接转移指令的宏定义
JUMP MACRO selector,offsetv
DB 0EAH ;操作码
DW offsetv ;16位偏移
DW selector ;段值或者选择子
ENDM
;字符显示宏指令的定义
ECHOCH MACRO ascii
MOV AH,2
MOV DL,ascii
INT 21H
ENDM
;存储段描述符结构类型的定义
DESCRIPTOR STRUC
LIMITL DW 0
BASEL DW 0
BASEM DB 0
ATTRIBUTES DW 0
BASEH DB 0
DESCRIPTOR ENDS
;为描述符结构类型的定义
PDESC STRUC
LIMIT DW 0
BASE DD 0
PDESC ENDS
;常量定义
ATDW = 92H ;存在的可读写数据段属性值
ATCE = 98H ;存在的只执行代码段属性值
.386P
DSEG SEGMENT USE16
GDT LABEL BYTE ;全局描述符表GDT
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
;准备要加载到GDTR的伪描述符
MOV BX,16
MUL BX ;计算并设置GDT基地址 ;
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
;加载GDTR
LGDT FWORD PTR VGDTR ;书中为QWORD,FWORD-6字节, QWORD-8字节, TBYTE-10字节
CLI ;表示将处理器标志寄存器的中断标志位清0,不允许中断
CALL EA20 ;打开地址线A20
;切换到保护方式
MOV EAX,CR0
OR EAX,1
MOV CR0,EAX
;清指令预取队列,并真正进入保护方式
JUMP <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 ;设置4字节为单位的缓冲区长度
REPZ MOVSD ;传递
;切换回实方式
MOV EAX,CR0
AND EAX,0FFFFFFFEH
MOV CR0,EAX
;请指令预取队列,进入实方式
JUMP <SEG REAL>,<OFFSET REAL>
REAL: ;现在又回到实方式
CALL DA20 ;关闭地址线A20
STI ;开中断
MOV AX,DSEG ;重置数据寄存器
MOV DS,AX
MOV SI,OFFSET BUFFER
CLD ;显示缓冲区内容
MOV BP,BUFFERLEN/16
NEXTLINE:
MOV CX,16
NEXTCH:
LODSB
PUSH AX
SHR AL,4
CALL TOASCII
ECHOCH AL
POP AX
CALL TOASCII
ECHOCH AL
ECHOCH ' '
LOOP NEXTCH
ECHOCH 0DH
ECHOCH 0AH
DEC BP
JNZ NEXTLINE
MOV AX,4C00H
INT 21H
TOASCII PROC
and al,0fh
add al,90h
daa
add al,40h
daa
RET
TOASCII ENDP
EA20 PROC
PUSH AX
IN AL,92H
OR AL,2
OUT 92H,AL
POP AX
RET
EA20 ENDP
DA20 PROC
PUSH AX
IN AL,92H
AND AL,0FDH
OUT 92H,AL
POP AX
RET
DA20 ENDP
CSEG ENDS
END START
作者: sungodll 发布时间: 2010-12-13
这段代码只能在实模式下运行。
作者: masmaster 发布时间: 2010-12-13
也就是说必须在像DOS这样的环境中吗?
作者: sungodll 发布时间: 2010-12-13
引用 2 楼 sungodll 的回复:
也就是说必须在像DOS这样的环境中吗?
也就是说必须在像DOS这样的环境中吗?
必须是dos环境, 或者,在虚拟机里也也可以。
作者: masmaster 发布时间: 2010-12-13
引用 3 楼 masmaster 的回复:
引用 2 楼 sungodll 的回复:
也就是说必须在像DOS这样的环境中吗?
必须是dos环境, 或者,在虚拟机里也也可以。
引用 2 楼 sungodll 的回复:
也就是说必须在像DOS这样的环境中吗?
必须是dos环境, 或者,在虚拟机里也也可以。
膜拜
作者: znxllyuan 发布时间: 2010-12-13
相关阅读 更多
热门阅读
-
office 2019专业增强版最新2021版激活秘钥/序列号/激活码推荐 附激活工具
阅读:74
-
如何安装mysql8.0
阅读:31
-
Word快速设置标题样式步骤详解
阅读:28
-
20+道必知必会的Vue面试题(附答案解析)
阅读:37
-
HTML如何制作表单
阅读:22
-
百词斩可以改天数吗?当然可以,4个步骤轻松修改天数!
阅读:31
-
ET文件格式和XLS格式文件之间如何转化?
阅读:24
-
react和vue的区别及优缺点是什么
阅读:121
-
支付宝人脸识别如何关闭?
阅读:21
-
腾讯微云怎么修改照片或视频备份路径?
阅读:28