ml T10-1.asm 编译出错
错误信息:T10-1.ASM <105> :error A2068:instruction prefix not allowed
这个“REPZ”前缀怎么会有问题呢?怎么会没有得到承认呢?
该行内容:REPZ MOVSD 在程序中已经标出
上面的编译器是使用的MASM6.11版本的。编译时在windows xp的cmd下编译的,
具体命令行是:ml T10-1.asm
T10-1.asm 程序源代码如下:
;******************************************************************
;《80x86汇编语言程序设计教程》实例1源程序
;功能:演示实模式和保护模式的切换
;******************************************************************
;16位偏移的段间直接转移指令的宏定义
JUMPMACRO selector,offsetv
DB0EAH;操作码
DWoffsetv;16位偏移
DW selector;段值或选择子
ENDM
;字符显示宏指令的定义
ECHOCHMACRO ascii
movah,2
movdl, ascii
int21h
ENDM
;存储段描述符结构类型的定义
DESCRIPTORSTRUC
LIMTLDW0;段界限(0~15)
BASELDW0;段基地址(0~15)
BASEMDB0;段基地址(16~23)
ATTRIBUTESDW0;段属性
BASEHDB0;段基地址(24~31)
DESCRIPTORENDS
;伪描述符结构类型定义
PDESCSTRUC
LIMITDW0;16位界限
BASEDD0;基地址
PDESCENDS
;常量定义
ATDW=92H;存在的可读写数据段属性值
ATCE=98H;存在的只执行代码段属性值
;
.386P
;------------------------------
DSEGSEGMENTUSE16;16位段
GDTLABEL BYTE;全局描述符表GDT
DUMMYDESCRIPTOR <> ;空描述符
CODEDESCRIPTOR <0FFFFH,,,ATCE,>
CODE_SEL=CODE - GDT;代码段描述符的选择子
DATASDESCRIPTOR <0FFFF,0H,11H,ATDW,0>
DATAS_SEL=DATAS - GDT;源数据段描述符的选择子
DATADDESCRIPTOR <0FFFFH,,,ATDW,>
DATAD_SEL=DATAD - GDT;目标数据段描述符的选择子
GDTLEN=$ - GDT
;
VGDTRPDESC <GDTLEN - 1,>
;
BUFFERLEN=256;缓冲区字节长度
BUFFERDBBUFFERLENDUP(0);目标数据段
DSEGENDS
STACKS SEGMENT
;此处输入堆栈段代码
STACKS ENDS
CSEGSEGMENTUSE16
ASSUME CS:CSEG,DS:DSEG
START:
MOVAX,DSEG
MOV DS,AX
;准备要加载到GDTR的伪描述符
MOV BX,16
MUL BX;EDX:AX=AX*16 计算并设置GDT基地址
ADD AX,OFFSETGDT
ADC DX,0
MOV WORD PTRVGDTR.BASE, AX
MOV WORD PTRVGDTR.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,OFFSETBUFFER
ADC DX,0
MOV DATAD.BASEL,AX
MOV DATAD.BASEM,DL
MOV DATAD.BASEH,DH
;加载GDTR
LGDTFWORDPTRVGDTR
;
CLI;关中断
CALLEA20
;切换到保护模式
MOV EAX,CR0
OREAX,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;SI由低到高方向
XOR SI,SI
XOR DI,DI
MOV CX,BUFFERLEN/4;设置按双字的传递次数
REPZ MOVSD ;$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$编译出错
;切换回实模式
MOV EAX,CR0
AND EAX,0FFFFFFFEH
MOV CR0,EAX
;清指令预取队列,进入实模式
JUMP <SEGREAL> , <OFFSETREAL>
;
REAL:
CALLDA20
STI;开中断
;
MOV AX,DSEG;重置数据段寄存器
MOV DX,AX
MOV SI,OFFSETBUFFER
CLD
MOV BP,BUFFERLEN/16;缓冲区的可以显示的行数,按每行显示16个字节计算
NEXTLINE:
MOV CX,16
NEXTCH:
LODSB;读入ES:DI的内容到AL中
PUSH AX ;实际上是为了压入AL
SHR AL,4;取高半字节
CALLTOASCII
ECHOCHAL
POP AX
CALLTOASCII
ECHOCHAL
ECHOCH ' '
LOOPNEXTCH
ECHOCH0DH
ECHOCH0AH
DECBP
JNZNEXTLINE
;
MOV AH,4CH
INT 21H
;把AL低4位的十六进制数转换成对应的ASCII码,保存在AL中
TOASCIIPROC
AND AL,0FH
ADD AL,90H
DAA
ADC AL,40H
DAA
RET
TOASCIIENDP
;打开地址线A20号
EA20PROC
PUSH AX
INAL,92H
ORAL,2
OUT92H,AL
POPAX
RET
EA20ENDP
;关闭地址线A20号
DA20PROC
PUSH AX
INAL,92H
ANDAL,0FDH
OUT92H,AL
POPAX
RET
DA20ENDP
CSEG ENDS
END START
[解决办法]
将 repz 改为 rep 了