寄存器使用实例
1.程序代码
例5.1 编写程序,显示80X86处理器中寄存器的内容。
;文件名:SHOWREG.ASM
;*****************************************************
.386P
DATA SEGMENT USE16
BEGIN LABEL BYTE
_IP DB 'IP = ',0DH,0AH
_CS DB 'CS = ',09H
_DS DB 'DS = ',0DH,0AH
_ES DB 'ES = ',09H
_FS DB 'FS = ',0DH,0AH
_GS DB 'GS = ',09H
_SS DB 'SS = ',0DH,0AH
_ESP DB 'ESP= ',09H
_EAX DB 'EAX= ',0DH,0AH
_EBX DB 'EBX= ',09H
_ECX DB 'ECX= ',0DH,0AH
_EDX DB 'EDX= ',09H
_ESI DB 'ESI= ',0DH,0AH
_EDI DB 'EDI= ',09H
_EBP DB 'EBP= ',0DH,0AH
_CR0 DB 'CR0= ',09H
_CR2 DB 'CR2= ',0DH,0AH
_CR3 DB 'CR3= ',09H
_DR0 DB 'DR0= ',0DH,0AH
_DR1 DB 'DR1= ',09H
_DR2 DB 'DR2= ',0DH,0AH
_DR3 DB 'DR3= ',09H
_DR6 DB 'DR6= ',0DH,0AH
_DR7 DB 'DR7= ',09H
_EFL DB 'EFL= ',0DH,0AH
_LDTR DB 'LDTR= ',0DH,0AH
_GDTR DB 'GDTR= ',0DH,0AH
_IDTR DB 'IDTR= ',09H
DB '$'
DIGIT DB '0123456789ABCDEF'
DATA ENDS
;
CODE SEGMENT USE16
ASSUME CS:CODE,DS:DATA,ES:DATA
START:
MOV AX,DATA
MOV DS,AX
MOV ES,AX
MOV AX,CS
LEA DI,[_CS 4]
CALL COMPUTE16
MOV AX,DS
LEA DI,[_DS 4]
CALL COMPUTE16
MOV AX,ES
LEA DI,[_ES 4]
CALL COMPUTE16
MOV AX,FS
LEA DI,[_FS 4]
CALL COMPUTE16
MOV AX,GS
LEA DI,[_GS 4]
CALL COMPUTE16
MOV AX,SS
LEA DI,[_SS 4]
CALL COMPUTE16
CALL NEXT
NEXT:
POP AX
LEA DI,[_IP 4]
CALL COMPUTE16
MOV EAX,EAX
LEA DI,[_EAX 4]
CALL COMPUTE32
MOV EAX,EBX
LEA DI,[_EBX 4]
CALL COMPUTE32
MOV EAX,ECX
LEA DI,[_ECX 4]
CALL COMPUTE32
MOV EAX,EDX
LEA DI,[_EDX 4]
CALL COMPUTE32
MOV EAX,ESI
LEA DI,[_ESI 4]
CALL COMPUTE32
MOV EAX,EDI
LEA DI,[_EDI 4]
CALL COMPUTE32
MOV EAX,EBP
LEA DI,[_EBP 4]
CALL COMPUTE32
MOV EAX,ESP
LEA DI,[_ESP 4]
CALL COMPUTE32
MOV EAX,CR0
LEA DI,[_CR0 4]
CALL COMPUTE32
MOV EAX,CR2
LEA DI,[_CR2 4]
CALL COMPUTE32
MOV EAX,CR3
LEA DI,[_CR3 4]
CALL COMPUTE32
MOV EAX,DR0
LEA DI,[_DR0 4]
CALL COMPUTE32
MOV EAX,DR1
LEA DI,[_DR1 4]
CALL COMPUTE32
MOV EAX,DR2
LEA DI,[_DR2 4]
CALL COMPUTE32
MOV EAX,DR3
LEA DI,[_DR3 4]
CALL COMPUTE32
MOV EAX,DR6
LEA DI,[_DR6 4]
CALL COMPUTE32
MOV EAX,DR7
LEA DI,[_DR7 4]
CALL COMPUTE32
PUSH FD
POP EAX
LEA DI,[_EFL 4]
CALL COMPUTE32
PUSH EAX
PUSH AX
SGDT [ESP]
POP AX
LEA DI,[_GDTR 5]
CALL COMPUTE16
ADD DI,4
POP EAX
CALL COMPUTE32
PUSH EAX
PUSH AX
SIDT [ESP]
POP AX
LEA DI,[_IDTR 5]
CALL COMPUTE16
ADD DI,4
POP EAX
CALL COMPUTE32
MOV AH,9
MOV DX,OFFSET BEGIN
INT 21H
MOV AH,4CH
INT 21H
COMPUTE32:
PUSH AD
MOV BX,OFFSET DIGIT
MOV CX,8
CLD
AGAIN:
ROL EAX,4
PUSH EAX
AND EAX,0FH
XLAT
STOSB
POP EAX
LOOP AGAIN
POPAD
RET
COMPUTE16:
PUSHAD
MOV BX,OFFSET DIGIT
MOV CX,4
CLD
AGAIN1:
ROL AX,4
PUSH AX
AND AX,0FH
XLAT
STOSB
POP AX
LOOP AGAIN1
POPAD
RET
CODE ENDS
END START
;*****************************************************
说明:
(1)程序中的“.386P”,是说明处理器类型的伪指令,告诉汇编程序“MASM”或“TASM”,使用处理器的类型。说明处理器类型的伪指令有:
.8086 ;只支持对8086指令的汇编
.186 ;支持对80186指令的汇编
.286 ;支持对80286非特权指令的汇编
.286C ;支持对80286非特权指令的汇编
.286P ;支持对80286所有指令的汇编
.386 ;支持对80386非特权指令的汇编
.386C ;支持对80386非特权指令的汇编
.386P ;支持对80386所有指令的汇编
(2)在定义段时,“DATA SEGMENT USE16”和“CODE SEGMENT USE16”中的USE16,是指明用16位地址的数据段和代码段,其段最大长度为64KB。若是“USE32”,则表明32位的段,段长度可达4GB。对于使用“.386”等伪指令,其缺省为32位的段。
2.编译与链接
先用Tasm进行编译,然后用Tlihk进行链接。或者用Masm编译,用Lihk进行链接。
3. 运行
在Wihdows的DOS窗口中程序运行结果如下:
IP=003A
CS=0D66 DS=0D4E
ES=0D4E FS=0000
GS=0000 SS=0D4E
ESP=00000000 EAX=0000003A
EBX=00000000 ECX=000000FF
EDX=A8D40D3E ESI=00000000
EDI=0000008A EBP=00000912
CR0=00000000 CR2=00000000
CR3=00000000 DR0=00000000
DR1=00000000 DR2=00000000
DR3=00000000 DR6=00000000
DR7=00000000 EFL=00003246
LDTR=
GDTR=0FFFC0F59000
IDTR=02FFC000D4D4
在纯粹DOS环境下运行的结果会略有不同。实际上在DOS下,是否载入Emm386.exe,也会有所不同。这是因为当起动DOS时,如果载入了Emm386.exe,它会把CPU切换入保护模式,所以控制寄存器和系统地址寄存器会有不同。
另外要注意,前面CRn的值并不全是正确的,因为指令“MOV CRn,REG”是特权指令,只有在实模式或保护模式0环上执行的程序才可直接读出,否则会引起异常。上面的CRn值,都是操作系统截获了这个异常后,模拟这条指令产生的结果,而操作系统未必会把真实的值给出。
例如,Windows9X的CR0,CR2和CR3都不可能为0。