Giáo trình C - Chương 4: Bộ nhớ và hiển thị kí tự

Các phép toán này có thể áp dụng cho dữ liệu kiểu int , char nh-ng không áp dụng

cho số float .

 Toán tử & (khác với and logic &&) cần hai toán hạng có kiểu giống nhau . Các toán

hạng này đ-ợc and bit với bit . Toán tử & th-ờng dùng kiểm tra xem một bit cụ thể nào đó

có trị là bao nhiêu . Ví dụ để kiểm tra bit thứ 3 cuả biến ch có trị 1 hay 0 ta dùng phép toán :

ch &0x08;

pdf12 trang | Chuyên mục: C/C++ | Chia sẻ: dkS00TYs | Lượt xem: 1552 | Lượt tải: 1download
Tóm tắt nội dung Giáo trình C - Chương 4: Bộ nhớ và hiển thị kí tự, để xem tài liệu hoàn chỉnh bạn click vào nút "TẢI VỀ" ở trên
thêm một 
trình xử lí văn bản theo dòng . Trình xử lí này chỉ làm việc trên một dòng văn bản . Ta sẽ 
tiến hành theo 2 b−ớc : đầu tiên là một ch−ơng trình cho phép ng−ời dùng gõ vào một dòng 
50
và di chuyển con nháy tới lui . Có thể xoá kí tự nhờ di chuyển con nháy tới đó và ghi đè lên 
nó . Ch−ơng trình nh− sau : 
Ch−ơng trình 4-4 : 
#include 
#include 
#define colmax 80 
#define rarrow 77 
#define larrow 75 
#define video 0x10 
#define ctrlc '\x03' 
int col=0; 
int far *fptr; 
union REGS reg; 
void main() 
 { 
 char ch; 
 void clear(void); 
 void cursor(void); 
 void insert(char); 
 fptr=(int far*)0xB8000000; 
 clear(); 
 cursor(); 
 while((ch=getch())!=ctrlc) 
 { 
 if (ch==0) 
 { 
 ch=getch(); 
 switch (ch) 
 { 
 case rarrow : if (col<colmax) 
 ++col; 
 break; 
 case larrow : if (col>0) 
 --col; 
 break; 
 } 
 } 
 else 
 if (col<colmax) 
 insert(ch); 
 cursor(); 
 } 
 } 
void cursor() 
 { 
 reg.h.ah=2; 
 reg.h.dl=col; 
 reg.h.dh=0; 
51
 reg.h.bh=0; 
 int86(video,®,®); 
 } 
void insert(char ch) 
 { 
 *(fptr+col)=ch|0x0700; 
 ++col; 
 } 
void clear() 
 { 
 int j; 
 for (j=0;j<2000;j++) 
 *(fptr+j)=0x0700; 
 } 
Để xoá màn hình ta điền số 0 vào vùng nhớ màn hình với thuộc tính 07 . Sau đó con 
nháy đ−ợc di chuyển về đầu màn hình nhờ phục vụ ấn định vị trí con nháy nh− sau : 
 ngắt 10h 
 ah=0; 
 dh=số hiệu dòng 
 dl= số hiệu cột 
 bh=số hiệu trang , th−ờng là 0 
