Tự học lập trình assembly - Bài 1: Bước đầu với lập trình assembly trên vi xử lý intel 8086/8088

Chú ý 2: Hợp ngữ còn cung cấp các lệnh dịch chuyển số học SAL (Shift Arithmetic Left) và SAR (Shift Arithmetic Right) . SAL tương tự hoàn toàn ShL, có thể sử dụng để thực hiện nhân 2 với các số âm. SAR tương tự ShR nhưng bít cuối cùng của [Toán hạng đích] không bị thay bằng bít 0 mà vẫn giữ nguyên giá trị cũ, có thể sử dụng để thực hiện chia 2 với các có dấu. Các lệnh dich bít, quay bít của các vi xử lý Intel 80286/80386/. cho phép viết số bít cần dịch, trong trường hợp lớn hơn một, trực tiếp trong lệnh dịch, quay mà không cần thông qua thanh ghi Cl [1 – 540].

docx113 trang | Chia sẻ: nguyenlam99 | Lượt xem: 2685 | Lượt tải: 0download
Bạn đang xem trước 20 trang tài liệu Tự học lập trình assembly - Bài 1: Bước đầu với lập trình assembly trên vi xử lý intel 8086/8088, để xem tài liệu hoàn chỉnh bạn click vào nút DOWNLOAD ở trên
  Ah, 2Bh                      ; gọi ngắt 21h với         Int           21h                             ; hàm 2Bh Hàm này trả về ngày-tháng-năm hiện tại (theo đồng hồ hệ thống trên máy tính). Cụ thể: Thanh ghi CX (1980-2099) chứa năm hiện tại, thanh ghi DH (1-12) chứa tháng hiện tại, thanh ghi DL (1-31) chứa ngày hiện tại. Đồng thời AL cho biết ngày trong tuần (0 : chủ nhật, 6 : thứ 7). Một số hàm của ngắt 21h (MSDOS) Ngắt 21h của MSDOS là ngắt thường được sử dụng nhất, nên ở đây chúng tôi chọn giới thiệu về  ngắt này, nhưng chỉ với các hàm vào/ra kí tự/xâu kí tự cơ bản. Chức năng của mỗi  ngắt, chức năng của các hàm trong một ngắt, các yêu cầu dữ liệu vào/ra của từng hàm trong mỗi ngắt,... dễ dàng tìm thấy trong các tài liệu về lập trình hệ thống. Hàm 02 của ngắt 21h: Tác dụng: In một kí tự ra màn hình. Kí tự (hoặc mã ASCII của kí tự) cần in được đặt trước trong thanh ghi DL. Kí tự ở đây có thể là kí tự thường hoặc kí tự điều khiển. Sử dụng: Vào:   Ah = 02             Dl = Ra:     Không có Ví dụ 1: Các lệnh sau đây in ra màn hình kí tự A:                     Mov          Ah, 02             Mov          Dl, ‘A’                  ;có thể viết lệnh  Mov   Dl, 41h                     Int             21h                       ; 41h là mã ASCII của kí tự A Ví dụ 2: Các lệnh sau đây in ra màn hình 10 kí tự, bắt đầu từ kí tự A:             Mov          Cx, 10             Mov          Ah, 02             Mov          Dl, ‘A’      Lap_In:             Int             21h             INC           DL             Loop         Lap_In Ví dụ 3: Các lệnh sau đây in xâu kí tự từ trong biến TieuDe ra màn hình. Giả sử rằng biến TieuDe đã được khai báo như sau:             TieuDe     DB            ‘Khoa CNTT Truong DHKH Hue’ Các lệnh:             Lea            DI, TieuDe             Mov          Cx, 25             Mov          Ah, 02      Lap_In:             Mov          Dl, Byte PTR [DI]             Int             21h             INC           DI             Loop         Lap_In             ;--------------------------- Ví dụ 4: Giả sử tại địa chỉ 0A00:0100 trong bộ nhớ có chứa một xâu kí tự ASCII, gồm 50 kí tự. Các lệnh sau đây sẽ in xâu kí tự nói trên ra màn hình.             Mov          Ax, 0A00h             Mov          ES, Ax             Mov          DI, 0100h             ;-------------------------             Mov          Cx, 50             Mov          Ah, 02       Lap_In:             Mov          Dl, Byte PTR ES:[DI]             Int             21h             INC           DI             Loop         Lap_In             ;-------------------------------------- Hàm 09 của ngắt 21h: Tác dụng: In một dãy kí tự (một xâu kí tự) ra màn hình. Địa chỉ của xâu cần in này phải được chỉ bởi cặp thanh ghi DS:DX và xâu phải được kết thúc bởi dấu $. Sử dụng: Vào:   Ah = 09             DS:DX =     Ra:     Không có Ví dụ 1: Giả sử chương trình đã khai báo biến TieuDe. Viết lệnh in nội dung của biếnTieuDe ra màn hình: -     Trong trường hợp này biến TieuDe phải được khai báo trước như sau:                      TieuDe     DB   ‘Truong DH Khoa hoc Hue$’ -     Và đoạn lệnh gồm các lệnh sau:             Mov          Ah, 09             Mov          Ax, Seg TieuDe             Mov          DS, Ax             Mov          Dx, Offset TieuDe          ; có thể dùng lệnh Lea      TieuDe             Int             21h Trong thự tế, với các chương trình hợp ngữ viết ở dạng đoạn giản đơn, thì không cần đưa địa chỉ Segment của biến cần in vào DS. Bởi vì: -     Đối với các chương trình dạng COM: -     Đối với các chương trình dạng EXE: Ví dụ 2: Giả sử biến TieuDe đã được khai báo như sau:             TieuDe     DB            ‘Khoa CNTT Truong DHKH Hue$’ Các lệnh sau chỉ in các kí tự “Truong DHKH Hue” từ biến TieuDe ra màn hình:             Mov          Ax, Segment TieuDe             Mov          DS, Ax             Mov          Dx, TieuDe             Add           Dx, 11             Mov          Ah, 09             Int             21h           Các lệnh sau chỉ in các kí tự “Khoa CNTT” từ biến TieuDe ra màn hình:             Mov          Ax, Segment TieuDe             Mov          DS, Ax             Mov          Dx, TieuDe             Mov          DI, Dx             Add           DI, 10             Mov          Byte PTR DS:[DI], ‘$’             Mov          Ah, 09             Int             21h           Ví dụ 3: Giả sử tại địa chỉ 0A00:0100 trong bộ nhớ có chứa một xâu kí tự ASCII, gồm 50 kí tự. Các lệnh sau đây sẽ in xâu kí tự nói trên ra màn hình.             Mov          Ax, 0A00h             Mov          DS, Ax             Mov          Dx, 0100h             ;-------------------------             Mov          DI, Dx             Mov          Cx, 50             Add           DI, Cx             Mov          Byte PTR DS:DX, ‘$’             ;-------------------------------------             Mov          Ah, 09             Int             21h             ;------------------- Hàm 01 của ngắt 21h: Tác dụng:Nhập một kí tự từ bàn phím vào lưu trong thanh ghi AL. Cụ thể là, AL sẽ chứa mã ASCII của kí tự ghi trên phím nhập. Sử dụng: Vào:   Ah = 01 Ra:     Al = 0: nếu phím nhập là một trong các phím chức năng             Al = Cụ thể như sau: Khi chương trình gọi ngắt 21h với hàm 01 thì màn hình sẽ xuất hiện một con trỏ nhập, để người sử dụng nhập vào một kí tự từ bàn phím. Khi đó, nếu người sử dụng gõ một trong các phím chức năng thì AL nhận được giá trị 0, nếu người sử dụng gõ một phím kí tự nào đó thì AL nhận được mã ASCII của kí tự đó. Chú ý: Hàm 08 của ngắt 21h có chức năng tương tự hàm 01 ngắt 21h nhưng kí tự trên phím gõ không xuất hiện trên màn hình, tất cả đều được xuất hiện bởi kí tự ‘*’. Ví dụ 1:             Mov          Ah, 01                  ; với hai lệnh này màn hình sẽ xuất hiện con trỏ             Int             21h                       ; nhập để người sử dụng nhập một kí tự vào AL Ví dụ 2: Các lệnh sau đây cho phép nhập một xâu kí tự, với số lượng kí tự được ấn định trước, vào biến LuuXau đã khai báo trước trong chương trình Giả sử biến LuuXau được khai báo như sau:             LuuXau         DB      30 Dup (‘ ‘) Các lệnh:             Mov          Ax, Seg LuuXau             Mov          DS, Ax             Lea            DI, LuuXau                     ;--------------------------------             Mov          Cx, 30             Mov          Ah, 01      Nhap_Xau:             Int             21h             Mov          Byte PTR DS:[DI], Al             INC           DI             Loop         Nhap_Xau             ;-------------------------------------- Trong trường hợp này chúng ta đã giả sử: Người sử dụng chỉ nhập các kí tự (gõ phím kí tự để nhập), không nhập các phím chức năng. Trong thực tế, không bao giờ chúng ta sử dụng hàm 01 ngắt 21h để nhập xâu, vì nó tồn tại hai hạn chế: không thể kết thúc nhập bằng cách gõ phím Enter; số kí tự của xâu nhập phải được ấn định trước trong chương trình. Để khắc phục, MSDOS cung cấp hàm 0Ah của ngắt 21h để hỗ trợ nhập xâu kí tự. Hàm 0Ah của ngắt 21h: Tác dụng:Nhập một xâu kí tự vào một biến đệm cho trước trong chương trình, biến này phải được chỉ bởi cặp thanh ghi DS:DX. Và biến đệm phải có dạng như sau: -         Byte 0: chứa số kí tự tối đa của xâu nhập vào -         Byte 1: chứa một trị không (= 0) -         Byte 2, byte 3, byte 4, ... chứa một trị rỗng (để trống), để chứa các kí tự sẽ được nhập vào sau này (khi chương trình thực hiện).  Để có được một biến như trên chương trình phải khai báo biến (tên biến là Xau_Nhap) như sau:             Xau_Nhap     DB      256, 0, 256 Dup (‘ ‘) Như vậy Xau_Nhap là một biến kiểu byte, gồm 258 byte. Byte đầu tiên (byte) chứa trị 256, byte 1 chứa trị 0, 256 byte tiếp theo chứa kí tự trống, được sử dụng để chứa các kí tự sẽ được nhập sau này. Xau_Nhap chứa tối đa 256 kí tự. Cũng có thể sử dụng hàm 0Ah/21h để nhập một xâu kí tự vào vùng nhớ có địa chỉ xác định trong bô nhớ. Sử dụng: Vào:  Ah = 0Ah                   DS:DX = Ra:     DS:DX không thay đổi Biến đệm bây giờ có dạng như sau: -         Byte 0: không thay đổi -         Byte 1: chứa tổng số kí tự đã được nhập vào -         Byte 2, byte 3, byte 4, ... chứa các kí tự đã được nhập vào. Ví dụ 1: Với khai báo biến đệm Xau_Nhap như trên, nếu sau này chương trình nhập vào xâu: “Tin hoc” thì: -         Byte 0: vẫn chứa số 256 -         Byte 1: chứa giá trị 7, đó chính là 7 kí tự trong xâu “Tin hoc” -         Từ byte 2 đến 8 chứa lần lượt các kí tự trong xâu “Tin hoc. Ví dụ 2: Giả sử chương trình đã khai báo xâu TieuDe như sau: TieuDe           DB      100, 0, 100 Dup (‘ ‘)             Các lệnh sau đây sử dụng hàm 0Ah/21h để nhập một xâu kí tự vào biếnTieuDe:             Mov          Ax, Seg TieuDe             Mov          Ds, Ax             Lea            Dx, TieuDe             Mov          Ah, 0Ah             Int             21h Các lệnh sau đây lấy số kí tự thực sự nhập đưa vào lưu trữ trong thanh ghi Cx:             Mov          Cx, 0             Mov          Cl, TieuDe[1]                  Các lệnh sau đây sử dụng hàm 02/21h để in xâu kí tự vừa nhập ra lại màn hình:             Lea            DI, TieuDe             Mov          Cx, 0             Mov          Cl, TieuDe[1]             Add           DI, 2             Mov          Ah, 02       Lap_In:             Mov          Dl, DS:[DI]             Int             21h             INC           DI             Loop         Lap_In      Các lệnh sau đây sử dụng hàm 09/21h để in xâu kí tự vừa nhập ra lại màn hình:             Mov          Ax, Seg TieuDe             Mov          Ds, Ax             Lea            Dx, TieuDe             Add           Dx, 2             Mov          DI, Dx             Mov          Cx, 0             Mov          Cl, TieuDe[1]             Add           DI, Cx             Mov          Byte PTR DS:[DI], ‘$’             Mov          Ah, 09h             Int             21h Ví dụ 3: Chương trình dạng COM sau đây sử dụng hàm 0Ah ngắt 21h để nhập một xâu kí tự vào biến Buff. Sau đó sử dụng hàm 09h ngắt 21h để in xâu kí tự vừa nhập ra lại màn hình.  Để đơn giản, chương trình khai báo biến Buff gồm toàn kí tự ‘$’, nhờ đó, khi dùng hàm 09h/21h để in ra chương trình không cần đưa thêm kí tự ‘$’ vào cuối xâu nhập, mà chỉ cần trỏ DS:DX về đầu vùng/xâu kí tự cần in ra.         .Model       small         .Code                     ORG       100h           Start:                         JMP    Main               TBN    DB      'Nhap vao mot xau ki tu: $'               TBX    DB      0Ah,0Dh,'Xau vua nhap: $'               Buff    DB      100,0,100 Dup ('$')                      Main          Proc                     Mov        Ah,  09h                     Lea          Dx, TBN                     Int           21h                     ;--------------------------                     Mov        Ah, 0Ah                     Lea          Dx, Buff                     Int           21h                     ;-------------------------                     Mov        Ah,  09h                     Lea          Dx, TBX                     Int           21h                     ;-------------------------                     Mov        Ah,  09h                     Lea          Dx, Buff                     Add         Dx, 2                     Int           21h                     ;-------------------------                     Int           20h           Main          Endp                     End         Start Một số ví dụ: Ví dụ 1: Giả sử hàm X của ngắt Y khi được gọi sẽ trả về trong cặp thanh ghi ES:SI địa chỉ của vùng nhớ chứa tên của nhà sản xuất (nhãn hiệu) của vi xử lý đang sử dụng trên máy tính hiện tại, tên này dài không quá 8 kí tự. Các lệnh sau đây sẽ in tên nhà sản xuất nói trên ra màn hình:                     Mov        Ah, X                          ; hàm cần gọi được đưa vào thanh ghi ah                     Int           Y                                 ; gọi ngắt Y với hàm X                     ;--------------------                             Mov        Cx, 8                           ; tên dài không quá 8 kí tự                     Mov        Ah, 02                                    ; dùng hàm 02/21h để in kí tự ra nàm hình              LapIn:                     Mov        Dl, Byte PTR ES:[SI]                     Int           21h                     INC         SI                                 ; đến kí tự tiếp theo                     Loop       LapIn                      ;------------------------------------ Ví dụ 2: Giả sử hàm X của ngắt Y khi được gọi với AL = 1 (được gọi là hàm con) sẽ trả về trong cặp thanh ghi ES:DI địa chỉ của vùng nhớ chứa ngày-tháng-năm sản xuất ROM-BIOS đang sử dụng trên máy tính hiện tại. Đồng thời hàm/ngắt này cũng cho biết số kí tự trong xâu ngày-tháng-năm trong thanh ghi BX. Các lệnh sau đây sẽ in xâu ngày-tháng-năm nói trên ra màn hình:                     Mov        Ah, X                          ; hàm cần gọi được đưa vào thanh ghi ah                     Mov        Al, 1                            ; gọi hàm X với Al = 1                     Int           Y                                 ; gọi ngắt Y với hàm X                     ;--------------------                     Mov        Cx, Bx                        ; đưa số kí tự của xâu ngày-tháng-nămvào Cx                     Mov        Ah, 02                                    ; dùng hàm 02/21h để in kí tự ra nàm hình              LapIn:                     Mov        Dl, Byte PTR ES:[DI]                     Int           21h                     INC         DI                                ; đến kí tự tiếp theo                     Loop       LapIn                      ;------------------------------------- Ví dụ 3: Hàm 39h của ngắt 21h được sử dụng để tạo thư mục con trên đĩa. Hàm này quy định: DS:DX chứa xâu tên thư mục cần tạo, bao gồm cả đường dẫntìm đến thư mục này, xâu này kết thúc bởi trị 0. Nếu việc tạo không thành công thì Cf = 1, khi đó thanh ghi Ax sẽ chứa mã lỗi. Các lệnh sau đây sẽ tạo ra thư mục con BTCB trong thư mục ASSEM trên thư mục gốc ổ đĩa D. Chương trình phải khai báo biến TenTM, chứa xâu tên thư mục cần tạo như sau:             TenTM           DB      ‘D:\ASSEM\BTCB’,0 Các lệnh:             Mov    Ax, Seg TenTM             Mov    DS, Ax             Mov    Dx, Offset TenTM             Mov    Ah, 39h             Int       21h                ;-------------------------             Jc        TB_Loi                                   ; nếu CF = 1 thì việc tạo bị lỗi             Jmp     KetThuc        TB_Loi:         KetThuc:             ...             ;---------------------------------------------------- Tự học lập trình Assembly - Bài 5: Sử dụng Interrupt trong chương trình assembly (2) Thứ Ba, 03/09/2013 16:05 MỘT SỐ VÍ DỤ Ví dụ 1: Giả sử hàm X của ngắt Y khi được gọi sẽ trả về trong cặp thanh ghi ES:SI địa chỉ của vùng nhớ chứa tên của nhà sản xuất (nhãn hiệu) của vi xử lý đang sử dụng trên máy tính hiện tại, tên này dài không quá 8 kí tự. Các lệnh sau đây sẽ in tên nhà sản xuất nói trên ra màn hình:                     Mov        Ah, X                             ; hàm cần gọi được đưa vào thanh ghi ah                     Int           Y                                  ; gọi ngắt Y với hàm X                     ;--------------------                             Mov        Cx, 8                              ; tên dài không quá 8 kí tự                     Mov        Ah, 02                            ; dùng hàm 02/21h để in kí tự ra nàm hình              LapIn:                     Mov        Dl, Byte PTR ES:[SI]                     Int           21h                     INC         SI                                 ; đến kí tự tiếp theo                     Loop       LapIn                      ;------------------------------------ Ví dụ 2: Giả sử hàm X của ngắt Y khi được gọi với AL = 1 (được gọi là hàm con) sẽ trả về trong cặp thanh ghi ES:DI địa chỉ của vùng nhớ chứa ngày-tháng-năm sản xuất ROM-BIOS đang sử dụng trên máy tính hiện tại. Đồng thời hàm/ngắt này cũng cho biết số kí tự trong xâu ngày-tháng-năm trong thanh ghi BX. Các lệnh sau đây sẽ in xâu ngày-tháng-năm nói trên ra màn hình:                     Mov        Ah, X                            ; hàm cần gọi được đưa vào thanh ghi ah                     Mov        Al, 1                             ; gọi hàm X với Al = 1                     Int           Y                                 ; gọi ngắt Y với hàm X                     ;--------------------                     Mov        Cx, Bx                          ; đưa số kí tự của xâu ngày-tháng-nămvào Cx                     Mov        Ah, 02                          ; dùng hàm 02/21h để in kí tự ra nàm hình              LapIn:                     Mov        Dl, Byte PTR ES:[DI]                     Int           21h                     INC         DI                                ; đến kí tự tiếp theo                     Loop       LapIn                      ;------------------------------------- Ví dụ 3: Hàm 39h của ngắt 21h được sử dụng để tạo thư mục con trên đĩa. Hàm này quy định: DS:DX chứa xâu tên thư mục cần tạo, bao gồm cả đường dẫntìm đến thư mục này, xâu này kết thúc bởi trị 0. Nếu việc tạo không thành công thì Cf = 1, khi đó thanh ghi Ax sẽ chứa mã lỗi. Các lệnh sau đây sẽ tạo ra thư mục con BTCB trong thư mục ASSEM trên thư mục gốc ổ đĩa D. Chương trình phải khai báo biến TenTM, chứa xâu tên thư mục cần tạo như sau:             TenTM           DB      ‘D:\ASSEM\BTCB’,0 Các lệnh:             Mov    Ax, Seg TenTM             Mov    DS, Ax             Mov    Dx, Offset TenTM             Mov    Ah, 39h             Int       21h                ;-------------------------             Jc        TB_Loi                                   ; nếu CF = 1 thì việc tạo bị lỗi             Jmp     KetThuc        TB_Loi:         KetThuc:             ...             ;----------------------------------------------------     Ví dụ 4: Sau đây là chương trình dạng COM: In ra tất cả (256) các kí tự có trong bảng mã ASCII: .Model       Small .Code       ORG       100h           Start:                     Jmp         Main     TB       DB    'Noi dung Bang ma ASCII:',0Ah,0Dh,'$'          Main           Proc                     Mov        Ah, 09h                     Lea          Dx, TB                     Int           21h                     ;--------------------------                     Mov        Cx, 256                     Mov        Ah, 02                     Mov        Dl, 0             LapIn:                     Int           21h                     ;-----------------                     Mov        Bl, Dl                     Mov        Dl, ' '                     Int           21h                     Mov        Dl, Bl                     ;-----------------                     INC         Dl                     Loop       LapIn                     ;-------------------------                     Int           20h     Main        Endp                     End         Start    Ví dụ 5.1: Sau đây là chương trình dạng COM: Nhập vào một xâu kí tự bất kỳ. Sau đó in ra lại chính xâu kí tự vừa được nhập vào nhập. Sử dụng hàm 09/21h để in ra. .Model       Small .Code                     ORG       100h     Start:                         JMP    Main               TBN                DB    'Nhap vao mot xau ki tu: $'               TBX                DB    0Ah,0Dh,'Xau vua nhap: $'               Buff                DB    100,0,100 Dup (' ')      Main           Proc                     Mov        Ah,  09h                     Lea          Dx, TBN                     Int           21h                     ;--------------------------                     Mov        Ah, 0Ah                     Lea          Dx, Buff                     Int           21h                     ;-------------------------                     Mov        Cx, 0                     Mov        Cl,  Buff[1]                     Add         Dx, 2                     Mov        DI, Dx                     Add         DI, Cx                     Mov        Byte PTR [DI], ‘$’                     ;-------------------------                     Mov        Ah,  09h                     Lea          Dx, TBX                     Int           21h                     ;-------------------------                     Mov        Ah,  09h                     Lea          Dx, Buff                     Add         Dx, 2                     Int           21h                     ;-------------------------                     Int           20h      Main           Endp                     End         Start Ví dụ 5.2: Sau đây là chương trình dạng EXE: Nhập vào một xâu kí tự bất kỳ. Sau đó in ra lại chính xâu kí tự vừa được nhập vào nhập. Sử dụng hàm 02/21h để in ra. .Model       Small .Stack        100h .Data               TBN                DB    'Nhap vao mot xau ki tu: $'               TBX                DB    0Ah,0Dh,'Xau vua nhap: $'               Buff                DB    100,0,100 Dup (' ')   .Code           Main           Proc                     Mov        Ax,@Data                     Mov        DS, Ax                     ;-------------------------                     Mov        Ah,  09h                     Lea          Dx, TBN                     Int           21h                     ;--------------------------                     Mov        Ah, 0Ah                     Lea          Dx, Buff                     Int           21h                     ;-------------------------                     Mov        Cx, 0                     Mov        Cl,  Buff[1]                     Add         Dx, 2                     Mov        DI, Dx                     ;--------------------------                     Mov        Ah,  09h                     Lea          Dx, TBX                     Int           21h                     ;-------------------------                     Mov        Ah, 2        Lap_In:                                               Mov        Dl, [DI]                     Int           21h                     INC         DI                     Loop       Lap_In                     ;-------------------------                     Mov        Ah, 4Ch                     Int           21h    Main           Endp             End     Ví dụ 6: Sau đây là chương trình dạng COM: Nhập vào một kí tự thường, chương trình sẽ in ra kí tự in hoa tương ứng. .Model       Small .Code             ORG   100h Start:             Jmp     Main               TB1                 DB    'Nhap vao mot ki tu thuong: $'                     TB2                 DB    0Ah,0Dh,'Ki tu hoa tuong ung: $'  Main           Proc                     Mov        Ah, 09h                     Lea          Dx, TB1                     Int           21h                     ;----------------------                     Mov        Ah, 01                     Int           21h                     Mov        Bl, Al                     ;-----------------------                     Mov        Ah, 09h                     Lea          Dx, TB2                     Int           21h                     ;----------------------                     Mov        Ah, 02                     Mov        Dl, Bl                     Sub         Dl, 20h                     Int           21h                     ;-------------------------                     Int           20h  Main           Endp          End        Start    Ví dụ 7: Sau đây là chương trình dạng COM: Nhập vào một xâu kí tự sau đó in ra lại xâu đã nhập theo thứ tự đảo ngược. .Model       Small .Code             ORG   100h Start:             JMP    Main               TBN                DB    'Nhap vao mot xau ki tu: $'               TBX                DB    0Ah,0Dh,'Xau vua nhap: $'               Buff                DB    100,0,100 Dup (' ')    Main           Proc                     Mov        Ah,  09h                     Lea          Dx, TBN                     Int           21h                     ;--------------------------                     Mov        Ah, 0Ah                     Lea          Dx, Buff                     Int           21h                     ;-------------------------                     Mov        Cx, 0                     Mov        Cl,  Buff[1]                     ;---------------------------                     Mov        Ah,  09h                     Lea          Dx, TBX                     Int           21h                     ;-------------------------                     Lea          Dx, Buff                     Add         Dx, 2                     Mov        DI, Dx                     Add         DI, Cx                     Dec         DI                     Mov        Ah, 02         Lap_In_Nguoc:                     Mov        Dl, [DI]                     Int           21h                     DEC        DI                     Loop       Lap_In_Nguoc                     ;--------------------------------                     Int           20h  Main           Endp             End     Start Ví dụ 8:,Sau đây là chương trình dạng COM: Nhập vào hai số (số thứ nhất: nhỏ hơn 5; số thứ hai: nhỏ hơn hoặc bằng 5), sau đó in ra tổng của hai số vừa nhập. .Model       Small .Code         ORG       100h Start:         Jmp         Main               TBN1              DB        'Nhap so hang thu nhat (nho hon 5): $'               TBN2              DB        0Ah,0Dh,'Nhap so hang thu hai (nho hon bang 5): $'               TBX                DB        0Ah,0Dh,'Tong cua hai so la: $'  Main           Proc         Mov        Ah, 09h                     Lea          Dx, TBN1         Int           21h         Mov        Ah, 01         Int           21h         Mov        Bl, Al         Sub         Bl, 30h         ;-------------------------         Mov        Ah, 09h         Lea          Dx, TBN2         Int           21h         Mov        Ah, 01         Int           21h         Sub         Al, 30h         Add         Bl, Al         ;-------------------------         Mov        Ah, 09h         Lea          Dx, TBX         Int           21h                                     Mov        Ah, 02         Mov        Dl, Bl         Add         Dl, 30h         Int           21h         ;------------------------         Int           20 Main           Endp          End              Start           Tự học lập trình assembly - Bài 6: Tập lệnh assembly của Intel 8088/8086 - Tiếp theo (1) Thứ Sáu, 25/10/2013 15:44 TẬP LỆNH ASSEMBLY CỦA INTEL 8088/8086 - (Tiếp theo) Lệnh so sánh: Cú pháp:      Cmp     [Toán hạng đích], [Toán hạng nguồn] Trong đó: [Toán hạng đích], [Toán hạng nguồn] có thể là hằng, biến, thanh ghi hay ô nhớ. [Toán hạng đích] không thể là hằng số. [Toán hạng đích] và [Toán hạng nguồn] không thể đồng thời là ô nhớ. Tác dụng: Lệnh Cmp (Compare) được sử dụng để so sánh giá trị/nội dung của [Toán hạng đích] so với [Toán hạng nguồn]. Tương tự như lệnh Sub, nó lấy [Toán hạng đích] trừ đi [Toán hạng nguồn] nhưng kết quả không làm thay đổi [Toán hạng đích] mà chỉ làm thay đổi giá trị của một số cờ hiệu: CF, ZF, OF,... Kết quả so sánh của lệnh Cmp là: [Toán hạng đích] > [Toán hạng nguồn]; [Toán hạng đích] ≥[Toán hạng nguồn]; [Toán hạng đích] < [Toán hạng nguồn]; [Toán hạng đích] ≤[Toán hạng nguồn]; [Toán hạng đích] = [Toán hạng nguồn]; [Toán hạng đích] ≠ [Toán hạng nguồn];... mỗi kết quả sẽ tác động (0 →1, 1→0) đến một cờ tương ứng cụ thể nào đó. Do đó, để biết được kết quả so sánh chương trình phải sử dụng các lệnh kiểm tra cờ (đó là cá lệnh nhảy), và chúng phải được đặt ngay sau lệnh so sánh. Như vậy lệnh Cmp sẽ không có ý nghĩa khi nó đứng độc lập. Có thể nói ngược lại, lệnh Cmp được sử dụng để cung cấp điều kiện nhảy (thay đổi giá trị các cờ) cho các lệnh nhảy có điều kiện.     Ví dụ 1: Cmp        Ax, Bx                        ; so sánh giá tị thanh ghi Ax với Bx Cmp        Ax, 20                        ; so sánh giá trị thanh ghi Ax với 20 Cmp        Ax, [SI]                      ; so sánh Ax với nội dung ô nhớ được chỉ bởi SI Ví dụ 2:          Cmp        Al, ‘A’                        ; so sánh giá trị thanh ghi Al với ‘A’ Cmp        Al, Var1                     ; so sánh giá trị thanh ghi Al với giá trị biến Var1 Tất cả cá lệnh Cmp ở trên điều không có ý nghĩa, vì nó không cho biết kết quả so sánh một cách trực tiếp mà phải ánh thông qua các cờ. Lệnh Cmp không thể sử dụng để so sánh hoặc kiểm tra giá trị của các cờ. Các lệnh nhảy Lệnh nhảy không điều kiện: Cú pháp:   Jmp        Trong đó:  có thể là nhãn của một lệnh, tên của một thủ tục hoặc có thể là một thanh ghi, một ô nhớ (đã được định nghĩa) nào đó. cũng có thể là một biến nào đó, giá trị của nó thường là địa chỉ của một ô nhớ trong đoạn Code. Tác dụng: Khi gặp lệnh này chương trình chuyển điều khiển (nhảy đến) đến thực hiện lệnh sau mà không phụ thuộc vào bất kỳ điều kiện nào. Cơ chế thực hiện của lệnh Jmp là thay đổi nội dung của cặp thanh ghi con trỏ lệnh CS:IP. CS:IP mới sẽ là địa chỉ của lệnh sau trong bộ nhớ. Lệnh Jmp có 3 dạng: Short, Near và Far. Đối với dạng Short và Far thì chỉ có thanh ghi IP bị thay đổi khi lệnh thực hiện, ngược lại, với dạng Far, khi lệnh thực hiện thì cả thanh ghi IP và thanh ghi đoạn CS đều bị thay đổi. Hay nói cách khác: Đối với dạng Short và Near thì lệnh Jmp và phải nằm trong cùng Segment nhớ, ngược lại, với dạng Far thì lệnh Jmp và có thể nằm ở các Segment nhớ khác nhau. Ví dụ 1:                     Start:                           Jmp               Main                           TieuDe         DB      ‘Khoa CNTT – DHHH’                     Main       Proc                   ..................                     Main       Endp                     End            Start Ví dụ 2: Jmp         short   Main Jmp         Ax Jmp         word      PTR     [BX] Jmp         dword    PTR     [BX] Ví dụ 3:         Reset      DD      5BE000F0h         Jmp         Reset  Ví dụ 4:                     Mov        Ax, 15                     Mov        Bx, 20                     Jmp         TTong                     Add         Ax, Bx               TTong:                             Sub         Ax, Bx                     Mov        Cx, Ax Kết thúc đoạn lệnh trên Cx = Ax = -5, vì lệnh Add      Ax, Bx không được thực hiện. Khi gặp lệnh Jmp      TTong chương trình nhảy đến thục hiện lệnh sau nhãn TTong, đó chính là lệnh Sub      Ax, Bx.                                    Lệnh nhảy có điều kiện:                    Cú pháp chung:                   Trong đó: : Tương tự như lệnh Jmp. Tác dụng: Khi gặp một lệnh nhảy có điều kiện, đầu tiên chương trình sẽ kiểm tra điều kiện nhảy của nó, nếu thỏa mãn thì sẽ nhảy đến thực hiện lệnh ở , nếu không thì bỏ qua không thực hiện lệnh nhảy này. Điều kiện nhảy của các lệnh nhảy này chính là sự thay đổi giá trị của các cờ hiệu, do đó để tạo điều kiện nhảy cho một lệnh nhảy xác định thì chương trình phải làm thay đổi giá trị của cờ hiệu tương ứng với nó. Chương trình thường dùng các lệnh địch bít, quay bít, so sánh,... để làm thay đổi giá trị các cờ hiệu để tạo điều kiện nhảy cho các lệnh nhay. Cách đơn giản nhất là sử dụng lệnh Cmp ngay trước lệnh nhảy.    Sau đây là các lệnh nhảy có điều kiện với dữ liệu có dấu: Lệnh JG:             Nhảy nếu [Đích] > [Nguồn] ; (SF = 0F và ZF = 0) Lệnh JL:             Nhảy nếu [Đích] 0F) Lệnh JGE:          Nhảy nếu [Đích] ≥[Nguồn] ; (SF = 0F) Lệnh JLE:           Nhảy nếu [Đích] ≤[Nguồn] ; (CF 0F và ZF = 1)    ... Trong đó: [Đích] và [Nguồn] chính là hai toán hạng: [Toán hạng đích] và [Toán hạng nguồn] trong lệnh Cmp đứng ngay trước lệnh nhảy. Tức là, chương trình sử dụng lệnh Cmp để tạo điều kiện nhảy cho các lệnh này. Cụ thể: lệnh nhảy có thực hiện được hay không (có chuyển điều khiển đến hay không) phụ thuộc vào giá trị của [Đích] và [Nguồn] trong lệnh Cmp đứng ngay trước nó. Với việc sử dụng lệnh Cmp để tạo điều kiện nhảy cho các lệnh nhảy thì ta không cần quan tâm đến các cờ điều kiện nhảy của chúng. Sau đây là các lệnh nhảy có điều kiện với dữ liệu không dấu: Lệnh JA:            Nhảy nếu [Đích] > [Nguồn] ; (CF = 0 và ZF = 0) Lệnh JB:              Nhảy nếu [Đích] < [Nguồn] ; (CF = 0) Lệnh JNA:          Nhảy nếu [Đích] không lớn hơn [Nguồn]; (CF =1 or ZF =1) Lệnh JNB:           Nhảy nếu [Đích] không nhỏ hơn [Nguồn] ; (CF = 0) Các lệnh nhảy với dữ liệu có dấu có thể áp dụng với các dữ liệu không dấu. Sau đây là các lệnh nhảy có điều kiện dùng chung: Lệnh JC:              Nhảy nếu cờ CF = 1 Lệnh JNC:           Nhảy nếu cờ CF = 0 Lệnh JZ:              Nhảy nếu cờ ZF = 1 Lệnh JNZ:           Nhảy nếu cờ ZF = 0 Lệnh JE:              Nhảy nếu [Đích] = [Nguồn]; Tương tự JZ; (ZF = 1) Lệnh JNE:           Nhảy nếu [Đích] ≠[Nguồn]; Tương tự JNZ; (ZF = 0) ... [2 - 150] Với các lệnh này, chương trình thường sử dụng các lệnh dịch bít hoặc lệnh quay bít để tạo điều kiện nhảy nó. Ví dụ 1a: Dãy lệnh sau đây thực hiện việc gán giá trị cho thanh ghi Cx dựa vào giá trị của thanh ghi Ax và Dx:                     Mov        Ax, 12                     Mov        Dx, 25                     ;-------------------                     Cmp        Ax, Dx                        ; Ax ? Bx                     Jg            Nhan1                       ; nếu Ax > Dx                     Jle           Nhan2                                     Nhan1:                     Mov        Cx, Ax                     Jmp         Tiep_Tuc                                Nhan2:                                                             Mov        Cx, Dx                     Jmp        Tiep_Tuc                                   Tiep_Tuc:                     Mov        Bx, Cx                     ;------------------------ Có thể thấy, ở đây không cần dùng lệnh Jle    Nhan2, vì nếu Ax không lớn hơn Dx thì chắc chẵn nó sẽ nhỏ hơn hoặc bằng Dx. Ngoài ra cũng không cần dùng lệnh Jmp     Tiep_Tuc sau nhãn Nhan2, vì việc chuyển đến lệnh sau nhãn Tiep_Tuc ở đây là tất nhiên. Vì thế đoạn lệnh trên có thể được viết rút gọn như trong Ví dụ 1b sau đây.   Ví dụ 1b: Dãy lệnh sau đây là trường hợp rút gọn của dãy lệnh trên:                     Mov        Ax, 12                     Mov        Dx, 25                     ;------------------                     Cmp        Ax, Dx                     Jg            Nhan1                       ; nếu Ax > Dx                     Mov        Cx, Dx                        ; khi Ax ≤Dx                     Jmp        Tiep_Tuc                Nhan1:                     Mov        Cx, Ax                        ; khi Ax > Dx                 Tiep_Tuc:                     Mov        Bx, Cx                     ;------------------------ Trong cả hai ví dụ trên: khi kết thúc, Bx =  Cx = Dx = 25. Nhưng nếu cho Ax = 120 (Ax > Bx) thì Bx = Cx = Ax = 120. Ví dụ 2: Giả sử tại địa chỉ 0A000:0100 trong bộ nhớ có chứa một mảng các số nguyên kiểu byte, gồm 100 phần tử (100 byte). Các lệnh sau đây tính tổng của các phần tử trong mảng này mà giá trị của nó lớn hơn 123. Kết quả chứa ở thanh ghi Dx.                     Mov        Ax, 0A000h                     Mov        DS, Ax                                               Mov        DI, 0100h                                             ;------------------------                     Mov        Dx, 0                                                      Mov        Cx, 100                                              Lap_TT:                     Mov        Al, Byte PTR DS:[DI]                             Cmp        Al, 123                                                  Jle           Tiep_Tuc                                               Add         Dx, Al                                      Tiep_Tuc:                     INC         DI                                ; trỏ đến phần tử kế tiếp                     Loop       Lap_TT                      ; lặp lại: kiển tra và tính tổng                     ;--------------------- Ví dụ 3: Giả sử tại địa chỉ 0C000:00120 trong bộ nhớ có chứa một xâu kí tự, xâu này được kết thúc bởi giá trị 0 (số 0). Các lệnh sau đây sẽ đếm xem xâu nói trên gồm bao nhiêu kí tự. Kết quả ghi vào ô nhớ ngay trước vùng nhớ chứa xâu này:                     Mov        Ax, 0C000h                     Mov        ES, Ax                                                   Mov        DI, 00120h                                Mov        SI, DI                     ;------------------------                     Mov        Dx, 0                                                Lap_Dem:                     Mov        Al, Byte PTR ES:[DI]                           Cmp        Al, 0                                        ; so sánh Al với 0                     Je            KetThuc                                 ; nếu Al = 0: đã đến cuối xâu                     INC         Dx                                           ; khi Al 0: đếm                     INC         DI                                            ; trỏ đến kí tự kế tiếp                     Jmp         Lap_Dem                            ; lặp lại: kiển tra và đếm               KetThuc:                                      Mov        Byte PTR DS:[SI - 1], Dx                     ;------------------------------------------ Ví dụ 4: Các lệnh sau đây in nội dung bản bản ASCII ra màn hình, nhưng không in ra các kí tự có mã 07h, 0Ah, 0Dh.                     Mov        Cx, 256                     Mov        Ah, 02                                       Mov        Dl, 0                         Lap_In:                     Cmp        Dl, 07h                         Je            TTuc                                 Cmp        Dl, 0Ah                              Je            TTuc                     Cmp        Dl, 0Dh                     Je            TTuc                     Int           21h                             TTuc:                     INC         DL                     Loop       Lap_In                     ;----------------------- Ví dụ 5: Các lệnh sau đây cho phép nhập một xâu kí tự bất kỳ, dài không quá 200 kí tự, từ bàn phím vào biến XauNhap. Sau đó copy các kí tự là chữ cái in hoa trong xâu vừa nhập vào biến XauHoa.               Trước hết chương trình phải khai báo các biến:                     XauNhap           DB      200, 0, 200 Dup (‘ ’)                                XauHoa             DB      200 Dup (‘ ’)               Các lệnh:                     Mov        Ax, Seg XauNhap                     Mov        DS, XauNhap                     Mov        Dx, Offset XauNhap                     Mov        Ax, Seg XauHoa                     Mov        ES, XauHoa                     Mov        DI, Offset XauHoa                     ;----------------------------------                     Mov        Ah, 0Ah                                        Int           21h                     ;---------------------                     Mov        Cx, 0                     Mov        Cl, XauNhap[1]                          Mov        SI, Dx                                      Add         SI, 2                                          ;------------------------------               Lap_Copy:                     Mov        Al, DS:[SI]                                   Cmp        Al, ‘A’                                    Jl             TTuc                                          Cmp        Al, ‘Z’                                   Jg            TTuc                                          Mov        ES:[DI], Al                               INC         DI                                     TTuc:                     INC         SI                                 ;                     Loop       Lap_Copy                     ;----------------------- Nên nhớ, trong bảng mã ASCII các kí tự là chữ cái in hoa nằm ở những vị trí liên tiếp nhau: A, B, C, ..., Z, chúng có mã lần lượt là 65, 66, 67, ..., 90. Ví dụ 6: Giả sử tại địa chỉ 0F000:FFFE trong bộ nhớ ROM-BIOS có chứa một byte dữ liệu. Byte này cho biết loại của máy tính đang sử dụng. Cụ thể, nếu byte này: chứa trị 0FBh: máy PC/XT; chứa trị 0FCh: máy PC/AT; chứa trị 0FFh: máy PC classic;... Các lệnh sau đây cho biết máy tính đang sử dụng thuộc loại máy nào: Trước hết chương trình phải khai báo các biến trả lời:         TB1         DB      ‘Day la may PC/XT.$’           TB2         DB      ‘Day la may PC/AT.$’         TB3         DB      ‘Day la may PC classic.$’ Các lệnh:         Mov        Ax, 0F000h         Mov        ES, Ax         Mov        SI, 0FFFEh         ;------------------------         Mov        Al, Byte PTR ES:[SI]         Cmp        Al, 0FBh         Je            TraLoi1         Cmp        Al, 0Fch         Je            TraLoi2         Cmp        Al, 0Ffh         Je            TraLoi3         ... TraLoi1:         Mov        Ax, Seg TB1         Mov        DS, Ax         Lea          Dx, Offset TB1         Mov        Ah, 09         Int           21h         Jmp         KetThuc TraLoi2:         Mov        Ax, Seg TB2         Mov        DS, Ax         Lea          Dx, Offset TB2         Mov        Ah, 09         Int           21h         Jmp         KetThuc TraLoi1:         Mov        Ax, Seg TB3         Mov        DS, Ax         Lea          Dx, Offset TB3         Mov        Ah, 09         Int           21h         Jmp         KetThuc         ..... KetThuc:         Mov        Ah, 4Ch         Int           21h         ;---------------------- Có thể nói, ví dụ trên đây là một thao tác điển hình trong lập trình hợp ngữ. Nó cũng cho thấy chức năng và thế mạnh của ngôn ngữ này. Đây cũng là mục tiêu mà người lập trình hợp ngữ nhắm tới. Việc truy xuất vào các vùng nhớ dữ liệu để lấy các byte/word thông tin cấu hình hệ thống là một yêu cầu cơ bản với các ngôn ngữ lập trình cấp thấp, và nó được thực hiện một cách khá đơn giản trong ngôn ngữ hợp ngữ. Ví dụ trên đây cũng cho thấy nguyên tắc để làm việc này. Các lệnh Dịch bít – Quay bít (còn tiếp) Tự học lập trình assembly - Bài 6: Tập lệnh assembly của Intel 8088/8086 - Tiếp theo (2) Thứ Sáu, 25/10/2013 16:08 TẬP LỆNH ASSEMBLY CỦA INTEL 8088/8086 - (Tiếp theo) Các lệnh Dịch bít – Quay bít Các lệnh dịch bít là các lệnh làm cho các bít trong một thanh ghi bị dịch về bên trái (lệnh ShR) hoặc về bên phải (lệnh ShL) một hoặc nhiều bít. Lệnh quay bít làm cho các bít trong một thanh ghi quay theo “chiều trái” hoặc theo “chiều phải” một hoặc nhiều bít. Thông thường các bít được dịch hay được quay đều lần lượt được đưa qua cờ CF. Do đo, các lệnh dịch bít và quay bít thường được sử dụng để kiểm tra giá trị bít (= 0 hay = 1) của các bít trong thanh ghi. Hợp ngữ cung cấp hai dạng lệnh quay bít, quay không qua cờ CF (lệnh RoL và RoL) và quay có qua cờ CF (lệnh RcL và RcR). Cú pháp: Shr      [Toán hạng đích], Shl      [Toán hạng đích], Rcr     [Toán hạng đích], Rcl      [Toán hạng đích], Trong đó: [Toán hạng đích] là một thanh ghi 8 bít hoặc 16 bít. là số bít cần dịch, nếu = 1 thì chỉ định trực tiếp trong câu lệnh, nếu lớn hơn 1 phải chỉ định thông qua thanh ghi CL. Tác dụng: Lệnh ShR (Shift Logical Right): Dịch chuyển các bít trong thanh ghi [Toán hạng đích] sang phải một hoặc nhiều bít. Các bít được dịch lần lượt được đưa vào cờ CF, cờ CF sẽ chứa bít của lần dịch cuối cùng. Sau khi dịch các bít bị khuyết (ở bên đối diện) sẽ được thay bằng các bít có trị 0. Tức là, với thanh ghi 8 bít thì sau 8 lần dịch nó sẽ nhận được một dãy 8 bít = 0, tương tự với thanh ghi 16 bít thì sau 16 lần dịch nó sẽ nhận được một dãy 16 bít = 0. Nếu thanh ghi AL = 01001001 thì sau khi bị dịch về bên trái 2 bít nó sẽ như sau: AL = 00100100, khi đó CF = 1. Lệnh ShL (Shift Logical Left): Tương tự như lệnh ShR nhưng các bít được dịch về phía bên trái. Lệnh RCR (Rotate through Carry Right): Tương tự như lệnh ShR, nhưng bít được dịch sẽ được đặt vào lại bít bị khuyết ở bên đối diện. Tức là, với thanh ghi 8 bít thì sau 8 lần dịch nó sẽ nhận lại dãy bít ban đầu, tương tự với thanh ghi 16 bít thì sau 16 lần dịch nó sẽ nhận lại dãy bít ban đầu. Nếu thanh ghi AL = 01001001 thì sau khi bị quay về bên trái 2 bít nó sẽ như sau: AL = 00100101, khi đó CF = 1. Lệnh RCL (Rotate through Carry Left): Tương tự như lệnh RCR nhưng các bít được quay về phía bên trái. Ví dụ 1: Shr          Al, 1 Mov        Cl, 2              Shr          Al, CL              Shl          Bl, CL               Rcl          AL, CL Rcr          Dl, 1                Ví dụ 2: Các lệnh sau đây đếm số bít bằng 1 trong thanh ghi BX, kết quả chứa ở thanh ghi Al mà không làm thay đổi giá trị của nó:         Mov        Al, 0            Mov        Cx, 16    DemBit1:         Rol          Bx, 1         Jnc          TiepTuc         Inc           Al    TiepTuc:         Loop       DemBit1   ;--------------------------      Ví dụ 3: Các lệnh sau đây đếm số bít giống nhau (tương ứng) giữa hai thanh ghi Ax và Bx. Kết quả chứa trong biến Dem (Dem    DB      0):         Mov        Dem, 0          Xor         Ax, Bx         Mov        Cx, 16    KTra:         Shl          Ax, 1         Jnc          Bit_0                  Jmp         TiepTuc   Bit_0:         Inc           Dem   TiepTuc:         Loop       KTra     ;------------------------ Ví dụ 4: Các lệnh sau đây in nội dung của thanh ghi BX ra màn hình dưới dạng sô nhị phân:                     Mov        Cx, 16             ; lặp in đủ 16 bít                     Mov        Ah, 02             ; in ra kí tự với hàm 02/21h             In_NhiPhan:                     Shl          Bx, 1       ; dịch trái để bít cần in rơi vào cờ CF                     Jc            In_1       ; lệnh JC nhảy khi cờ CF = 1                     Mov        Dl, ‘0’      ; CF = 0 tức là bít cần in có trị = 0, nên in ra kí tự ‘0’                     Int           21h                     Jmp         In_Tiep                      In_1:                     Mov        Dl, ‘1’                          Int           21h             In_Tiep:                     Loop       In_NhiPhan                     ;------------------------- Ví dụ 5: Các lệnh sau đây nhập một số nhị phân từ bàn phím đưa vào lưu trữ trong thanh ghi BX:         Mov        Bx, 0         Mov        Cx, 0         Mov        Ax, 0         Mov        Ah, 1   Nhap:         Int           21h         Cmp        Al, 0Dh             ; nếu nhập Enter thì kết thúc         Je            KetThuc         ;--------------------         Cmp        Al, ‘1’         Je            Them_Bit         Cmp        Al, ‘0’         Je            Them_Bit         ;----------------------         Mov        Ah,09         Mov        Dx, Seg TB    ; Biến TB được khai báo như sau:         Mov        DS, Dx            ; TB     DB    ‘Ban phai nhap 0/1 hoac Enter$’         Mov        Dx, Offset TB         Int           21h         Jmp         Nhap   Them_Bit:         Sub         Al, 30h                       ; có thẻ sử dụng lệnh And     Al, 0Fh         Shl          Bx, 1         Or            Bx, Al         Inc           Cx         Cmp        Cx, 17         Jne          Nhap   KetThuc:         Mov        4Ch         Int           21h ;---------------------------------- Ví dụ 6: Giả sử tại địa chỉ 0B000:0010 trong bộ nhớ có chứa một byte dữ liệu, nó cho biết một số thông tin liên quan đến cấu hình hệ thống. Byte 3 cho biết máy tính hiện tại có (byte 3 = 1) hay không có (byte 3 = 0) cổng cắm USB. Các lệnh sau đây cho biết máy tính hiện tại (máy thực hiện đoạn lệnh) có hay không có cổng cắm USB. Kết quả được thông báo thông qua thanh ghi Cx: Cx = 0: không có cổng cắm USB; Cx = 0FFFFh: có cổng cắm USB.         Mov        Ax, 0B000h         Mov        DS, Ax         Mov        DI, 0010h         ;-------------------------         Mov        Ax, 0         Mov        Al, byte PTR DS:[DI]                              ;-------------------------------------         Mov        Cl, 4         Shr          Al, Cl         Jc            CoUSB                                   ; co cong USB         Mov        Cx, 0                                       ; khong co cong USB         Jmp         KetThuc   CoUSB:         Mov        Cx, 0FFFFh   KetThuc:         ...                     ;------------------------- Trong thực tế, kết quả kiểm tra này thường được trả lời thông qua ngay chính cờ CF. CF = 0: không có cổng USB, CF = 1: có cổng USB. Chú ý 1: Có thể sử dụng lệnh dịch bít ShR/ShL để thực hiện phép chia/phép nhân giá trị của một thanh ghi (chứa số nguyên không dấu) với một số là bội số của 2. Ví dụ: Hai lệnh sau đây sẽ dịch AL sang trái 3 bít, tức là nhân AL với 8:         Mov        Cl, 3         Shl          Al, Cl              ; Al ß AL * 8, 8 = 23. Ví dụ: Hai lệnh sau đây sẽ dịch AL sang phải 3 bít, tức là chia AL với 8:         Mov        Cl, 3         Shr          Al, Cl              ; Al ß AL * 8, 8 = 23. Chú ý 2: Hợp ngữ còn cung cấp các lệnh dịch chuyển số học SAL (Shift Arithmetic Left) và SAR (Shift Arithmetic Right) . SAL tương tự hoàn toàn ShL, có thể sử dụng để thực hiện nhân 2 với các số âm. SAR tương tự ShR nhưng bít cuối cùng của [Toán hạng đích] không bị thay bằng bít 0 mà vẫn giữ nguyên giá trị cũ, có thể sử dụng để thực hiện chia 2 với các có dấu. Các lệnh dich bít, quay bít của các vi xử lý Intel 80286/80386/.... cho phép viết số bít cần dịch, trong trường hợp lớn hơn một, trực tiếp trong lệnh dịch, quay mà không cần thông qua thanh ghi Cl [1 – 540]. Các lệnh xử lý chuỗi

Các file đính kèm theo tài liệu này:

  • docxtu_hoc_lap_trinh_assembly_8763.docx
Tài liệu liên quan