ASSEMBLER(Dai hoc quoc gia)

Chia sẻ: Lê Đức Quân | Ngày: | Loại File: DOC | Số trang:16

1
829
lượt xem
231
download

ASSEMBLER(Dai hoc quoc gia)

Mô tả tài liệu
  Download Vui lòng tải xuống để xem tài liệu đầy đủ

Các ngắt của hệ thống hỗ trợ cho lập trình ASSSEMBLY Có 4 hàm hay dùng nhất: Hàm 1: Chờ 1 ký tự từ bàn phím: Mov ah, 1;AL chứa mã ASCII ký tự mã vào Int 21h Hàm 2: Đưa 1 ký tự dạng ASCII ra màn hình tại vị trí con trỏ đang  đứng Cách 1: Nhờ ngắt của BIOS Mov al, mã ASCII của ký tự Mov ah, oeh Int 10h Cách 2: Mov dl, mã ASCII của ký tự Mov ah, 2 Int 21h Hàm 3: Hiện 1 xâu ký tự kết thúc bằng dấu $ ra màn hình Mov dx, offset tên biến xâu Mov ah, 9 Int 21h Hàm 4: Trở về DOS Mov ah, 4ch ;[int 20h] Int 21h...

Chủ đề:
Lưu

Nội dung Text: ASSEMBLER(Dai hoc quoc gia)

  1. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY Các ngắt của hệ thống hỗ trợ cho lập trình ASSSEMBLY _SEGMENT Xác lập các segment cho chương trình Có 4 hàm hay dùng nhất:       tên_segment   SEGMENT   align   combine   use   ‘class’ Hàm 1: Chờ 1 ký tự từ bàn phím: {thân segment} Mov ah, 1;AL chứa mã ASCII ký tự mã vào       tên_segment   ENDS Int 21h trong đó: Hàm 2: Đưa 1 ký tự dạng ASCII ra màn hình tại vị trí con trỏ đang  tên_segment là 1 identifier (không chứa dấu cách, dấu \ ; : ...) đứng align là cách xác lập khoảng cách giữa segment đang khai báo với  Cách 1: Nhờ ngắt của BIOS segment trước nó Mov al, mã ASCII của ký tự align Mov ah, oeh byte khoảng cách 1 byte Int 10h word khoảng cách 2 byte Cách 2: paka khoảng cách 16 byte Mov dl, mã ASCII của ký tự page khoảng cách 256 byte Mov ah, 2 combine có hai chức năng: Int 21h +cho phép đặt segment vào 1 địa chỉ mong muốn (theo yêu cầu) của bộ  Hàm 3: Hiện 1 xâu ký tự kết thúc bằng dấu $ ra màn hình nhớ RAM Mov dx, offset tên biến xâu tên_segment   SEGMENT   at   địa_chỉ_dạng_vật_lý Mov ah, 9 {thân} Int 21h tên_segment   ENDS Hàm 4: Trở về DOS +cho chương trình đa tệp: cách gộp các segment có cùng tên nằm ở các  Mov ah, 4ch ;[int 20h] tệp khác nhau khi liên kết. Ví dụ: Tệp 1 có DATA SEGMENT; Tệp 2 có  Int 21h DATA SEGMENT.khác  Các DIRECTIVE điều khiển SEGMENT dạng đơn giản: dễ viết, dễ liên       _COMMON tức là độ dài của segment sau liên kết bằng độ dài  kết nhưng chưa bao hết mọi tình huống về điều khiển SEGMENT segment lớn nhất .Model thuê vùng nhớ RAM thích hợp cho chương trình      _PUBLIC tức là độ dài của segment sau liên kết bằng tổng độ dài cả  .Model kiểu_tiny code+data≤ 64KB 2 segment .Model kiểu_small code≤ 64KB;data≤ 64KB      _PRIVATE tức là độ dài của segment sau liên kết bằng độ dài của  .Model kiểu_compact code≤ 64KB;data≥ 64KB chính nó (không quan hệ với nhau, đây là chế độ default) .Model kiểu_medium code≥ 64KB;data≤ 64KB      _STACK giống như _PUBLIC .Model kiểu_large code≥ 64KB;data≥ 64KB song khi khai báo1       _CLASS sắp xếp các segment lại gần nhau sau khi liên kết array không ≤ 64KB (Sau khi liên kết thì những segment nào cùng một nhóm thì ở gần nhau) .Model kiểu_large code≥ 64KB;data≥ 64KB song khi khai báo1  _GROUP gộp các segment có cùng kiểu lại với nhau cho dễ dàng qui  array không >64KB chiếu .Stack  Độ lớn (Byte) → Xác lập độ lớn stack cho chương trình     tên_ nhóm   GROUP   tên_các_segment (cách nhau bởi dấu , ) .Data Xác lập vùng nhớ cho dữ liệu của chương trình khai báo biến  _ASSUME cho biết tên segment thuộc loại segment nào nằm ở segment này _ASSUME tên_thanh_ghi   SEG : tên_seg .Data Khai báo biến (có 3 loại biến) Cấu trúc một chương trình Assembly thường thấy: Khai báo MACRO,  Với các loại biến số thì kiểu db có độ dài 1 byte STRUCT, UNION, RECORD, SEGMENT dw có độ dài 2 byte Dạng đơn giản dd có độ dài 4 byte .Model  kiểu dp/df có độ dài 6 byte .Stack     độ lớn dq có độ dài 8 byte [.Data dt có độ dài 10 byte khai báo biến] Với các loại biến xâu có các cách khai báo như sau: .Code tên_biến_xâu   db   ‘các ký tự’ nhãn_chương_trình: tên_biến_xâu   db   độ_lớn   dup(‘1 ký tự’) mov ax, @data tên_biến_xâu   db   độ_lớn   dup(?) mov ds, ax Với các loại biến trường số (array) có các cách khai báo như sau: ... tên_biến_trường   kiểu_thành_phần  (các số cách nhau bởi dấu ,) thân chương trình tên_biến_trường   kiểu_thành_phần   độ_lớn   dup(giá trị 1 số) ... tên_biến_trường   kiểu_thành_phần   độ_lớn   dup(?) mov ah, 4ch .Code Xác lập vùng nhớ truy xuất ngẫu nhiên dùng cho phần mã máy int 21h .Code [các  chương trình con] nhãn_chương_trình: END nhãn_chương_trình mov ax, @data mov ds, ax Dạng chuẩn ... _Stack  segment thân chương trình  db   độ_dài   dup(?) ... _Stack   ends mov ah, 4ch Data segment int 21h khai báo biến [các chương trình con] Data ends end nhãn_chương_trình  Code segment Các DIRECTIVE điều khiển SEGMENT dạng chuẩn: _SEGMENT;  Assume   cs:code   ds:data   ss:stack nhãn_chương_trình: _GROUP; _ASSUME mov ax, data 1
  2. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY mov ds, ax Tệp include ... Tệp INCLUDE cho phép người lập trình viết gọn chương trình  thân chương trình ­ Thiết lập 1 tệp ngoài (gọi là tệp INCLUDE) mà trong tệp này chứa khối  ... lệnh Assembly .ASM mov ah, 4ch ­ Sau đó dùng lệnh INCLUDE để chèn khối lệnh đó vào tệp chương trình  int 21h đang viết. Cú pháp: [các  chương trình con] .............. ENDS INCULDE   X:\đường dẫn\tệp INCLUDE END nhãn_chương_trình .............. *Chương trình con: ­ Cơ chế của chương trình dịch Assembly khi gặp INCLUDE: chương  1, Cơ chế khi 1 chương trình con bị gọi: trình dịch của Tubor Assember khi gặp INCLUDE thì thực hiện các bước: Bước 1: Tham số thực đưa vào STACK * Mở tệp INCLUDE theo sau Directive Include Bước 2: Địa chỉ của lệnh tiếp theo được đưa vào STACK * Sao chép và chèn toàn bộ khối lệnh Assembly có trong tệp INCLUDE  Bước 3: Hệ điều hành quản lý địa chỉ đầu của chương trình con do vậy  vào vị trí Directive Include đứng Hệ điều hành sẽ đưa địa chỉ đó vào CS:IP → rẽ nhánh vào chương trình  * Tiến hành dịch khối lệnh đó con ­ Cách tìm tệp INCLUDE để chèn Bước 4: Thực hiện thân chương trình con cho đến khi gặp lệnh RET thì  * Nếu tệp đứng sau Directive Include có tên đĩa, đường dẫn thì chương  vào STACK lấy địa chỉ lệnh tiếp theo (đã cất ở Bước 2) và cho vào  trình dịch tìm đến, nếu không có thì đó là thư mục hiện hành, còn nếu  CS:IP, rồi quay về chương trình đã gọi nó không có nữa thì sai Bước 5: Tiếp tục thực hiện chương trình đang đợi * Nếu sai thì chỉ có cách sửa lại chương trình nguồn. Khi dịch chương  2, Cú pháp của chương trình con Assembly: trình dùng thêm tham số TASM   ­i   A:\...\*.ASM Tên_chương_trình_con   PROC   [NEAR/FAR] ­ Hạn chế của INCLUDE là không được phép có nhãn nhảy trong khối  Bảo vệ các thanh ghi sẽ bị phá vỡ ở thân chương trình  lệnh của tệp INCLUDE khi gọi nó 2 lần Thân chương trình con macro và các vấn đề liên quan Hồi phục các thanh ghi mà chương trình con phá vỡ 1, Các lệnh lặp khối lệnh khi dịch chương trình: RET REPT dịch khối lệnh theo số lần đi sau REPT Tên_chương_trình_con   ENDP REPT n a, Vấn đề NEAR – FAR:      Khối_lệnh NEAR chương trình con cùng nằm trên 1 segment với chương trình gọi  ENDM nó → địa chỉ lệnh tiếp theo cất vào STACK (Bước 2) chỉ cần 2 byte offset IRP dịch khối lệnh theo số lượng danh sách FAR chương trình con nằm khác segment với chương trình con gọi nó → IRP tên_đối  địa chỉ lệnh tiếp theo cất vào STACK (Bước 2) cần đến 4 byte offset      Khối_lệnh * Với khai báo segment dạng đơn giản thì directive model sẽ xác định  ENDM hiện chương trình con NEAR hay FAR ­ Các Directive điều khiển điều kiện khi dịch chương trình . Model tiny → chương trình con là NEAR Chức năng: Dịch khối lệnh khi điều kiện đúng TRUE . Model small → chương trình con là NEAR IF  IF  . Model compact → chương trình con là NEAR Khối_lệnh Khối_lệnh_1 . Model medium → chương trình con là FAR ENDIF ELSE  Khối_lệnh_2 . Model large → chương trình con là FAR ENDIF . Model huge → chương trình con là FAR Lệnh IFE giống như lệnh IF nhưng ngược điều kiện * Với khai báo dạng chuẩn thì mặc định là NEAR Chức năng: Dịch khối lệnh khi biểu thức  = 0 b, Chương trình con Assembly không có đối số → cơ chế kích hoạt  IFB  chương trình con Assembly  không có Bước 1 Khối_lệnh 3, Chuyển giao tham số: ENDIF Cách 1: Nhờ thanh ghi Lệnh IFNB giống như lệnh IFB nhưng ngược điều kiện Chương_trình_chính Chương_trình_con   Chức năng: Dịch khối lệnh khi  =  ...... ...... IFIDN ,  mov ax, 10 mov bx, ax Khối_lệnh call Chương_trình_con ...... ENDIF ...... Lệnh IFDIF giống như lệnh IFIDN nhưng ngược điều kiện (khi đó bx = 10) Chức năng: Dịch khối lệnh khi nhãn theo sau đó đã được khai báo Cách 2: Nhờ biến nhớ IFDEF nhãn Chương_trình_chính Chương_trình_con   Khối_lệnh ...... ...... ENDIF mov value, 20 mov bx, value Lệnh IFNDEF giống như lệnh IFDEF nhưng ngược điều kiện call Chương_trình_con ...... *Macro là 1 cơ chế giúp người lập trình tạo 1 lệnh mới trên cơ sở tập lệnh  ...... sẵn có của Assembly  (khi đó bx = 20) ­ Trước khi được dùng thì phải khai báo Cách 3: Thông qua STACK (dùng khi liên kết với ngôn ngữ lập trình bậc  Cú pháp: cao) Tên_Macro MACRO[đối] 4, Bảo vệ thanh ghi: Bảo vệ các thanh ghi sẽ bị phá vỡ ở thân chương trình  Khi thân chương trình con sử dụng các lệnh làm giá trị thanh ghi thay đổi  Thân MACRO như and, xor, ... thì phải bảo vệ các thanh ghi đó trước khi dùng Hồi phục các thanh ghi mà chương trình con phá vỡ Cách 1: Dùng các lệnh POP, PUSH ENDM Cách 2: Chuyển vào biến hoặc thanh ghi khác sau đó hồi phục 2
  3. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY ­ Cách dùng lệnh mới đã xác lập ở MACRO: Sau khi macro đã được xác      [các chương trình con]     code   ends lập thì tên của Macro trỏ thành một lệnh mới của ASM END   nhãn_chương_trình END   nhãn_chương_trình  ­ Cách dùng: Gọi tên macro và thay vì đối sẽ là tham số thực Directive public Chương trình Macro hiện xâu ra màn hình: Chức năng: Báo cho chương trình dịch biết những nhãn ở Model này  HIENSTRING   MACRO   XAU cho phép các tệp khác cũng có thể dùng Push  ax, bx Cú pháp: Public   tên_nhãn Lea  dx, XAU   Khai báo kiểu nhãn Mov  ah, 9 .Với hằng: Public     tên_hằng = hằng Int 21h Public Port Popdx, ax Port = 038h ENDM .Với biến: Public tên_biến Chương trình Macro xóa màn hình: Khai báo biến CLRSCR    MACRO .Với tên chương trình con: Push  ax Public tên_chương_trình_con Mov  ah, 0fh tên_chương_trình_con   PROC Int  10h ........... Mov  ah, 0 RET Int 10h tên_chương_trình_con   ENDP Pop  ax Directive public ENDM Chức năng: Báo cho chương trình dịch biết Module này xin phép được  tính ưu việt của macro dùng các nhãn mà các Module khác đã cho phép a, So sánh Macro với chương trình con: Cú pháp: Extrn   tên_nhãn:   kiểu  Tốc độ: Khi chạy chương trình thì Macro nhanh hơn vì không phải dùng  .Nhãn là tên hằng: Extrn   tên_nhãn:   ABS  lệnh CALL và RET Extrn   Post   kiểu  Tiết kiệm bộ nhớ: Chương trình con chiếm ít bộ nhớ hơn .Nhãn là biến nhớ: Extrn   x:   word (hoặc byte hoặc dword) Macro cho phép chuyển giao tham số thông qua đối và cho phép sử  .Nhãn là chương trình con: dụng các Directive lặp khidịch chương trình. Các Directive điều khiển  Extrn   tên_chương_trình_con:PROC điều kiện khi dịch chương trình.  Directive global b, So sánh Macro với tệp INCLUDE: Chức năng: Không phải chương trình nào cũng có Directive này, nó thay  Cơ chế: Giống nhau khi dịch cho Public và Extrn  Tốc độ: Khi chạy chương trình thì Macro nhanh hơn vì không phải mở  Cú pháp:          GLOBAL tên_nhãn:   kiểu  đóng tệp Khai báo biến Macro cho phép có nhãn nhảy trong lệnh của Macro nhờ Directive Local.  Liên kết C với Assembly Trong thân Macro cho phép có các Macro khác INLINE ASM là chèn khối lệnh ASM vào chương trình được viết bằng C Chương trình dạng *.com và *.exe Cú pháp: khối lệnh C Chương trình .EXE có 3 segment {code, data và stack}. Có thể không  ASM   lệnh ASM cùng nằm trên 1 segment ........... Chương trình .COM có 3 segment {code, data và stack} nằm cùng trên  ASM   lệnh ASM 1 segment. Khi chạy chương trình .COM cần 256 byte đầu của segment  khối lệnh C đó để nhảy. Do vậy, lệnh đầu của chương trình .COM sẽ đặt ở offset → Dịch và liên kết người lập trình phải khai báo cho hệ điều hành Directive ORG  TCC   ­ms   :IC\TC\INCLUDE   ­LC Khai báo chương trình dạng .COM có 1 segment và là Code Segment → Hạn chế: Các lệnh ASM được chèn thì dịch nhờ bởi chương trình dịch  biến cũng được khai báo ở Code Segment của TC. Do đó 1 số lệnh khó của ASM dịch không đúng. Không cho phép  .Code có các nhãn nhảy trong ASM → khối lệnh chèn vào yếu (vì không có  Nhãn_chương trình: LOOP, nhảy có và không có điều kiện) Jmp   nhãn_khác Viết tách biệt tệp cho c và tệp cho asm [nếu có khai báo biến] Phải giải quyết 3 vấn đề: Khai báo biến 1, Vấn đề đa tệp: (khai báo Public) với Module của C, bất kỳ khai báo  Nhãn_khác: nào của C đều là khai báo Public. Khai báo External ngôn ngữ C phải xin  ...... phép dùng các nhãn đã cho phép từ tệp ngoài. Với Module ASM giống  mov   ah, 4ch như đa tệp thuần túy int 21h 2, Vấn đề dấu (­) (underscore) người viết chương trình ASM phải thêm  Dạng thường thấy của chương trình .COM thuần túy [Khai báo  dấu – vào trước trên các nhãn dùng chung với C và thêm ở mọi nơi mà  MACRO, STACK, UNION, RECORD] tên đó xuất hiện  Dạng đơn giản Dạng chuẩn 3, Vấn đề giá trị quay về của hàm ASM: qui định với giá trị 2 byte thì  .Model  tiny .Code   segment trước khi RET ax = bao nhiêu thì tên hàm ASM có giá trị bấy nhiêu. Với                (hoặc small)     ORG   100h giá trị 4 byte trước khi RET dx:ax có giá trị bao nhiêu thì hàm ASM có giá  .Code assume   cs:code,ds:code,ss:code trị bấy nhiêu     ORG   100h Nhãn_chương_trình: cơ chế khi một ngắt và chương trình con được kích hoạt Nhãn_chương_trình:     Jmp   nhãn_khác Chương trình con bình thường:     Jmp   nhãn_khác     Khai báo biến CALL     Khai báo biến     Nhãn_khác: Bước 1: Tham số thực → STACK     Nhãn_khác:     ........ Bước 2: Địa chỉ lệnh tiếp theo → STACK     .........     int   20h     int   20h     [các chương trình con] 3
  4. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY Bước 3: Hệ điều hành quản lý địa chỉ đầu của chương trình con → Hệ  xuất phần cứng thì viết driver cho nó và nạp vào ROM và ROM đó sẽ  điều hành đưa địa chỉ đầu của chương trình con → cs:ip → rẽ nhánh vào  được đặt trên Card đó chương trình con Int 19h:  Lôi boot sector xuống RAM và trao quyền cho chương trình nằm  Bước 4: Thực hiện các lệnh của chương trình con → RET thì vào STACK  trong boot sector lấy địa chỉ lệnh tiếp theo (đã cất ở bước 2) → cs:ip và trở về chương trình  Trong boot sector là sector 512 byte chứa tham số đĩa và chứa chương  đang dở trình mồi Bước 5: Tiếp tục chương trình đang dở Chương trình mồi lôi 2 tệp ẩn xuống RAM (hệ điều hành DOS) Chương trình con phục vụ ngắt: Kiểm tra thiết bị ngoại vi Int n (tác động linh kiện) Lôi COMMAND.COM vào vùng nhớ RAM – là chương trình dịch các lệnh  Bước 1: Flag → STACK;Tham số thực → STACK của DOS → Mã máy Bước 2: Địa chỉ lệnh tiếp theo → STACK CONFIG.SYS Bước 3: Hệ điều hành quản lý địa chỉ đầu của chương trình con phục vụ  AUTOEXEC.BAT ngắt. Song địa chỉ đầu của chương trình con phục vụ ngắt nằm trong ô  C:\> nhớ tương ứng của bảng vectơ ngắt → máy tính vào vectơ ngắt lấy địa  chỉ đầu của chương trình con phục vụ ngắt đưa vào cs:ip → rẽ nhánh vào  chương trình con phục vụ ngắt Bước 4: Thực hiện các lệnh của chương trình con cho đến khi gặp IRET  thì vào STACK lấy địa chỉ lệnh tiếp theo (đã cất ở bước 2) → cs:ip và trở  về chương trình đang dở Bước 5: Trước khi tiếp tục chương trình đang dở thì vào  STACK lấy cờ  đã cất Bảng vectơ ngắt: là vùng nhớ RAM chứa địa chỉ đầu của chương trình  con phục vụ ngắt. Máy tính có 256 ngắt → có 256 chương trình con phục  vụ ngắt. Địa chỉ ô bằng n * 4 (mỗi địa chỉ 4 byte) Các bước để xác lập chương trình con phục vụ ngắt: Bước 1: Viết chương trình con theo yêu cầu của thuật toán Cú pháp: Tên_chtrình_con_pvụ_ngắt  PROC  [NEAR/FAR] Bảo vệ các thanh ghi Thân chương trình Phục hồi các thanh ghi Bài tập 1: IRET Hiện 1 xâu ký tự “Hello TASM!” ra màn hình Tên_chtrình_con_pvụ_ngắt  ENDP Cách 1: Bước 2: Sau khi viết xong chương trình con phục vụ ngắt thì tìm địa chỉ  .MODEL small đầu của chương trình này đưa vào vị trí tương ứng của bảng vectơ ngắt .STACK 100h Khởi động máy tính với hệ điều hành DOS .DATA Với máy tính của INTEL, khi bật máy thì thanh ghi CS = F000h; IP =  Message db ‘Hello TASM!$’ FFF0h và sẽ nhảy vào thực hiện lệnh ở ô nhớ F000:FFF0. Lệnh này là  .CODE lệnh jmp và nó nhảy đến chương trình khởi động máy tính đều nằm ở  ProgramStart: ROM­BIOS Mov AX,@DATA ROM­BIOS là vùng nhớ chỉ đọc, không ghi được và chứa 2 loại chương  Mov DS,AX trình khởi động máy và chương trình phục vụ ngắt của BIOS Mov DX,OFFSET Message Các chương trình khởi động máy tính: Mov AH,9 Test CPU: kiểm tra các thanh ghi. Tống vào các giá trị 00, 55 và FF vào  Int 21h các thanh ghi và kiểm tra lại có bằng 00, 55 và FF không. Đồng thời kiểm  Mov AH,4Ch tra một số lệnh ASM nếu có lỗi thì hiện FATA ERROR. Int 21h Kiểm tra ROM­BIOS: trong ROM có 1 byte CHECKSUM (tổng các byte  END ProgramStart của ROM) khi khởi động thì có 1 chương trình cộng các byte của ROM lại  Cách 2: lưu kết quả vào 1 byte và so sánh byte này  với CHECKSUM. Nếu bằng  _STACK  segment  stack  ‘stack’ nhau thì tức là ROM tốt, ngược lại là tồi. db 100h dup(?) Kiểm tra một số linh kiện quan trọng của mainboard _STACK ends 8259 là chip phục vụ ngắt DATA segment 8250 UART (COM) Message db ‘Hello TASM!’,0 8253 Timer DATA ends 8237 DMA CODE segment Kiểm tra RAM (giống hệt CPU và thanh ghi) tức là cho toàn bộ các byte  AssumeCS:CODE, DS:DATA, SS:_STACK của RAM các giá trị 00, 55, FF liệu RAM có chấp nhận các giá trị này  ProgramStart: không Mov AX,DATA Xác lập bảng vec tơ ngắt của BIOS Mov DS,AX Đưa mọi địa chỉ đầu của các chương trình con phục vụ ngắt vào bảng  Mov SL,OFFSET Message vec tơ ngắt cld Đưa các thông số máy tính đang dùng vào vùng nhớ biến BIOS L1: Kiểm tra liệu có ROM mở rộng: với màn hình và ổ đĩa thì về phần cứng  Lodsb cho các Card điều khiển không giống nhau → không thể viết 1 driver  AndAL,AL chung và nạp vào ROM­BIOS chuẩn → thỏa hiệp của các hãng: Ai sản  Jz Stop Mov AH,0eh 4
  5. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY Int 10h     m2   db     0ah,0dh,'Vao so thu2: $' Jmp L1     m3   db     0ah,0dh,'So be la:  $' Stop: .code Mov AH,1    ps: Int  21h       mov ax,@data Mov AH,4Ch       mov ds,ax Int 21h       hien_string m1 CODE ends       call VAOSO END ProgramStart       mov ax,sohex Bài tập 2:       mov temp,ax So sánh 2 số nguyên nhập từ bàn phím xem số nào bé hơn       hien_string m2 Cách 1:       call VAOSO include C:\HTDAT\INCLUDE\lib1.asm       mov bx,sohex _stack segment stack 'stack'       hien_string m3        db 100h dup(?)       cmp ax,bx _stack ends        jl L1 data segment         xchg ax,bx m1 db 10,13,'Vao so thu nhat:$'      L1: m2 db 10,13,'Vao so thu hai:$'       call HIENSO m3 db 10,13,'So be la:$'       mov  ah,1 m4 db 10,13,'Co tiep tuc khong (c/k)?:$'       int  21h data ends       mov ah,4ch code segment       int 21h    assume cs:code,ds:data,ss:_stack ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­    ps:    VAOSO PROC mov ax,data      push ax bx cx dx mov ds,ax      mov bx,10 clrscr      xor cx,cx hienstring m1      mov sohex,cx call Vao_so_N   VS1: mov bx,ax      mov ah,1   ; Ham nhan 1 ki tu va ­­­>al hienstring m2      int 21h call Vao_so_N      cmp al,0dh cmp ax,bx       je VS2 jl L1      sub al,30h xchg ax,bx      mov cl,al   L1:      mov ax,sohex hienstring m3      mul bx call Hien_so_N      add ax,cx hienstring m4      mov sohex,ax mov ah,1    jmp VS1 int 21h   VS2: cmp al,'c'      pop dx cx bx ax je ps      ret mov ah,4ch   VAOSO ENDP int 21h ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ include C:\HTDAT\INCLUDE\lib2.asm   HIENSO PROC code ends     push ax bx cx dx end ps     mov bx,10 So sánh 2 số nhập vào từ bàn phím xem số nào bé hơn     xor cx,cx Cách 2:  HS1: hien_string MACRO xau    xor dx,dx   push ax dx    div bx       ; tuc lay dx:ax chia cho bx kq thuong­­>ax va du­­>dx    mov dx,offset xau    add dx,30h   ; de dua ra dang  ASCCI    mov ah,9    push dx      ; tong 1 chu vao stack    int 21h    inc cx   pop dx ax    cmp ax,0 ENDM    jnz HS1 ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­  HS2: .model small    pop ax .stack 100h    mov ah,0eh .data    int 10h     sohex    dw        ?   loop HS2     temp     dw        ?    pop dx cx bx ax     m1   db     0ah,0dh,'Vao so thu1: $'    ret 5
  6. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY   HIENSO ENDP    m3 db ' la:$' end ps    m4 db 10,13,'Co tiep tuc khong(c/k)?: ' Bài tập 3: data ends Tính trung bình cộng 2 só nguyên nhập từ bàn phím code segment INCLUDE C:\INCLUDE\LIB1.ASM   assume cs:code,ds:data,ss:_stack _STACK segment     ps: db 100h dup(?) mov ax,data _STACK ends mov ds,ax DATA segment clrscr M1 db ‘Hay vao so thu 1: $’ hienstring m1 M2 db 0ah,0dh,‘Hay vao so thu 2: $’ call vao_so_N M3 db 0ah,0dh,‘Trung binh cong cua 2 so nguyen la: $’ hienstring m2 M4 db ‘­$’ call Hien_so_N M5 db ‘.5$’ hienstring m3 M6 db 0ah,0dh,’ Co tiep tuc khong (c/k) ?: $’ call S_N_T DATA ends mov ax,fv CODE segment call hien_so_N assume cs:code,ds:data,ss:_stack hienstring m4 ps: mov ah,1 mov ax,data int 21h mov ds,ax cmp al,'c' clrscr je ps HienString M1 mov ah,4ch call VAO_SO_N int 21h mov bx,ax include C:\HTDAT\INCLUDE\lib3.asm HienString M2 include C:\HTDAT\INCLUDE\lib2.asm call VAO_SO_N code ends HienString M3 end ps Add ax,bx Chương trình tính giai thừa của một số n nhập từ bàn phím And ax,ax  Cách 2: Jns L1 code segment HienString M4      assume cs:code,ds:code Neg ax      org 100h L1: start: jmp do Shr ax,1 msg1 db 'nhap vao mot so:$' Pushf msg2 db 'ket qua la:$' Call HIEN_SO_N giaithua  dw  1 Popf so dw 0 Inc L2 m db 'ok $' HienString M5 do : L2:       mov ah,09h HienString M6       mov dx,offset msg1 Mov ah,1       int 21h Int 21h       call nhapso Cmp al,’c’       call cr_lf Je TT       mov bx,1 Mov ah,4ch       mov cx,ax Int 21h lap: TT:      mov ax,giaithua Jmp ps      mul bx INCLUDE C:\INCLUDE\LIB2.ASM      inc bx CODE ends      mov giaithua,ax END ps      loop lap Bài tập 4:      mov ax,giaithua Nhập một số nguyên dương n từ bàn phím và tìm giai thừa của nó      push ax Cách 1:      push dx include C:\HTDAT\INCLUDE\lib1.asm      mov ah,09h _stack segment stack 'stack'      mov dx,offset msg2 db 100h dup(?)      int 21h _stack ends      pop dx data segment      pop ax    fv dw ?      call inra    fac dw ?      mov ah,01h    m1 db 10,13,'Vao so n:$'      int 21h    m2 db 10,13,'Giai thua cua $'      int 20h 6
  7. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY ;­­­­­­­­­­­­­­­­­­­­­­­­­­ sta :  cr_lf  proc near      push dx      push ax      mov ah,08      push dx       int 21h      mov ah,02h      cmp al,0dh      mov dx,0dh      je exit1      int 21h      cmp  al,30h      mov dx,0ah      jb sta      int 21h      cmp al,39h      pop dx      ja sta      pop ax       mov dl,al      ret ;     xor ah,ah cr_lf endp ;­­­­­­­­­­­­­­­­­­­­­­­­­­­      mov ah,02h nhapso proc near      int 21h      push dx exit1:      push cx      pop dx      push bx      ret      xor dx,dx nhap endp      mov so,0 ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­      mov cx,1 code ends lap1:  call nhap end start      cmp al,0dh Bài tập 5:      je exit Tìm số nguyên tố nhỏ hơn hoặc bằng số giới hạn cho trước      sub al,30h INCLUDE C:\INCLUDE\LIB1.ASM      xor ah,ah _STACK segment      xor dx,dx db 100h dup(?)      mov dx,ax _STACK ends      mov ax,so DATA segment      cmp cx,1 M1 db ‘Hay vao so gioi han: $’      je nota M2 db 0ah,0dh,’ Cac so nguyen to tu 2 den $’      mov bl,10 M3 db ‘la: $’      mul bl M4 db 0ah,0dh,’ Co tiep tuc khong (c/k) ?: $’ nota: add ax,dx So dw dw      mov so,ax DATA ends      inc cx CODE segment      jmp lap1 Assume CS:CODE, DS:DATA, SS:_STACK exit: mov ax,so PS:     pop bx Mov AX,DATA     pop cx Mov DS,AX     pop dx CLRSCR     ret HienString M1 nhapso endp Call VAO_SO_N ;­­­­­­­­­­­­­­­­­­­­­­­­­­­ HienString M2 inra proc Call VAO_SO_N      mov bx,10 HienString M3      xor cx,cx Mov BX,AX none_zero: Mov so,1       xor dx,dx L1:       div bx Inc so       push dx Mov AX,so       inc cx Cmp AX,BX       or ax,ax Jg Stop       jnz none_zero Mov CX,AX write: pop dx Shr CX,1       add dl,'0' L2:       mov ah,02 Cmp CX,1       int 21h Jle L3       loop write Xor DX,DX       ret Div CX inra endp And DX,DX Jz L1 ;­­­­­­­­­­­­­­­­­­­­­­­­­­­ Mov AX,so public nhap Loop L1 nhap proc near L3: 7
  8. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY Call HIEN_SO_N POP AX HienString M4 CALL WRITE_CHAR Jmp L1 EXIT: MOV AH,4CH Stop: INT 21H   HienString M5 CODE_SEG ENDS Mov AH,1 END START Int 21h ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ Cmp AL,’c’ CR_LF PROC FAR Je TT PUSH AX Mov AH,4Ch PUSH DX Int 21h MOV AH,02 TT: MOV DX,0AH Jmp PS INT 21H INCLUDE C:\INCLUDE\LIB2.ASM MOV DX,0DH CODE ends INT 21H END PS POP DX Bài tập 6: POP AX Nhập 2 số vào từ bàn phím và in ra tích của chúng RET EXTRN CR­LF ENDP ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ GET_IN_NUMBER PROC  CR_LF:PROC,PRINT_CHAR:PROC,GET_IN_NUMBER:PROC,WRITE_ PUSH DX CHAR:PROC NHAY: MOV AH,08 ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ INT 21H DATA_SEG SEGMENT PUBLIC CMP AL,0DH DATA_1   DB  'ENTER TWO STRING:$' JE EXIT_1 DATA_2   DB 'NUMBER1:$' CMP AL,30H DATA_3    DB 'NUMBER2:$' JB NHAY PRODUCT   DB 'PRODUCT IS:$' CMP  AL,39H TEMP_VAR  DW 0 JA NHAY TEMP   DW 0 MOV DL,AL NUMBER   DW 0 MOV AH,02 DATA_SEG  ENDS INT 21H ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ EXIT_1: POP DX STACK SEGMENT STACK MOV AX,4CH DB 64 DUP('STACK') INT 21H STACK ENDS RET ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ GET_IN_NUMBER ENDP CODE_SEG SEGMENT PUBLIC ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ASSUME CS:CODE_SEG,DS:DATA_SEG,SS:STACK PRINT_CHAR PROC NEAR START:MOV AX,DATA_SEG         ;khoi tao thanh ghi DX PUSH DX MOV DS,AX PUSH BX MOV AH,09               ;yeu cau nhap MOV TEMP,0 MOV DX,OFFSET DATA_1 MOV CX,1 INT 21H LOOP_1: CALL GET_IN_NUMBER CALL CR_LF CMP AL,0DH MOV AH,09               ; so thu 1 JE EXIT_2 MOV DX,OFFSET DATA_2 SUB AL,30H INT 21H MOV DX,AX CALL PRINT_CHAR XOR AH,AH CMP AX,99 MOV AX,TEMP JA EXIT CMP CX,2 MOV TEMP_VAR,AX JB NONE_ZERO CALL CR_LF MOV BX,10 MOV AH,09               ; so thu 2 MUL BX MOV DX,OFFSET DATA_3 NONE_ZERO: INT 21H ADD AX,DX CALL PRINT_CHAR MOV TEMP,AX CMP AX,99 INCCX JA EXIT CMP CX,2 CALL CR_LF JA EXIT_2 MUL NUMBER              ;AX:=AX*NUMBER JMP LOOP_1 PUSH AX EXIT_2: MOV AX,TAM MOV AH,09 POP BX MOV DX,OFFSET PRODUCT POP DX INT 21H 8
  9. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY RET         INT 21H PRINT_CHAR ENDP ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­ mov soam,0h WRITE_CHAR PROC NEAR                         mov dauso2,0 PUSH BX                         CALL GET_AN_INT_NUM PUSH CX                         cmp soam,1 XOR DX,DX                         jne so2khongam MOV BX,10                          mov dauso2,1   MOV CX,1            so2khongam: LOOP_2:     CMP AX,255 DIV BX JA EXIT PUSH DX MOV NUMBER2,AL INCCX CALL CR_LF OR AX,AX JNZ LOOP_2                 MOV AH,09 JE PRINT MOV DX,OFFSET MSG3 PRINT: POP DX INT 21H ADD DX,30H                                   MOV AH,02H ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ INT 21H                         mov    cl,dauso1 LOOP PRINT                         add    cl,dauso2 RET                         cmp    cl,1 WRITE_CHAR ENDP ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­                         je     khacdau         ;HAI SO KHAC DAU Bài tập 7: Tính tổng hai số nhập từ bàn phím                         XOR    AX,AX  CODE_SEG  SEGMENT BYTE  PUBLIC                         MOV    BL,NUMBER1 ASSUME CS:CODE_SEG,DS:CODE_SEG                         ADD    AL,BL ORG  100H                         PUSH   AX  START: JMP  FIRST                         cmp    dauso1,1 MSG       DB 'NHAP VAO 2 SO DE CONG :$'                         jne    khongam MSG1 DB  'SO THU NHAT :$'                         call   indau MSG2 DB  'SO THU HAI :$'                         jmp    khongam MSG3 DB  'TONG CUA CHUNG LA :$' ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ NUMBER1 DB 0              khacdau:   mov    cl,number1 NUMBER2 DB 0                         cmp    cl,number2  ;SO1>SO2 ?                         je     writeZero soam db ?                         ja     laydauso1  dauso1 db ? ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ dauso2 db ?                         XOR    AX,AX                         MOV    BL,NUMBER1 FIRST:         MOV AH,09H                         SUB    AL,BL MOV DX,OFFSET MSG                         PUSH AX INT 21H                                                   call cr_lf                         cmp    dauso2,1                         MOV AH,09H                         jne    khongam                 MOV DX,OFFSET MSG1                         CALL   INDAU           INT 21H                         JMP    KHONGAM mov soam,0              laydauso1:  XOR   AX,AX                         mov dauso1,0                          MOV   AL,NUMBER1                         CALL GET_AN_INT_NUM                          SUB   AL,NUMBER2 cmp soam,1                          PUSH  AX                         jne so1khongam                          cmp    dauso1,1                         mov dauso1,1                          jne    khongam            so1khongam:                           CALL   INDAU                         CMP AX,255                           Jb  tieptuclam              khongam:                           int 20h                                       POP AX   tieptuclam:MOV NUMBER1,AL                          CALL CR_LF                          CALL WRITE_INT_NUMBER                          jmp exit MOV AH,09H             writezero:   mov ax,0         MOV DX,OFFSET MSG2                          call write_int_number 9
  10. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY            MOV  AH,08H        EXIT:                     INT  21H                         INT 20    CMP AL,0DH ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­    JE  EXIT_1        ;­­­­­­­­­­­­­­­­­­­­­­­­ ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­                    CMP AL,'­'  indau proc                    JNE TIEP             push ax                    JMP INSO       push dx                ;­­­­­­­­­­­­­­­­­­­­­­­­       mov ah,02          TIEP:     CMP AL,30H       mov dl,'­'    JB  LOOP_1       int 21h    CMP AL,39H       pop dx    JA  LOOP_1       pop ax            ret                        indau endp          INSO:     MOV DL,AL ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­    MOV AH,02 GET_AN_INT_NUM  PROC    INT  21H             JMP  $+4 EXIT_1:    POP DX TEMP_VAR    DW   0    RET             PUSH BX              GET_A_DEC_DIGIT ENDP             PUSH CX  ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­             PUSH DX  ;             XOR  DX,DX ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­             MOV TEMP_VAR,0 WRITE_INT_NUMBER  PROC NEAR             MOV CX,1   MOV  BX,10             mov soam,0h                  XOR  CX,CX NONE_ZERO: LOOP_2:     CALL  GET_A_DEC_DIGIT   XOR  DX,DX CMP AL,0DH   DIV  BX JE EXIT_2   PUSH  DX ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­   INC  CX                    cmp al,'­'   OR  AX,AX                         jne tieptuc   JNZ  NONE_ZERO                          mov soam,1h  WRITE_DIGIT_LOOP:                         jmp  loop_2   POP DX ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ ADD DL,48  ;=30H='0'               tieptuc:  SUB AL,30H MOV  AH,02 XOR AH,AH INT 21H MOV DX,AX LOOP WRITE_DIGIT_LOOP MOV AX,TEMP_VAR RET CMP CX,1 WRITE_INT_NUMBER   ENDP JE SUM_UP ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ MOV BL,10 ; PUSH DX ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ MUL  BL CR_LF   PROC NEAR POP DX PUSH  AX SUM_UP: ADD AX,DX PUSH  DX MOV TEMP_VAR,AX MOV AH,02 INC CX MOV DL,0DH CMP CX,3 INT 21h JA   EXIT_2 MOV DL,0AH JMP  LOOP_2 INT 21H EXIT_2: MOV  AX,TEMP_VAR POP DX POP DX POP AX POP CX RET POP BX CR_LF   ENDP RET ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ GET_AN_INT_NUM   ENDP CODE_SEG   ENDS ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ END        START ; Bài tập 8: ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­ Chương Trình xác định số cổng COM và địa chỉ cổng COM GET_A_DEC_DIGIT  PROC hien_string MACRO xau LOOP_1:          push ax dx            PUSH  DX         mov dx,offset xau 10
  11. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY         mov ah,9   add al,30h         int 21h   mov ah,0eh         pop dx ax   int 10h ENDM   ret ;­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­­  HIEN ENDP  _STACK SEGMENT  STACK 'STACK'   code ends      db 100h dup(?) end ps _STACK ENDS Bài tập 9: data segment Hiển thị tên ổ đĩa và thời gian đọc đĩa     m1   db          'Khong co cong COM. $' COMMENT *     m2   db  0ah,0dh,'So luong cong COM la: $'    PROGRAM DISKLITE     m3   db  0ah,0dh,'Dia chi cong COM1 la: $'    chuong trinh se hien thi ten o dia va thoi gian doc dia data ends    moi khi co truy nhap dia code segment     Sudung:   assume cs:code,ds:data,ss:_STACK        DISKLITE ­> chay chuong trinh    ps:        DISKLITE /U ­> unload disklite*       mov ax,data CODE   SEGMENT       mov ds,ax        ASSUME CS:CODE,DS:CODE        ORG 100h       mov ax,40h START:       mov es,ax        JMP    INIT    ;nhay toi thu tuc khoi tao       mov bx,11h MAGIC_CODE  DB  'DISKLITE VERSION 1.0'       mov al,es:[bx] MAGIC_LEN   LABEL BYTE       and al,0eh ; lay 3 bit chua so luong cong COM (0 0 0 0 | x x x 0) NUM_IN      EQU 11 ;so chu so de in                  ;                                      0        e DISPLAY_BASE DW 0B800h       jnz l1 OLD_CHARS     DB NUM_IN*2 DUP(?)        hien_string m1 DISPLAY_DRV   DB 'A',70h,':',70h,' ',70h ;in ten o dia       jmp stop DISPLAY_TM    DB '0',70h,'0',70h,':',70h,'0',70H,'0',70h,':',70h     l1:               DB  2 DUP('0',70h)      hien_string m2 NUM_FLOPPIES   DB ?      shr al,1 SECOND        DB 0      add al,30h MINUTE        DB 0      mov ah,0eh HOUR          DB 0      int 10h TICKER        DB 0 ;so nhip dong ho      hien_string m3 D_DISK        EQU  (80­NUM_IN­1)*2 ;offset de ghi ten o dia      mov bx,2           ; cong COM 2 D_TIME        EQU  (82­NUM_IN)*2  ;offset ghi thoi gian      mov ax,es:[bx] ;dia chi byte trang thai moto o mem      push ax MOTOSTATUS  EQU 43Fh      mov al,ah ;dia chi cong dia cung      call HIENHEX HARDPORT EQU 1F7h      pop ax ;dia chi co dia cung      call HIENHEX HARDFLAGS EQU 48Ch   ;(Neu flags and 8)=8 thi dang roi   stop: ;dia chi co IN_DOS      mov ah,1 DAPTR EQU  THIS DWORD      int 21h DAPTR_OFS  DW ?      mov ah,4ch DAPTR_SEG  DW ?      int 21h ;cac thuc tuc ngat cu ; chuong trinh con HIENHEX va trong CTC nay lai chua CTC HIEN OLDINT13_PTR EQU THIS DWORD  HIENHEX PROC OLD_INT13   DW ? ;dia chi ngat 13H    push ax cx             DW ?    push ax OLDINT1C_PTR EQU THIS DWORD    mov cl,4 OLD_INT1C   DW ? ;dia chi ngat 1C    shr al,cl             DW ?    call HIEN INT13 PROC FAR    pop ax       ASSUME CS:CODE,DS:NOTHING     and al,0fh       PUSHF      ;luu thanh ghi co    call HIEN       PUSH   AX    pop cx ax       PUSH   CX    ret       PUSH   DX  HIENHEX ENDP       PUSH   SI  HIEN PROC       PUSH   DI   cmp al,10       PUSH   DS   jl H       PUSH   ES   add al,7       CALL   GET_DISPLAY_BASE   ;tinh dia chi doan bo nho man hinh  H:       CALL   SAVE_SCREEN        ;Luu 11 ky tu 11
  12. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY       CALL   DISPLAY_DRIVE       INC   TICKER       CALL   DISPLAY_TIME        MOV   AL,TICKER       POP    ES       CMP   AL,18     ;so nhip 18.2 lan trong mot giay       POP    DS       JB    NOT_INC   ;neu Chua bang thi in ra man hinh       POP    DI       MOV   TICKER,DL ;neu qua thi dat lai ticker=0       POP    SI       INC   SECOND    ;tang giay       POP    DX       MOV   AL,SECOND       POP    CX       CMP   AL,60     ;neu qua 60 giay thi tang phut       POP    AX       JB    NOT_INC       POPF       MOV   SECOND,DL       PUSHF       INC   MINUTE    ;tang phut       CALL   DWORD PTR CS:OLD_INT13       MOV   AL,MINUTE       PUSHF       CMP   AL,60       PUSH   AX       JB    NOT_INC       PUSH   CX       MOV   MINUTE,DL       PUSH   SI       INC   HOUR       PUSH   DI NOT_INC:       PUSH   DS       ;CALL  DISPLAY_TIME  ;thu       PUSH   ES       ;POP   ES       LEA    SI,OLD_CHARS       POP   DS       MOV    DI,D_DISK       ;POP   SI       MOV    CX,NUM_IN       POP   DI       CALL  WRITE_S       POP   DX       POP   ES       ;POP   CX       POP   DS       POP   AX       POP   DI       JMP   DWORD PTR CS:OLD_INT1C       POP   SI INT1C  ENDP       POP   CX ;thu tuc get_display_base xac dinh doan bo nho man hinh       POP   AX ; thay doi AX       POPF GET_DISPLAY_BASE PROC NEAR       RET   2      INT    11h  ;lay co thiet bi INT13  ENDP      AND    AX,30h INT1C  PROC FAR      CMP    AX,30h  ;man hinh don sac       ASSUME CS:CODE,DS:NOTHING       MOV    AX,0B800h       PUSH  AX      JNE    GET_BASE       ;PUSH  CX      MOV    AX,0B000h       PUSH  DX GET_BASE:       PUSH  DI      MOV    DISPLAY_BASE,AX       ;PUSH  SI      RET       PUSH  DS GET_DISPLAY_BASE ENDP       ;PUSH  ES ;thu tuc savescreen luu manh hinh lai       ;LDS   DI,[DAPTR] ;nap IN_DOS vao DS:DI ;thay doi AX,si,di,ds,es,cx       ;CMP   BYTE PTR DI,0 ;co DOS co ban khong SAVE_SCREEN PROC NEAR       XOR   AX,AX     MOV     SI,D_DISK  ;lay dia chi bo nho man hinh       MOV   DS,AX     MOV     DI,OFFSET OLD_CHARS       MOV   AL,BYTE PTR DS:[MOTOSTATUS] ;co o dia nao quay khong      MOV     AX,DISPLAY_BASE       AND   AL,3     MOV     DS,AX         ;ky tu man hinh nam tai DS:SI       CMP   AL,0       MOV     AX,CS       JNE   CONTINUE       ;neu ban thi tiep tuc      MOV     ES,AX         ;old_chars nam tai ES:DI       ;MOV   DX,HARDPORT  ;cong dia cung chua byte so 7 la co bao ban     MOV     CX,NUM_IN       ;IN    AL,DX           ;kiem tra cong dia cung      REP     MOVSW       ;SHR   AL,7            ;kiem tra bit 7     RET       ;CMP   AL,1            ;neu ban SAVE_SCREEN ENDP       MOV    AL,BYTE PTR DS:[HARDFLAGS]  ;kiem tra co dia cung ;thu tuc display_drive ghi ten o dia       AND    AL,8 ;thay doi AX,SI,CX,DI       CMP    AL,8            ;neu co=8 la roi DISPLAY_DRIVE PROC NEAR       JNE    CONTINUE        ;khong thi tiep tuc     MOV   AL,DL       XOR    AL,AL     CMP   AL,80h    ;co phai o cung khong       MOV    SECOND,AL     JB    DISPLAY   ;khong thi tiep tuc       MOV    MINUTE,AL     SUB   AL,80h    ;khong thi tru 80h       MOV    HOUR,AL     ADD   AL,NUM_FLOPPIES ;cong voi so o dia       MOV    TICKER,AL  DISPLAY:       JMP    NOT_INC      ADD   AL,'A' CONTINUE:     LEA   SI,DISPLAY_DRV       XOR   DL,DL     MOV   CS:[SI],AL 12
  13. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY     MOV   CX,3 WRITE_S  PROC NEAR     MOV   DI,D_DISK   ;offset in ten dia     MOV  AX,DISPLAY_BASE     CALL  WRITE_S     MOV  ES,AX   ;dia chi man hinh ES:DI     RET     MOV  AX,CS DISPLAY_DRIVE ENDP     MOV  DS,AX   ;dia chi display_tm tai DS:SI ;thu tuc display_time in so gio     REP  MOVSW ;thay doi AX,CX,SI,DX     RET DISPLAY_TIME PROC NEAR WRITE_S  ENDP     LEA   SI,DISPLAY_TM ;dia chi cua gio de in  ;bat dau khoi tao     MOV   DL,'0' INIT:        ;bat dau thuong tru     MOV   CS:[SI],DL OLDPSP   DW ?      MOV   AL,HOUR BLOCMCB EQU 'M'  ; bao hieu chua het MCB     XOR   AH,AH LASTMCB EQU 'Z'  ; da het MCB     CMP   AX,10   ;gio co lon hon muoi khong MCB        STRUC   ;cau truc cua MCB     JB    LESS_H  IDCODE    DB ?         MOV   CL,10  PSP       DW ?     DIV   CL       ;ket qua trong AL,so du trong AH  SIZE      DW ?     ADD   AL,'0' MCB        ENDS     MOV   CS:[SI],AL       MOV   AL,AH    ;lay so du trong AH          ;kiem tra xem da resident chua LESS_H:          MOV    AH,51h     INC   SI          INT    21h       ;lay PSP cua chuong trinh,gia tri cho trong BX     INC   SI           MOV    DX,BX     ; giu gia tri  vao DX     ADD   AL,'0'     MOV   CS:[SI],AL          ;lay dia chi MCB dau     ADD   SI,4      ;dat SI vao offset cua minute          MOV     AH,52h     MOV   CS:[SI],DL ;dat truoc hang chuc=0          INT     21h    ;ES:BX­2 tro toi dia chi cua MCB dau tien     MOV   AL, MINUTE          SUB     BX,2     XOR   AH,AH          MOV     AX,ES:[BX]     CMP   AX,10   ; phut co lon hon 10 khong          MOV     ES,AX     JB    LESS_M          XOR     BX,BX ;ES:BX la MCB dau     MOV   CL,10          MOV    DI,OFFSET MAGIC_CODE ;ES:DI se chua Magic_code      DIV   CL       ;ket qua trong AL,so du trong AH neu da thuong tru     ADD   AL,'0' FIND_CODE:       ;Tim xem da thuong tru chua     MOV   CS:[SI],AL          CMP    DX,ES:[BX].PSP       ;xem PSP(MCB) co bang PSP(PROG)     MOV   AL,AH    ;lay so du trong AH          JE     TIEP                 ;co thi nhay sang MCB khac     LESS_M:          MOV AX,DS ;dia chi cua chuong trinh thuong tru      INC   SI          SUB    AX,DX     INC   SI           ADD    AX,ES:[BX].PSP ;addr=PSP(MCB)+(segment(PROG)­     ADD   AL,'0' PSP(PROG))     MOV   CS:[SI],AL          PUSH   ES             ;cat ES     ADD   SI,4      ;dat SI vao offset cua second          MOV    ES,AX          ;ES se chua doan chuong trinh thuong tru neu      MOV   CS:[SI],DL da resident      MOV   AL,SECOND          PUSH   DI                   ;cat DI      XOR   AH,AH          MOV    SI,DI                ;DS:SI se chua magic_code cua chuong      CMP   AX,10   ; giay co lon hon 10 khong trinh     JB    LESS_S          MOV    CX,OFFSET MAGIC_LEN­OFFSET MAGIC_CODE  ;tinh      MOV   CL,10 chieu dai chuoi     DIV   CL       ;ket qua trong AL,so du trong AH          REPE   CMPSB                ;kiem tra xem hai chuoi co bang nhau     ADD   AL,'0'          JCXZ   YET_INST             ;da co thuong tru ,ket thuc chuong trinh      MOV   CS:[SI],AL          POP    DI                   ;tra lai DI       MOV   AL,AH    ;lay so du trong AH          POP    ES                   ;tra lai ES   LESS_S: TIEP:     INC   SI          CMP    ES:[BX].IDCODE,LASTMCB ;da het MCB chua     INC   SI           JE     NOT_INST     ADD   AL,'0'          MOV    AX,ES                  ;khong thi     MOV   CS:[SI],AL          ADD    AX,ES:[BX].SIZE        ;cong ES voi SIZE+1 cua MCB     LEA   SI,DISPLAY_TM          INC    AX     MOV   CX,NUM_IN­3          MOV    ES,AX                  ;ES:BX la MCB ke tiep     MOV   DI, D_TIME          JMP    FIND_CODE     CALL  WRITE_S               RET NOT_INST: ;neu chua TSR thi khoi tao    DISPLAY_TIME ENDP           CALL  GET_NUM_DISK ;Thu tuc write_s in chuoi ra man hinh ;thay doi AX,ES,DS           ;xac dinh dia chi co in_dos 13
  14. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY           MOV   AH,34h GET_NUM_DISK  ENDP             INT   21h                 MOV   CS:DAPTR_OFS,BX  ;offset cua co DOS                      MOV   CS:DAPTR_SEG,ES  ;segment cua co DOS READPARAM       PROC NEAR            MOV    SI,80h          ;Dia chi duoi dong lenh          ;giai phong khoi moi truong truoc khi TSR          MOV    CL,[SI]         ;so do chieu dai duoi lenh                           JCXZ   NO_PARAM        ;neu khong co thi bao loi va ket thuc              MOV   ES,DX ;ES doan cua PSP cua chuong trinh se thuong tru READ_PARAM:                     ;khong thi lap voi CX=so tham so           XOR  BX,BX     ;ES:BX  chua dia chi PSP          INC    SI              ;tham so dau tien           MOV  AX,ES:[BX].ENVSEG  ;nap dia chi moi truong vao AX          MOV    BL,[SI]           MOV  ES,AX          CMP    BL,' '           MOV  AH,49h           JE     CON_READ        ;neu la ky tu trang thi doc tiep           INT  21h          CMP    BL,'/'          ;co dung lenh khong          ;lay int 13          JZ     CON_READ        ;dung thi tiep tuc           MOV   AX,3513h          CMP    BL,'U'          ;lenh vao la /U thi unload TSR          INT   21h          JZ     REMOVE          ;dung thi loai TSR ra khoi bo nho                   MOV   CS:OLD_INT13,BX          CMP    BL,'u'          MOV   CS:OLD_INT13[2],ES          JNZ    W_PARAM          ;dat int 13 REMOVE:          MOV   AX,2513h          CALL   UNLOAD          ;dung thi unload TSR          PUSH  CS          RET          POP   DS CON_READ:          MOV   DX,OFFSET INT13          LOOP   READ_PARAM          INT   21h NO_PARAM:          ;lay int 1C          MOV    DX,OFFSET YET_TSR                                           MOV   AX,351Ch          CALL   WRITE_MSG         ;khong co tham so thi in thong bao          INT   21h          RET          MOV   CS:OLD_INT1C,BX W_PARAM:           MOV   CS:OLD_INT1C[2],ES          MOV    DX,OFFSET WRONG_PARAM          ;dat int 1C          CALL   WRITE_MSG          MOV   AX,251Ch          RET                 PUSH  CS READPARAM       ENDP          POP   DS          MOV   DX,OFFSET INT1C UNLOAD    PROC NEAR      ;thu tuc de loai TSR ra khoi bo nho         INT   21h PREFIX       STRUC          ;cau truc cua PSP          MOV   DX,OFFSET INIT_TSR    DUMMY  DB 2Ch DUP(?)            CALL  WRITE_MSG    ENVSEG DW ?           ;dia chi cua moi truong          ;ket thuc va noi tru PREFIX       ENDS              MOV   DX,OFFSET INIT           ;lay dia chi cua khoi moi truong           INT   27h           MOV  DX,OLDPSP ;nap OLDPSP vao DX           MOV  AX,351Ch  ;kiem tra xem YET_INST: ;da TSR roi thi kiem tra va ket thuc chuong trinh            INT  21h       ;ngat 1CH co bi thay doi khong          POP    DI           MOV  AX,ES     ;AX chua dia chi cua ngat 1CH           POP    ES           CMP  AX,DX               MOV    AX,ES:[BX].PSP             JNE  CHANGED   ;neu khong bang thi ket thuc          MOV    OLDPSP,AX   ;nap PSP cua TSR vao OLDPSP          CALL   READPARAM              MOV  AX,3513h  ;kiem tra xem          INT    20h           INT  21h       ;ngat 13H co bi thay doi khong           MOV  AX,ES     ;AX chua dia chi cua ngat 13H  GET_NUM_DISK   PROC NEAR           CMP  AX,DX               PUSH  AX            JNE  CHANGED   ;neu khong bang thi ket thuc          PUSH  CX BEGIN_UNLOAD:            ;neu khong thay doi thi loai TSR           INT   11h           ;giai phong bo nho ,luc nay ES da chua segment PSP cua TSR          MOV   CL,6           ;PUSH ES          SHR   AX,CL           MOV  AH,49h          AND   AL,3           ;POP  ES         ;ES la dia chi doan cua TSR          INC   AL           INT  21h          CMP   AL,1   ;neu la 1 o dia           ;dat lai ngat cu           JA    GET_F  ;thi ket thuc           PUSH  DS         ;cat DS          MOV   AL,2   ;co hai o           CLI GET_F:           MOV  AX,2513h   ;dat lai ngat 13          MOV   NUM_FLOPPIES,AL           LDS  DX,ES:OLDINT13_PTR          POP   CX           INT  21h          POP   AX                     RET           MOV  AX,251Ch   ;dat lai ngat 1c 14
  15. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY           LDS  DX,ES:OLDINT1C_PTR  mov al,1           INT  21h  stosb  pop ax di si ds es           STI   iret           POP  DS                 ;tra lai DS cu             MOV  DX,OFFSET SUCCESS  ;da loai ra khoi bo nho  CONTINUE:           CALL WRITE_MSG  lea si, Make           RET  lodsb CHANGED:                  ;vec to ngat da bi doi  cmp al,0           MOV  DX,OFFSET UN_SUCCESS  pop ax di si ds es           CALL WRITE_MSG  je PASSBY           RET  cmp ah,2 UNLOAD    ENDP  je READ               cmp ah,3 WRITE_MSG   PROC NEAR  je READ           PUSH AX  PASSBY:           MOV  AH,9  jmp cs:Oldint13h           INT  21h             POP  AX  READ:           RET  cmp dl,0 WRITE_MSG   ENDP  je GOON ;khai  bao cac chuoi de thong bao  cmp dl,1 INIT_TSR    DB 'DISKLITE VERSION 1.0',13,10  jne PASSBY             DB '   COPYRIGHT (C) LE ANH TUAN 1994$'  GOON: YET_TSR     DB 'CHUONG TRINH DA THUONG TRU$'  cmp ch,0 WRONG_PARAM DB 'SAI THAM SO$'  je TRACK0 SUCCESS     DB 'CHUONG TRINH DA DUOC UNLOAD$'  cmp ch,79 UN_SUCCESS  DB 'KHONG THE UNLOAD DUOC CHUONG TRINH$'   je TRACK79 CODE     ENDS  jmp PASSBY END      START   Bài tập 10:  TRACK0: Chương trình sửa bad track 0 của đĩa mềm  add ch,79   .model tiny  jmp PASSBY   .code  org 100h  TRACK79:  start:  cmp ah,3  jmp INIT  jne COMEBACK  Oldint13h label dword  mov ah,1  Int13hofs dw    ?  stc  Int13hseg dw    ?  COMEBACK:  Make   db       1  Iret    NEWINT13H:  INIT:  push es ds si di ax  mov si,80h  push cs cs  lodsb  pop ds es  push ax  cmp ax,0FEFEh  mov ax,0FEFEh  je ALREADY  int 13h  lea di,Make  cmp ax,0EFEFh  cmp ax,0BABAh  pop ax  je EQUAL0  jne INSTALL  cmp ax,0ABABh  cmp al,1  je EQUAL1  jbe CHANGETRACK  jmp CONTINUE  mov si,82h    lodsw  ALREADY:  cmp ax,0752Fh  pop ax di si ds es  je NORMAL  mov ax,0EFEFh  cmp ax,0552Fh  iret   je NORMAL  EQUAL0:  lea dx,Error  xor al,al  call WRITE  stosb  ret  pop ax di si ds es  CHANGETRACK:  iret  mov ax,0ABABh  EQUAL1:  int 13h 15
  16. ĐHQG – HN CNTT Ngôn ngữ máy ASSEMBLY  lea dx,Mess2  call WRITE  ret  NORMAL:  mov ax,0BABAh  int 13h  lea dx,Mess1  call WRITE  ret  INSTALL:  mov ax,3513h  int 21h  mov int13hofs,bx  mov int13hseg,es  lea dx,newint13h  mov ax,2513h  int 21h  lea dx,Mess  call WRITE  lea dx,Mess2  Call WRITE  lea dx,INIT  int 27h    WRITE:  mov ah,9  int 21h   ret    Mess db 'Program repares bad track0 disk.',13,10,'Written by Hoang  Tuan Dat.',13,10,'Finish install.',13,10,'$'  Mess1 db 13,10,'Now you can not read bad track0 disk',13,10,'$'  Mess2 db 13,10,'Now you only can read bad track0 disk',13,10,'$'  Error db 'Input valid',13,10,'$'  end Start  16
Đồng bộ tài khoản