www.pudn.com > RAM1.rar > RAM.ASM


;386以上微机适用 
;纯dos下才能使用 
;tasm4.1或以上编译 
;***********************; 
;*     存储器读写      *; 
;***********************; 
io_plx_device_id	equ 05406h	;TPC卡设备ID 
io_plx_vendor_id	equ 010b5h	;TPC卡厂商ID 
IO_PLX_SUB_ID		EQU 0905410B5H	;TPC卡子设备及厂商ID 
memaddress              equ 0a0000h     ;tpc设备存储器选择基地址 
data SEGMENT 
msg1    DB      0dh,0ah,'TPC pci card memory!',0dh,0ah,'$' 
gdt_def	DW	00h,00h,00h,00h	;全局描述符表GDT,第一段空 
	DW	0ffffh		;全局描述符表GDT,第二段,段界限低16位 
	DW	00h		;基地址低16位 
	DB	00H,92H		;基地址中间8位,段属性 
	DB	8FH,00H		;段界限的高4位(包括段属性的高4位),基地址的高8位 
gdt_addr DW	00h	;存放GDT的长度(以字节为单位的长度-1) 
	DW	00H,00H	;存放GDT的线性基地址 
memory_base_address	db 4 DUP(0)	;TPC卡MEMORY基地址暂存空间 
pcicardnotfind		db 0dh,0ah,'TPC pci card not find or address/interrupt error !!!',0dh,0ah,'$' 
memorybaseaddress	db 0dh,0ah,'TPC pci card Memory Base Address : ','$' 
enter_return		db 0dh,0ah,'$' 
data ENDS 
stacks segment 
 db 100 dup(?) 
stacks ends 
code SEGMENT 
        ASSUME CS:code,DS:data,SS:stacks,ES:data 
.386p 
start: 
        mov ax,data 
        mov ds,ax 
	mov	es,ax 
	mov	ax,stacks 
	mov	ss,ax 
        call    findtpc         ;查找TPC卡资源并显示 
 
        call opena20   ;打开a20地址线 
        call set4gb    ;进入保护模式重设段界限为4GB后返回实模式 
 
        mov esi,dword ptr memory_base_address 
	add esi,memaddress 
	mov ax,0 
	mov ds,ax 
        mov cx,100h 
        mov dl,40h 
loop1: 
	inc dl 
        mov [esi],dl 
        add esi,1 
        cmp dl,5ah 
        jnz loop2 
        mov dl,40h 
loop2: 
	loop loop1	;向tpc卡的存储空间反复写256个a-z 
 
        mov ax,data 
        mov ds,ax 
        mov esi,dword ptr memory_base_address 
	add esi,memaddress 
	mov ax,0 
	mov ds,ax 
        mov cx,100h 
loop3: 
        mov dl,[esi] 
        mov ah,02h 
        int 21h 
        add esi,1 
        loop loop3	;从tpc卡的存储空间读256个字节内容并显示 
 
	mov ax,data 
	mov ds,ax 
	MOV DX,OFFSET msg1 
	MOV AH,09h 
	INT 21h 
        call closea20 
	mov ax,4c00h 
	int 21h 
 
set4gb proc	;进入保护模式从设段界限为4GB后返回实模式 
        CLI 
        PUSH    DS 
	PUSH	ES 
        MOV     WORD PTR GDT_Addr[0], (2*8-1)	;   //GDT的长度存入GDT_Addr中 
        MOV     EAX,DS		;  //计算GDT描述符表的线性基地址31-0 
        SHL	EAX,4		;  //段地址eax=ds×16 
        XOR	EBX,EBX		;  //ebx清零 
        MOV	BX,OFFSET GDT_def	;   //bx=GDT的偏移地址 
        ADD	EAX,EBX		;  //GDT的线性基地址=eax+ebx 
        MOV	dword PTR GDT_Addr[2],EAX	;   //GDT的线性基地址存入GDT_Addr中 
        lgdt	qword PTR GDT_Addr 
        MOV	BX,8		;  //设置数据段描述符的选择字 
        MOV	EAX,cr0 
        OR	AL,1 
        MOV	cr0,EAX 
        JMP	flush1	;使保护模式下代码段的选择子装入CS,进入保护模式 
