Thứ Hai, 10 tháng 1, 2022

4: Bộ Nhớ Và Hiến Thị Kí Tự (Phần 2) - Các Kiểu Bộ Nhớ Trong C, Từ Chứa Danh Mục Thiết Bị

 

4: Bộ Nhớ Và Hiến Thị Kí Tự


- 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 bít để ghi địa chỉ . Thanh ghi 16 bít 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 64‡Kb 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 đữ 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ã đữ liệu nằm gọn trong
một đoạn 64Kb khác thì kiểu bộ nhớ small là thích hợp.
- Nếu mã chương trình lớn hơn 64Kb và mã đữ 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 đữ liệu (thường là mảng) mà bản thân nó lớn hơn 64Kb.

- 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à O410h và được biểu diễn trong C là 00000410 hay 0x410
15 14 13 12 11 10 9 8 7 6 5 4 3 2 1 0

Trong đó:
15 14: Số máy in đang có
13: Có lắp máy in nối tiếp 2
12: Có lắp game adaptor
11 10 9:  Số cổng nối tiếp
8: Có lắp chíp DMA
7 6: Số ổ đĩa
    + 00 = l ổ
    + O0l = 2 ổ
    + 10 = 3 ổ
    + 11 = 4 ổ
5 4: Kiểu màn hình
    + 01 =  màu 40 cột
    + 10 =  màu 80 cột
    + 11 =  đơn sắc 80 cột
3 2: RAM mạch hệ thống
    + 00 = 16K
    + 01 = 32K
    + 11 = 64K
1: Không dùng
0: Có ổ đĩa

Để 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:
// Memory_8
#include <conio.h>
#include <stdio.h>
#define eqlist 0x410
#define memsiz 0x413

int main()   {     
    int far *fptr;     
    unsigned int eq,data;     
  
    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
        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();
    
    return 0;
}


0 bình luận:

Đăng nhận xét