Tập lệnh assembly của Intel 8086/8088 (Phần 4)

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.

Mới hơn Cũ hơn

Biểu mẫu liên hệ