📄 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
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -