Trong chế độ thực, Turbo Pascal giới hạn phân đoạn dữ liệu (data segment) 64KB=65536 Byte.
Mọi khai báo Biến, Kiểu, cấp bộ nhớ ... đều phải có kích thước <=64KB.
Nếu >64KB: gây lỗi, sẽ không thể biên dịch được.
Ví dụ:
Code:
TYPE
TB = array [0..66000] ò Byte; { => Lỗi}
VAR
vP :Pointer;
BEGIN
GetMem (vP, 65540); { => Lỗi}
............................;
.....................................;
FreeMem (vP, 65540); { => Lỗi}
END.
Vậy, làm thế nào để cấp biến nhớ lớn hơn 64KB ?
Trong DOS, có cách giải quyết như sau:
- Trong các ngắt (interrupt) của DOS (ngắt 21h) có:
...+ Hàm 48h: là cấp phát bộ nhớ RAM; --Như thủ tục GetMem;
...+ Hàm 49h: giải phóng bộ nhớ RAM; --Như thủ tục FreeMem;
...+ Hàm 4ah: thay đổi kích thước vùng nhớ.
...
Trong phần này ta chỉ quan tâm đến hàm 48h và 49h.
- Phần vùng nhớ cấp phát được lấy từ Bộ nhớ quy ước (?) (Conventional Memory: Là vùng bộ nhớ từ 0 KB đến 640KB trong DOS).
- Kích thước vùng nhớ yêu cầu cấp phát được tính theo paragraph (nghĩa là: đoạn, phần ???).
Mỗi paragraph = 16 byte.
Do đó: số paragraph cần cấp = Số Byte cần cấp chia cho 16.
Ví dụ: nếu cần cấp 64KB bộ nhớ thì phải yêu cầu cấp (64*1024)/16=4096paragraph.
- Mô tả các hàm:
Code:
{Cấp bộ nhớ}
function Alloc (vPara :Word) :Word; Assembler;
{Nếu thành công, Hàm này trả về giá trị kiểu Word,
là địa chỉ đoạn của vùng nhớ được cấp phát}
asm
mov ah,48h {Hàm 48h}
mov bx,vPara {Số paragraph bộ nhớ cần cấp phát}
inc bx
int 21h {Gọi ngắt 21h}
jnc @OK {Cờ Carry = 0: Thành công}
mov ax,$ffff {Cờ Carry = 1: Lỗi, thanh ghi ax lúc này chứa mã lỗi: }
{ax=7: Khối điều khiển bộ nhớ bị xóa}
{ax=8: Không đủ RAM; bx= kích thước bộ nhớ còn lại của RAM tính bằng paragraph}
@OK: {Cờ Carry = 0: Thành công}
end;
{Giải phóng bộ nhớ}
procedure DeAlloc (vSegment :Word); Assembler;
asm
mov ah,49h {Hàm 49h}
mov es,vSegment {vSegment: Địa chỉ đoạn của vùng nhớ cần giải phóng}
int 21h {Gọi ngắt 21h}
end;
**Alloc: allocate/allocation: cấp phát
(code demo bổ sung sau)
Bookmarks