Phát biểu switch dùng để đoán nhận các phím đ−ợc nhận là phím th−ờng hay phím 
chức năng . Phím mũi tên dùng tăng giảm col và gọi hàm cursor() để di chuyển con nháy tới 
đó . Nếu kí tự gõ vào là kí tự th−ờng , nó đ−ợc chèn vào nhờ hàm insert() . 
6. Byte thuộc tính : Một kí tự trên màn hình đ−ợc l−u giữ bởi 2 byte : một byte là mã của kí 
tự và byte kia là thuộc tính của nó . Byte thuộc tính đ−ợc chia làm nhiều phần , bit nào bằng 
1 thì thì thuộc tính t−ơng ứng đ−ợc bật . Bit thứ 3 điều khiển độ sáng còn bit thứ 7 điều 
khiển độ chớp nháy . Các bit còn lại là : 6 - thành phần đỏ của màu nền ; 5 - thành phần 
green của màu nền ; 4 - thành phần blue của màu nền ; 2 - thành phần đỏ của màu chữ ; 1 - 
thành phần green của màu chữ ; 0 - thành phần blue của màu chữ . Ta lập một ch−ơng trình 
để điền đầy màn hình bằng các kí tự chớp nháy . 
Ch−ơng trình 4-5 : 
#include 
#include 
#define rowmax 25 
#define colmax 80 
void main() 
 { 
 int far *fptr; 
 int row,col; 
 char ch; 
 clrscr(); 
 printf("Go vao mot ki tu , go lai de thay doi"); 
 fptr=(int far*)0xB8000000; 
 while((ch=getche())!='x') 
 for (row=0;row<rowmax;row++) 
52
 for (col=0;col<colmax;col++) 
 *(fptr+row*colmax+col)=ch|0x8700; 
 } 
Để bật chớp nháy ta để bit thứ 7 thành 1 , 3 bit màu nền 0 , 1 và 2 đ−ợc đặt trị 1 nên 
nền sẽ là đen . Byte thuộc tính lúc này là 10000111 = 87h. 
7. Ch−ơng trình điền thuộc tính : Để hiểu sâu hơn thuộc tính của kí tự ta xét ch−ơng trình 
sau 
Ch−ơng trình 4-6 : 
#include 
#include 
#define rowmax 25 
#define colmax 80 
void main() 
 { 
 int far *fptr; 
 char ch,attr=0x07; 
 void fill(char,char); 
 clrscr(); 
 printf("Go n cho chu binh thuong,\n"); 
 printf("Go b cho chu xanh nuoc bien,\n"); 
 printf("Go i cho chu sang,\n"); 
 printf("Go c cho chu chop nhay,\n"); 
 printf("Go r cho chu dao mau\n"); 
 while((ch=getche())!='x') 
 { 
 switch (ch) 
 { 
 case 'n':attr=0x07; 
 break; 
 case 'b':attr=attr&0x88; 
 attr=attr|0x01; 
 break; 
 case 'i':attr=attr^0x08; 
 break; 
 case 'c':attr=attr^0x80; 
 break; 
 case 'r':attr=attr&0x88; 
 attr=attr|0x70; 
 break; 
 } 
 fill(ch,attr); 
 } 
 } 
void fill(char ch,char attr) 
 { 
 int far *fptr; 
 int row,col; 
 fptr=(int far*)0xB8000000; 
 for (row=0;row<rowmax;row++) 
53
 for (col=0;col<colmax;col++) 
 *(fptr+row*colmax+col)=ch|attr<<8; 
 } 
 Trong hàm fill() ta có lệnh 
*(fptr+row*colmax+col)=ch|attr<<8; 
vì attr là kí tự nên phải dịch trái 8 bit tr−ớc khi kết hợp với ch . 
8. Trở lại xử lí văn bản : Bây giờ chúng ta đã biết thuộc tính của kí tự và ta sẽ mở rộng 
ch−ơng trình xử lí văn bản bằng cách thêm vào việc chèn và huỷ bỏ kí tự ,đổi màu . 
Ch−ơng trình 4-7 : 
#include 
#include 
#define colmax 80 
#define rarrow 77 
#define larrow 75 
#define video 0x10 
#define norm 0x07 
#define blue 0x01 
#define bkspc 8 
#define altu 22 
#define ctrlc '\x03' 
int col=0; 
int length=0; 
int far *fptr; 
union REGS reg; 
void main() 
 { 
 char ch,attr=norm; 
 void clear(void); 
 void cursor(void); 
 void insert(char,char); 
 void del(void); 
 fptr=(int far*)0xB8000000; 
 clear(); 
 cursor(); 
 while((ch=getch())!=ctrlc) 
 { 
 if (ch==0) 
 { 
 ch=getch(); 
 switch (ch) 
 { 
 case rarrow : if (col<length) 
 ++col; 
 break; 
 case larrow : if (col>0) 
 --col; 
 break; 
 case altu : attr=(attr==norm)? blue:norm; 
 } 
54
 } 
 else 
 switch (ch) 
 { 
 case bkspc: if (length>0) 
 del(); 
 break; 
 default : if (length<colmax) 
 insert(ch,attr); 
 } 
 cursor(); 
 } 
 } 
