Truy cập trực tiếp vào bộ nhớ trong C

7 901 6
Truy cập trực tiếp vào bộ nhớ trong C

Đang tải... (xem toàn văn)

Thông tin tài liệu

Truy cập trực tiếp vào bộ nhớ trong C

chương 9Truy nhập trực tiếp vào bộ nhớTrong chương này trỡnh bầy cỏc vấn đề:+ Hai kiểu địa chỉ: Địa chỉ phõn đoạn và địa chỉ thực+ Truy nhập tới địa chỉ phõn đoạn+ Đổi từ địa chỉ phõn đoạn sang địa chỉ thực+ Bộ nhớ màn hỡnh, truy nhập trực tiếp vào bộ nhớ màn hỡnh+ Dựng con trỏ để lấy dữ liệu từ bộ nhớ phõn đoạn+ Dựng con trỏ hàm để thực hiện cỏc thủ tục của DOS§ 1. Cỏc hàm truy nhập theo địa chỉ phõn đoạn1. Hàm pokeb: Gửi một ký tự vào bộ nhớ.+ Nguyờn mẫu trong dos.h như sau:void pokeb(unsigned seg, unsigned off, char value);+ Cụng dụng: Gửi giỏ trị ký tự value vào bộ nhớ tại địa chỉ phõn đoạn seg:off2. Hàm peekb: Nhận một ký tự từ bộ nhớ.+ Nguyờn mẫu trong dos.h như sau:char peekb(unsigned seg, unsigned off);+ Cụng dụng: Nhận một byte tại địa chỉ phõn đoạn seg:off3. Hàm poke: Gửi một số nguyờn vào bộ nhớ.+ Nguyờn mẫu trong dos.h như sau:void poke(unsigned seg, unsigned off, int value);+ Cụng dụng: Gửi giỏ trị nguyờn value vào bộ nhớ tại địa chỉ phõn đoạn seg:off4. Hàm peek: Nhận một số nguyờn từ bộ nhớ.+ Nguyờn mẫu trong dos.h như sau:int peek(unsigned seg, unsigned off);+ Cụng dụng: Nhận một word tại địa chỉ phõn đoạn seg:off5. Hàm movedata: Sao cỏc byte.+ Nguyờn mẫu trong mem.h như sau:void movedata(unsigned seg_gui, unsigned off_gui,unsigned seg_nhan, unsigned off_nhan, int n);+ Cụng dụng: Sao n byte từ seg_gui:off_gui đến seg_nhan:off_nhan§ 2. Bộ nhớ màn hỡnh văn bản2.1. Cỏch biểu diễn ký tự trong bộ nhớ màn hỡnhBộ nhớ màn hỡnh văn bản bắt đầu từ địa chỉ :(0xb800:0x0000)Khi đưa một ký tự vào vựng nhớ màn hỡnh, thỡ nú sẽ hiện lờn màn hỡnh. Mỗi ký tự trờn màn hỡnh chiếm 2 byte trong bộ nhớ màn hỡnh: byte đầu chứa mó ASCII, byte thứ hai biểu diễn mầu hiển thị gọi là byte thuộc tớnh. Cỏc bit của byte thuộc tớnh:B7B6B5B4B3B2B1B0được chia làm 3 nhúm:+ Nhúm 1 gồm bit B7 biểu thị sự nhấp nhỏy. Nếu B7=0 thỡ ký tự khụng nhấp nhỏy, nếu B7=1 thỡ ký tự sẽ nhấp nhỏy.+ Nhúm 2 gồm cỏc bit B6, B5 và B4. Cỏc bit này chứa được một số nguyờn từ 0 đến 7 và biểu thị 8 mầu nền của ký tự.+ Nhúm 3 gồm cỏc bit B3, B2, B1 và B0. Cỏc bit này chứa được một số nguyờn từ 0 đến 15 và biểu thị 16 mầu của ký tự.2.2. Trang màn hỡnh Mỗi trang màn hỡnh gồm 80x25 ký tự, do đú cần 80x25x2=4000 byte bộ nhớ. Thực tế mỗi trang màn hỡnh được phõn bố 4096 = 0x1000 byte. Như vậy 4 trang màn hỡnh được phõn bố như sau:491 492 + Trang màn hỡnh thứ 0 bắt đầu từ địa chỉ 0xB800:0x0000+ Trang màn hỡnh thứ 1 bắt đầu từ địa chỉ 0xB800:0x1000+ Trang màn hỡnh thứ 2 bắt đầu từ địa chỉ 0xB800:0x2000+ Trang màn hỡnh thứ 3 bắt đầu từ địa chỉ 0xB800:0x30002.3. Chọn trang hiển thịTại mỗi thời điểm chỉ cú thể hiển thị được một trong 4 trang màn hỡnh. Để hiển thị trang màn hỡnh thứ t (t=0,1,2,3) chỳng ta sử dụng chức năng 5 của ngắt 0x10 theo mẫu sau:union REGS v,r;v.h.ah = 5 ; // Chức năng 5v.h.al = t ; // Số hiệu trang màn hỡnh cần hiển thịint86(0x10, &v, &r); // Thực hiện ngắt 0x102.4. Vớ dụ minh hoạVớ dụ sau dựng hàm pokeb để đưa cỏc ký tự vào cỏc trang của bộ nhớ màn hỡnh, sau đú dựng chức năng 5 của ngắt 0x10 để chọn trang hiển thị.//CT9_03.CPP#include <dos.h>#include <conio.h>char d1[]={'C',1*16+14,'H',1*16+14,'U',1*16+14,'C',1*16+14};char d2[]={'M',2*16+15,'U',2*16+15,'N',2*16+15,'G',2*16+15};void main(){union REGS v,r;clrscr();//Mặc định hiển thị trang 0for (int i=0;i<8;++i)pokeb(0xb800,i,d1[i]);getch();//Hien thi trang 1v.h.ah = 5 ; v.h.al = 1 ;int86(0x10,&v,&r);for (i=0;i<8;++i)pokeb(0xb800,0x1000+i,d2[i]);getch();//Hien thi trang 0v.h.ah = 5 ; v.h.al = 0 ;int86(0x10,&v,&r);getch();//Hien thi trang 1v.h.ah = 5 ; v.h.al = 1 ;int86(0x10,&v,&r);getch();}§ 3. chuyển Đổi địa chỉ 3.1. Để chuyển từ địa chỉ thực sang địa chỉ phõn đoạn ta dựng cỏc macro: unsigned FP_SEG(địa_chỉ_thực) unsigned FP_OFF(địa_chỉ_thực)3.2. Để chuyển từ địa chỉ phõn đoạn sang địa chỉ thực ta dựng macro:void far *MK_FP(seg,off)Vớ dụ 1. Sau khi thực hiện cỏc cõu lệnh:char buf[100];unsigned ds,dx;493 494 ds = FP_SEG(buf); dx = FP_OFF(buf);thỡ ds:dx chứa địa chỉ của mảng buf.Vớ dụ 2. Sau khi thực hiện cỏc cõu lệnh:char far *pchar;pchar = (char far*)MK_FP(0xb800:0);thỡ pchar trỏ tới địa chỉ đầu của bộ nhớ màn hỡnh. Khi đú ta cú thể sử dụng cỏc lệnh gỏn để truy nhập trực tiếp tới bộ nhớ màn hỡnh.§ 4. cỏc vớ dụ minh hoạChương trỡnh 1. Chương trỡnh minh hoạ cỏch truy nhập trực tiếp vào bộ nhớ màn hỡnh cú địa chỉ đầu là 0xB800:0. Chương trỡnh gồm hàm main() và hai hàm sau:1. Hàm cuasovoid cuaso(int dongt,int cott,int dongd,int cotd,int maucs); thiết lập một cửa sổ mầu cú toạ độ gúc trờn-trỏi là (dongt, cott) và gúc dưới-phải là (dongd,cotd). Mầu cho bởi tham số maucs. ở đõy sử dụng hàm pokeb và địa chỉ phõn đoạn.2. Hàm duarmhvoid duarmh(char *day, int dong, int cotd, int cotc,int m_nen, int m_chu);sẽ đưa ra màn hỡnh một dẫy ký tự (chứa trong dóy) tại dũng dong, từ cột cotd đến cotc. Mầu nền cho bởi m_nen, mầu chữ cho bởi m_chữ. ở đõy sử dụng toỏn tử gỏn trờn địa chỉ thực.Trong hàm main() sẽ sử dụng cỏc hàm cuaso và duarmh để tạo hai cửa sổ và viết hai dũng chữ trờn trang màn hỡnh thứ hai (từ dũng 26 đến dũng 50)./*chương trỡnh minh hoạ cỏch truy nhập trực tiếp vào bộnhớ của màn hỡnh*/#include "dos.h"#include "conio.h"void duarmh(char *day, int dong,I nt cotd, int cotc,I nt m_nen, int m_chu);void cuaso(int dongt,int cott,int dongd,int cotd,int maucs);main(){cuaso(26,1,50,80,BLUE);duarmh("Chuc mung nam moi", 28, 30, 50, MAGENTA, WHITE);cuaso(30,20,46,60,RED);duarmh("Chuc mung nam moi", 40, 30, 50, MAGENTA, YELLOW);getch();}void cuaso(int dongt,int cott,int dongd,int cotd,int maucs)/* Dung dia phan doan */{int i, j, p, t, dt, dd, mau;union REGS v, r;/* Xac dinh thuoc tinh mau */mau = (maucs << 4)+maucs;/*Xac dinh trang man hinh tva cac chi so dong tren dt, dong duoi ddtrong trang t*/t=(dongt-1)/25;495 496 dt=(dongt-1)-t*25; dd=(dongd-1)-t*25;/* Chon t la trang hien thi */v.h.ah=5;v.h.al=t; int86(0x10,&v,&r);/*Dua cac khoang trong (ma 32) va thuoc tinh mauvao cac vi tri thich hop cua bo nho man hinh*/for (i=dt;i<=dd;++i){p=t*4096+i*160+(cott-1)*2;for (j=0;j<=cotd-cott;++j){ pokeb(0xb800,p+2*j,32);pokeb(0xb800,p+2*j+1,mau);}}}void duarmh(char *day, int dong, int cotd, int cotc, int m_nen,int m_chu)/* Dung dia chi thuc */{int i,p,t,d,kt,mau; char far *buf;union REGS v,r;/* Lay dia chi thuc cua bo nho man hinh */buf=(char far*)MK_FP(0xb800,0);/* Xac dinh thuoc tinh mau */mau = (m_nen << 4)+m_chu;/*Xac dinh trang man hinh tva cac chi so dong d trong trang t*/t=(dong-1)/25; d=dong-1-t*25;/* Chon t la trang hien thi */v.h.ah=5;v.h.al=t; int86(0x10,&v,&r);p=t*4096+d*160+(cotd-1)*2;/*Dua cac ky tu va thuoc tinh mauvao cac vi tri thich hop cua bo nho man hinh*/for (i=0;i<=cotc-cotd;++i){if ((kt=day[i])==0) break;buf[p+2*i]=kt;buf[p+2*i+1]=mau;}}Chương trỡnh 2. Biết địa chỉ của cỏc thủ tục xử lý ngắt được lưu trữ trong bộ nhớ từ địa chỉ 0000:0000 đến 0000:0x0400. Chương trỡnh sẽ cho biết địa chỉ của thủ tục xử lý ngắt n (giỏ trị n nhập vào từ bàn phớm). Số hiệu của ngắt được tớnh từ 0, nhưng n được đỏnh số từ 1. /*Xac dinh dia chi cac thu tuc ngat */#include "dos.h"#include "conio.h" #include "stdio.h"497 498 main(){unsigned char far *p; /*p se tro toi bang vecto ngat*/int n; /* n - so hieu ngat, n=1,2, . */ int k; /* vi tri cua ngat n trong bang vecto ngat */unsigned seg,off;/* p tro toi bang vecto ngat */p=(unsigned char far*)MK_FP(0,0);clrscr();while(1){printf("\n So hieu ngat (Bam 0 - Ket thuc): ");scanf("%d",&n); if(n==0) break;k=(n-1)*4;off=p[k]+256*p[k+1]; seg=p[k+2]+256*p[k+3];printf("\nDia chi %x:%x",seg,off);}}Chương trỡnh 3. Chương trỡnh minh hoạ cỏch dựng con trỏ hàm để thực hiện thủ tục khởi động lại mỏy của DOS, biết địa chỉ đầu của thủ tục này là 0xFFFF:0000 . Chương trỡnh yờu cầu nhập mật khẩu. Nếu chọn đỳng (bấm ABCD và Enter) thỡ chương trỡnh tiếp tục làm việc, nếu vào sai thỡ sẽ khởi động lại mỏy.#include <dos.h>#include <conio.h>#include <iostream.h>#include <ctype.h>typedef void far (*HAM)(void);void khoi_dong_may(void){HAM f;f = (HAM)MK_FP(0xFFFF,0);f();}char mat_khau[]= {'A','B','C','D'};int n = sizeof(mat_khau)/sizeof(char);void main(){char i, ch, sai_mat_khau;clrscr();i=0;sai_mat_khau=0;cout << "\nMat khau: ";while(1){ch=getch();if (ch==13) break;cout << '*' ;if (i<n){if (toupper(ch)!=mat_khau[i])sai_mat_khau=1;}elsesai_mat_khau=1;499 500 ++i ;}if (sai_mat_khau){cout << "\nSai mat khau, Khoi dong lai may";getch();khoi_dong_may();}else{cout << "\nDung mat khau, tiep tuc chuong trinh";getch();}}Chương trỡnh 4. Chương trỡnh minh hoạ cỏch dựng biến con trỏ để lấy dữ liệu về thời gian hệ thống chứa trong 4 byte bắt đầu từ địa chỉ 0:0x46C . Chương trỡnh cũng minh hoạ cỏch truy nhập trực tiếp bộ nhớ màn hỡnh văn bản (địa chỉ đầu là 0xB800:0) và cỏch bắt phớm tổng quỏt. Chương trỡnh sẽ in ra màn hỡnh cỏc chữ cỏi một cỏch ngẫu nhiờn. Khi bấm phớm F1 chương trỡnh tạm dừng để thụng bỏo thời gian. Để kết thỳc chương trỡnh bấm phớm ESC.#include <dos.h>#include <conio.h>#include <stdlib.h>#define VT 132 // vi tri thong bao//Dia chi vung nho man hinhchar far *p_mh = (char far*)MK_FP(0xB800,0) ;//Dia chi 4 byte chua thoi gianunsigned long far *t_time=(unsigned long far*)MK_FP(0,0x46C);char buf_time[]={'T',47,'I',47,'M',47,'E',47,':', 47, 32, 47, 32, 47, 32, 47, 32, 47, 32, 47, 32, 47, 32, 47, 32, 47, 32, 47};char buf_luu[28];void thong_bao_thoi_gian(){//Luu trang thai man hinhfor (int i=0; i<28; ++i)buf_luu[i]=p_mh[i];// Xac dinh gio, phut, giayint gio = (int)(*t_time/65543) ;unsigned long du = *t_time%65543 ;int phut = (int)(du/1092);du = du%1092;int giay = (int)(du/18);//Doi ra ky tu dua vao mang buf_timebuf_time[12]=gio/10 + 48;buf_time[14]=gio%10 + 48;buf_time[18]=phut/10 + 48;buf_time[20]=phut%10 + 48;buf_time[24]=giay/10 + 48;buf_time[26]=giay%10 + 48;//Dua thong bao goi ra man hinhfor (i=0; i<28; ++i)p_mh[i] = buf_time[i];getch();//Khoi phuc man hinhfor (i=0; i<28; ++i)501 502 p_mh[i] = buf_luu[i];}void main(){int ch1, ch2;clrscr();while(1){if (kbhit()){ch1=getch();if (ch1==0) ch2=getch();if (ch1==27) //ESCbreak;if (ch1==0 && ch2==59) // Bam F1thong_bao_thoi_gian();}//In cac chu cai mot cach ngau nhiengotoxy(random(80)+1,random(25)+1);putch(random(26)+65);delay(400);}}503 . chương 9Truy nhập tr c tiếp vào bộ nh Trong chương này trỡnh bầy c c vấn đề:+ Hai kiểu địa chỉ: Địa chỉ phõn đoạn và địa chỉ th c+ Truy nhập tới địa chỉ. địa chỉ phõn đoạn sang địa chỉ th c+ Bộ nhớ màn hỡnh, truy nhập tr c tiếp vào bộ nhớ màn hỡnh+ Dựng con trỏ để lấy dữ liệu từ bộ nhớ phõn đoạn+ Dựng con

Ngày đăng: 17/08/2012, 11:07

Từ khóa liên quan

Tài liệu cùng người dùng

  • Đang cập nhật ...

Tài liệu liên quan