flush1: 
        MOV	DS,BX	;       //DS装载具有4GB界限的数据段描述符 
        MOV	ES,BX	;       //ES装载具有4GB界限的数据段描述符 
        AND	AL,0feh 
        MOV	cr0,EAX 
        JMP	flush2	;清指令预取队列,使实模式下代码段的段值装入CS,进入实模式 
;              //返回实方式 
flush2: 
        POP	ES 
	POP	DS 
        STI 
	ret 
set4gb endp 
 
opena20 proc	;打开a20地址线 
                push    ax 
                in      al,92h 
                or      al,00000010b 
                out     92h,al 
                pop     ax 
		ret 
opena20 endp 
 
closea20 proc	;关闭a20地址线 
                push    ax 
                in      al,92h 
                and     al,11111101b 
                out     92h,al 
                pop     ax 
		ret 
closea20 endp 
 
findtpc proc near		;查找TPC卡资源并显示 
	pushad 
	pushfd 
	MOV	AX,0B101H 
	INT	1AH 
	JC	findtpc_notfind		;检查PCI BIOS是否存在 
 
	MOV	AX,0B102H 
	MOV	CX,io_plx_device_id 
	MOV	DX,io_plx_vendor_id 
	MOV	SI,0 
	INT	1AH 
	JC	findtpc_notfind		;检查TPC卡是否安装,设备号、厂商号 
 
	MOV	AX,0B10AH 
	MOV	DI,02CH 
	INT	1AH 
	JC	findtpc_notfind 
	CMP	ECX,IO_PLX_SUB_ID 
	JNZ	findtpc_notfind		;检查TPC卡是否安装,子设备号、厂商号 
 
	MOV	AX,0B10AH 
	MOV	DI,1CH 
	INT	1AH 
	JC	findtpc_notfind		;读TPC卡MEMORY基址信息 
	mov	dword ptr memory_base_address,ecx 
	and	ecx,1h 
	jnz	findtpc_notfind		;检查是否为memory基址信息 
	mov	ecx,dword ptr memory_base_address 
	and	ecx,0fffffff0h 
	mov	dword ptr memory_base_address,ecx	;去除memory指示位并保存 
 
	mov	dx,offset memorybaseaddress	;显示memory提示信息 
	mov	ah,09h 
	int	21h 
	mov	ax,word ptr memory_base_address+2 
	call	dispword			;显示memory基地址高16位 
	mov	ax,word ptr memory_base_address 
	shr	ax,16 
	call	dispword			;显示memory基地址低16位 
 
	mov	dx,offset enter_return		;加回车符,换行符 
	mov	ah,09h 
	int	21h 
	popfd 
	popad 
	ret 
findtpc_notfind: 
	mov dx,offset pcicardnotfind		;显示未找到tpc卡提示信息 
	mov ah,09h 
	int 21h 
	mov ax,4c00h 
	int 21h		;退出 
findtpc endp 
 
dispword proc near		;显示子程序 
	push dx 
	push cx 
	push bx 
	mov cx,4 
	mov bx,16 
dispword_loop1: 
	push ax 
	push cx 
	sub bx,4 
	mov cx,bx 
	shr ax,cl 
	and al,0fh	;首先取低四位 
	mov dl,al 
	cmp dl,9	;判断是否<=9 
	jle dispword_num		;若是则为'0'-'9',ASCII码加30H 
	add dl,7	;否则为'A'-'F',ASCII码加37H 
dispword_num: 
	add dl,30h 
	mov ah,02h	;显示 
	int 21h 
	pop cx 
	pop ax 
	loop dispword_loop1 
	pop bx 
	pop cx 
	pop dx 
	ret		;子程序返回 
dispword endp 
code ENDS 
END start