void cursor() 
 { 
 reg.h.ah=2; 
 reg.h.dl=col; 
 reg.h.dh=0; 
 reg.h.bh=0; 
 int86(video,®,®); 
 } 
void insert(char ch,char attr) 
 { 
 int i; 
 for (i=length;i>col;i--) 
 *(fptr+i)=*(fptr+i-1); 
 *(fptr+col)=ch|attr<<8; 
 ++length; 
 ++col; 
 } 
void del() 
 { 
 int i; 
 for (i=col;i<=length;i++) 
 *(fptr+i-1)=*(fptr+i); 
 --length; 
 --col; 
 } 
void clear() 
 { 
 int j; 
 for (j=0;j<2000;j++) 
 *(fptr+j)=0x0700; 
 } 
 Khi gõ tổ hợp phím Alt+U sẽ lật biến attr qua lại giữa norm(thuộc tính 07) và blue 
(cho chữ màu xanh - thuộc tính 01) . Hàm insert(0 có vòng lặp for dùng để thâm nhập trực 
55
tiếp bộ nhớ và con trỏ far để dịch các kí tự sang trái khi cần chèn . Tiến trìmh dịch phải bắt 
đầu từ cuối câu để tránh ghi đè lên . 
Đ4. Các kiểu bộ nhớ trong C 
1. Địa chỉ đoạn và offset : Trong C kiểu bộ nhớ là khái niệm để chỉ về l−ợng các phần bộ 
nhớ khác nhau mà ch−ơng trình có thể chiếm . C cho phép 6 kiểu bộ nhớ là tiny , small , 
compact , medium , large và huge . Kiểu bộ nhớ mặc định là small . 
 Bộ vi xử lí dùng các thanh ghi 16 bit để ghi địa chỉ . Thanh ghi 16 bit l−u đ−ợc ffffh 
byte hay 65536 hay 64 Kb địa chỉ . Vùng nhớ có kích th−ớc này gọi là đoạn . Để truy cập 
địa chỉ nằm ngoài đoạn , bộ vi xử lí phải dùng hai thanh ghi là thanh ghi đoạn và thanh ghi 
offset . Địa chỉ thực đ−ợc tính bằng cách dịch địa chỉ của thanh ghi đoạn sang trái 4 bit rồi 
cộng với thanh ghi offset . Làm nh− vậy ta đánh địa chỉ đ−ợc fffffh hay 1048576 = 1Mb . 
2. Hai loại chỉ thị của bộ vi xử lí : Bộ vi xử lí dùng hai kĩ thuật khác nhau để tham chiếu dữ 
liệu trong bộ nhớ . Nếu vị trí cần tham chiếu nằm trong đoạn 64Kb và đoạn này đã đ−ợc chỉ 
định trong thanh ghi đoạn thì bộ vi xử lí chỉ cần dùng một lệnh duy nhất để truy cập dữ liệu . 
Cách này t−ơng ứng với việc dùng con trỏ near trong C và thực hiện rất nhanh . Trái lại nếu 
bộ vi xử lí cần tham chiếu ô nhớ nằm ngoài đoạn thì đầu tiên nó phải thay đổi địa chỉ đoạn 
và sau đoa là địa chỉ offset . Điều này t−ơng ứng với việc dùng con trỏ far trong C và thực 
hiện khá chậm . 
3. Các kiểu Compact , small , medium và large : Có 4 loại chỉ thị của bộ vi xử lí ứng với 4 
kiểu bộ nhớ trong C 
Kiểu Mã Dữ liệu
small near near 
medium far near 
compact near far 
large far far 
 Nếu mã ch−ơng trình nằm gọn trong một đoạn 64 K và mã dữ liệu nằm gọn trong 
một đoạn 64 K khác thì kiểu bộ nhớ small là thích hợp . Nếu mã ch−ơng trình lớn hơn 64 K 
và mã dữ liệu nằm gọn trong một đoạn 64 K khác thì hãy dùng kiểu bộ nhớ medium. Nếu 
mã ch−ơng trình nhỏ hơn 64 K và mã dữ liệu lớn hơn 64 K thì hãy dùng kiểu bộ nhớ 
compact. Nếu cả mã ch−ơng trình và mã dữ liệu lớn hơn 64 K thì hãy dùng kiểu bộ nhớ 
large . 
4. Kiểu tyni và kiểu huge : Kiểu tyni đ−ợc dùng trong các tr−ờng hợp đặc biệt với l−ợng 
bộ nhớ cho cả mã ch−ơng trình lẫn mã dữ liệu nằm gọn trong một đoạn . Kiểu này đ−ợc 
dùng để tạo ra tập tin dạng *.com . Kiểu huge đ−ợc dùng chô một mục dữ liệu (th−ờng là 
mảng ) mà bản thân nó lớn hơn 64K . 
Đ5. Từ chứa danh mục thiết bị 
 Đây là một vùng bộ nhớ dài 2 byte nằm trong vùng nhớ thấp có địa chỉ tuyệt đối là 
410h chứa thông tin về thiết bị đ−ợc nối với máy tính. Để truy cậo từ này ta dùng con trỏ far 
. Con trỏ sẽ chỉ tới đoạn 0000 , địa xhỉ offset là 0410h và đ−ợc biểu diễn trong C là 
00000410 hay 0x410 
56
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0
 có 
Số máy in ổ đĩa 
đang có Không 
Có lắp máy dùng 
in nối tiếp RAM mạch 
Có lắp game hệ thống 
adaptor 00=16K 
Số cổng nối tiếp 01=32K 
 Có lắp chíp 11=64K 
 DMA Kiểu màn hình 
 01=màu 40 cột 
 Số ổ đĩa 10=màu 80 cột 
 00 = 1 ổ 11=đơn sắc 80 cột 
 01 = 2 ổ 
 10 = 3 ổ 
 11 = 4 ổ 
 Để xem xét từng bit và nhóm bit trong từ này chúng ta sẽ dùng các toán tử bitweise . 
Nói chung ta sẽ dịch từ chứa danh mục thiết bị sang phải và đ−a các bit cần quan tâm vào 
phía phải của từ và che các bit không quan tâm ở phái trái bằng toán tử and . Ngoài từ chứa 
danh mục thiết bị ta có thể đọc từ chứa kích th−ớc bộ nhớ tại địa chỉ 413h . 
Ch−ơng trình 4-8 : 
#define eqlist 0x410 
#define memsiz 0x413 
#include 
#include 
void main() 
 { 
 int far *fptr; 
 unsigned int eq,data; 
 clrscr(); 
 fptr=(int far *)eqlist; 
 eq=*(fptr); 
 data=eq>>14; 
 printf("So may in la : %d\n",data); 
 if (eq&0x2000) 
 printf("Co may in noi tiep\n"); 
 data=(eq>>9)&7; 
 printf("So cong noi tiep la :%d\n",data+1); 
 if (eq&1) 
 { 
 data=(eq>>6)&3; 
 printf("So dia mem la :%d\n",data); 
 } 
 else 
57
 printf("Khong co dia mem\n"); 
 data=(eq>>4)&3; 
 switch (data) 
 { 
 case 1: printf("Man hinh mau 40 cot\n"); 
 break; 
 case 2: printf("Man hinh mau 80 cot\n"); 
 break; 
 case 3: printf("Man hinh don sac 80 cot\n"); 
 } 
 fptr=(int far *)memsiz; 
 printf("Dung luong bo nho :%dKbyte\n",*(fptr)); 
 getch(); 
 } 

File đính kèm:

  • pdfGiao_Trinh_C_Chuong4.pdf
Tài liệu liên quan