⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ram.asm

📁 有关内存扩充的汇编程序
💻 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

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -