Một số ví dụ minh họa:
Ví dụ 1: Giả sử tại địa chỉ 0100:0120 trong bộ nhớ có chứa một mảng dữ liệu, gồm 100 ô nhớ, mỗi ô là 1 word. Hãy tính tổng nội dung của các ô nhớ này, kết quả chứa trong thanh ghi Dx.
Mov Ax, 0100
Mov DS, Ax ; trỏ cặp thanh ghi DS:DI về
Mov DI, 0120 ; đầu vùng nhớ cần truy xuất (0100:0120)
;------------------------
Mov Dx, 0 ; chuẩn bị Dx để lưu tổng
Mov Cx, 100 ; lặp 100 lần vì mảng gồm 100 ô nhớ
Lap_TT:
Add Dx, DS:[DI] ; cộng thêm n/dung ô nhớ chỉ bởi DS:DI vào Dx
Add DI, 2 ; chỉ đến ô nhớ kế tiếp (vì ô nhớ word nên tăng 2)
Loop Lap_TT ; lặp lại đủ 100 lần (duyệt qua đủ 100 ô nhớ)
;-----------------------------------
Kết thúc đoạn lệnh trên tổng nội dung của 100 word nhớ bắt đầu tại địa chỉ 0100:0120 trong bộ nhớ được lưu vào thanh ghi Dx. Ở đây chúng ta bỏ qua khả năng tràn dữ liệu trong thanh ghi kết quả Dx.
Ví dụ 2: Các lệnh sau đây sẽ copy 100 word dữ liệu từ vùng nhớ bắt đầu tại địa chỉ 0100:0120 sang vùng nhớ bắt đầu tại 0100:0500:
Mov Ax, 0100
Mov DS, Ax
Mov SI, 0120 ; trỏ DS:SI về vùng nhớ nguồn 0100:0120
Mov DI, 0500 ; trỏ DS:DI về vùng nhớ địch 0100:0500
;--------------------
Mov Cx, 100
Lap_Copy:
Mov Ax, DS:[SI] ; lưu tạm nội dụng word nhớ tại DS:SI vào Ax
Mov DS:[DI], Ax ; ghi giá trị Ax và word nhớ tại DS:DI
Add SI, 2 ; đến word nhớ tiếp theo
Add DI, 2
Loop Lap_Copy
;-------------------------
Hai vùng bộ nhớ đã cho đều ở trong cùng một segment nên ở đây ta chỉ cần sử dụng một thanh ghi đoạn dữ liệu DS.
Ví dụ 3: Các lệnh sau đây sẽ tính tổng nội dung của 100 ô nhớ (100 byte nhớ) trong bộ nhớ, bắt đầu tại địa chỉ 0A00:0120. Kết quả được lưu vào word nhớ ngay trước vùng nhớ này:
Mov Ax, 0A00h
Mov ES, Ax
Mov SI, 0120h ; trỏ DS:SI về vùng nhớ nguồn 0A00:0120
Mov DI, SI ; trỏ DS:DI về vùng nhớ nguồn 0A00:0120
Sub DI,2 ; trỏ DS:DI về word nhớ trước vùng nhớ nguồn
;------------------------
Mov Cx, 100
Mov Dx, 0 ; DX chứa tổng
TTong:
Add Dx, Byte PTR ES:[SI] ; cộng n.d của byte nhớ tại ES:SI vàoDX
Inc SI ; ô nhớ byte
Loop TTong
;----------------------------------------
Mov Word PTR ES:[DI], DX
;----------------------------------------
Trong đoạn lệnh trên chúng ta sử dụng toán tử PTR để định kiểu ô nhớ cần truy xuất. Lệnh Add Dx, Byte PTR ES:[SI]: lấy nội dung của byte nhớ tại ô nhớ được chỉ bởi ES:SI cộng thêm vào thanh ghi DX. Nếu ta viết Add Dx, ES:[SI] thì hệ thống lấy giá trị cả 1 word tại ES:SI cộng thêm vào DX (vì DX là thanh ghi word (16 bít), điều này không đúng với thực tế, vì chúng ta đang cần truy xuất đến các byte nhớ. Trong trường hợp này, nếu không dùng toán tử PTR thì lệnh Add phải viết như sau: Add DL, ES:[SI], khi đó hệ thống chỉ lấy giá trị cả 1 byte tại ES:SI cộng thêm vào DL (vì DL là thanh ghi byte: 8 bít),
Ví dụ 4: Các lệnh sau đây sẽ copy toàn bộ 20 kí tự Ascii từ biến Xau1 vào biến Xau2. Giả sử Xau1 và Xau2 đã được khai báo trước như sau:
Xau1 DB ‘Khoa CNTT – DHKH Hue’
Xau2 DB 20 Dup (‘ ’)
Các lệnh:
Mov Ax, @Data
Mov DS, Ax
Lea SI, Xau1
Lea DI, Xau2
;------------------------
Mov Cx, 20
Lap_Copy:
Mov Al, Byte PTR DS:[SI]
Mov Byte PTR DS:[DI], Al
Inc SI
Dec DI
Loop Lap_Copy
;-------------------------------------
Các biến của chương trình hợp ngữ được khai báo trong đoạn Data. Hai lệnh đầu tiên ở trên có tác dụng lấy địa chỉ segment của đoạn Data đưa vào thanh ghi đoạn DS. Do đó, DS sẽ chứa địa chỉ segment của hai biến Xau1 và Xau2. Hay cụ thể: DS:SI trỏ về biến Xau1 và DS:DI trỏ về Xau2.
Ví dụ 5: Chương trình sau đây: Để in một xâu kí tự từ trong chương trình ra màn hình văn bản đơn sắc (môi trường MSDOS).
Chú ý:
- BIOS và MSDOS đã cung cấp nhiều hàm/ngắt để chương trình hợp ngữ ghi một kí tự hoặc một xâu kí tự ra màn hình, tại vị trí hiện tại của con trỏ màn hình hoặc tại một tọa độ màn hình xác định nào đó. Kỹ thuật này được gọi là kỹ thuật ghi ra màn hình gián tiếp thông qua các hàm/ngắt màn hình.
- Biết rằng, tất cả những thông tin mà chúng ta thấy được trên màn hình của một máy tính đều được lưu trữ trong bộ nhớ màn hình của máy tính đó, theo một cách nào đó. Tức là, nọi thao tác ghi/đọc trên màn hình đều phải thông qua bộ nhớ màn hình. Như vậy: Muốn ghi một xâu kí tự ra màn hình chương trình có thể ghi nó vào bộ nhớ màn hình. Muốn đọc một xâu kí tự từ màn hình chương trình có thể đọc nó từ bộ nhớ màn hình. Kỹ thuật này được gọi là kỹ thuật truy xuất trực tiếp bộ nhớ màn hình.
- Mỗi hệ điều hành, mỗi chế độ màn hình sử dụng một đoạn bộ nhớ xác định (thường là khác nhau) cho bộ nhớ màn hình. Và cách tổ chức lưu trữ thông tin trên màn hình trong bộ nhớ màn hình cũng khác nhau với các hệ điều hành, các chế độ màn hình khác nhau.
- Trên môi trường hệ điều hành MSDOS, bộ nhớ màn hình của chế độ nàm hình đơn sắc 25 dòng (0 đến 24) x 80 cột (0 đếm 79) được lưu trữ tại segment nhớ 0B800, bắt đầu tại offset 0000.
- Tổ chức lưu trữ thông tin trên màn hình trong bộ nhớ màn hình loại này như sau: Mỗi kí tự trên nàm hình chiếm 1 word trong bộ nhớ màn hình: byte thấp chứa mã ASCII của kí tự, byte cao chứa thuộc tính (màu chữ, màu nền,...) của kí tự đó. Từng dòng kí tự trên màn hình, từ trái sang phải (từ cột 0 đến cột 79), được lưu tữ lần lượt tại các offset liên tiếp nhau trong bộ nhớ màn hình: 80 kí tự của dòng 0 được lưu trữ tại 80 word đầu tiên, 80 kí tự của dòng 1được lưu trữ tại 80 word tiếp theo,... , 80 kí tự của dòng 79ược lưu trữ tại 80 word cuối cùng trong bộ nhớ nàm hình. Như vậy ta dễ dàng tính ra được offset trong bộ nhớ màn hình, tương ứng với một kí tự trên màn hình khi ta biết được tọa độ (dòng, cột) của nó. Cụ thể, offset của kí tự tạo tọa độ (Dòng, Cột) được tính theo công thức sau:
(80*(Dong - 1) + (Cot - 1))*2
- Bộ nhớ màn hình loại này có kích thước là 25 x 80 x 2 (byte) = 40000 byte.
0 Comment:
Đăng nhận xét
Thank you for your comments!