Ngôn ngữ máy Assembly
lượt xem 40
download
Tài liệu về Ngôn ngữ máy Assembly...
Bình luận(0) Đăng nhập để gửi bình luận!
Nội dung Text: Ngôn ngữ máy Assembly
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT 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’ {thân segment} Hàm 1: Chờ 1 ký tự từ bàn phím: tên_segment ENDS Mov ah, 1 ;AL chứa mã ASCII ký tự mã vào trong đó: Int 21h tên_segment là 1 identifier (không chứa dấu cách, dấu \ ; : ...) Hàm 2: Đưa 1 ký tự dạng ASCII ra màn hình tại vị trí con trỏ đang align là cách xác lập khoảng cách giữa segment đang khai báo với đứng segment trước nó Cách 1: Nhờ ngắt của BIOS align Mov al, mã ASCII của ký tự byte khoảng cách 1 byte Mov ah, oeh word khoảng cách 2 byte Int 10h paka khoảng cách 16 byte Cách 2: page khoảng cách 256 byte Mov dl, mã ASCII của ký tự combine có hai chức năng: Mov ah, 2 +cho phép đặt segment vào 1 địa chỉ mong muốn (theo yêu cầu) của Int 21h bộ nhớ RAM Hàm 3: Hiện 1 xâu ký tự kết thúc bằng dấu $ ra màn hình tên_segment SEGMENT at địa_chỉ_dạng_vật_lý Mov dx, offset tên biến xâu {thân} Mov ah, 9 tên_segment ENDS Int 21h +cho chương trình đa tệp: cách gộp các segment có cùng tên nằm ở Hàm 4: Trở về DOS các tệp khác nhau khi liên kết. Ví dụ: Tệp 1 có DATA SEGMENT; Tệp 2 Mov ah, 4ch ;[int 20h] có DATA SEGMENT.khác Int 21h _COMMON tức là độ dài của segment sau liên kết bằng độ dài Các DIRECTIVE điều khiển SEGMENT dạng đơn giản: dễ viết, dễ segment lớn nhất liên kết nhưng chưa bao hết mọi tình huống về điều khiển SEGMENT _PUBLIC tức là độ dài của segment sau liên kết bằng tổng độ dài cả .Model thuê vùng nhớ RAM thích hợp cho chương trình 2 segment .Model kiểu_tiny code+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_small code≤ 64KB;data≤ 64KB chính nó (không quan hệ với nhau, đây là chế độ default) .Model kiểu_compact code≤ 64KB;data≥ 64KB _STACK giống như _PUBLIC .Model kiểu_medium code≥ 64KB;data≤ 64KB _CLASS sắp xếp các segment lại gần nhau sau khi liên kết .Model kiểu_large code≥ 64KB;data≥ 64KB song khi khai báo1 (Sau khi liên kết thì những segment nào cùng một nhóm thì ở gần nhau) array không ≤ 64KB _GROUP gộp các segment có cùng kiểu lại với nhau cho dễ dàng qui .Model kiểu_large code≥ 64KB;data≥ 64KB song khi khai báo1 chiếu array không >64KB tên_ nhóm GROUP tên_các_segment (cách nhau bởi dấu , ) .Stack Độ lớn (Byte) → Xác lập độ lớn stack cho chương trình _ASSUME cho biết tên segment thuộc loại segment nào .Data Xác lập vùng nhớ cho dữ liệu của chương trình khai báo _ASSUME tên_thanh_ghi SEG : tên_seg biến nằm ở segment này Cấu trúc một chương trình Assembly thường thấy: Khai báo .Data Khai báo biến (có 3 loại biến) MACRO, STRUCT, UNION, RECORD, SEGMENT Với các loại biến số thì kiểu db có độ dài 1 byte Dạng đơn giản dw có độ dài 2 byte .Model kiểu dd có độ dài 4 byte .Stack độ lớn dp/df có độ dài 6 byte [.Data dq có độ dài 8 byte khai báo biến] dt có độ dài 10 byte .Code Với các loại biến xâu có các cách khai báo như sau: nhãn_chương_trình: tên_biến_xâu db ‘các ký tự’ mov ax, @data tên_biến_xâu db độ_lớn dup(‘1 ký tự’) mov ds, ax tên_biến_xâu db độ_lớn dup(?) ... Với các loại biến trường số (array) có các cách khai báo như sau: thân chương trình tên_biến_trường kiểu_thành_phần (các số cách nhau bởi dấu ,) ... tên_biến_trường kiểu_thành_phần độ_lớn dup(giá trị 1 số) mov ah, 4ch tên_biến_trường kiểu_thành_phần độ_lớn dup(?) int 21h .Code Xác lập vùng nhớ truy xuất ngẫu nhiên dùng cho phần mã máy [các chương trình con] .Code END nhãn_chương_trình nhãn_chương_trình: mov ax, @data Dạng chuẩn mov ds, ax _Stack segment ... db độ_dài dup(?) thân chương trình _Stack ends ... Data segment mov ah, 4ch khai báo biến int 21h Data ends [các chương trình con] Code segment end nhãn_chương_trình 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
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT Cách 2: Chuyển vào biến hoặc thanh ghi khác sau đó hồi phục mov ds, ax ... Tệp include thân chương trình Tệp INCLUDE cho phép người lập trình viết gọ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 mov ah, 4ch lệnh Assembly .ASM int 21h Sau đó dùng lệnh INCLUDE để chèn khối lệnh đó vào tệp chương [các chương trình con] trình đang viết. Cú pháp: ENDS .............. END nhãn_chương_trình INCULDE X:\đường dẫn\tệp INCLUDE *Chương trình con: .............. 1, Cơ chế khi 1 chương trình con bị gọi: Cơ chế của chương trình dịch Assembly khi gặp INCLUDE: chương Bước 1: Tham số thực đưa vào STACK trình dịch của Tubor Assember khi gặp INCLUDE thì thực hiện các bước: Bước 2: Địa chỉ của lệnh tiếp theo được đưa vào STACK * Mở tệp INCLUDE theo sau Directive 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 * Sao chép và chèn toàn bộ khối lệnh Assembly có trong tệp INCLUDE Hệ điều hành sẽ đưa địa chỉ đó vào CS:IP → rẽ nhánh vào chương trình vào vị trí Directive Include đứng con * Tiến hành dịch khối lệnh đó Bước 4: Thực hiện thân chương trình con cho đến khi gặp lệnh RET thì Cách tìm tệp INCLUDE để chèn vào STACK lấy địa chỉ lệnh tiếp theo (đã cất ở Bước 2) và cho vào * Nếu tệp đứng sau Directive Include có tên đĩa, đường dẫn thì chương CS:IP, rồi quay về chương trình đã gọi nó 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 Bước 5: Tiếp tục thực hiện chương trình đang đợi không có nữa thì sai 2, Cú pháp của chương trình con Assembly: * Nếu sai thì chỉ có cách sửa lại chương trình nguồn. Khi dịch chương Tên_chương_trình_con PROC [NEAR/FAR] trình dùng thêm tham số TASM i A:\...\*.ASM Bảo vệ các thanh ghi sẽ bị phá vỡ ở thân chương trình Hạn chế của INCLUDE là không được phép có nhãn nhảy trong khối Thân chương trình con lệnh của tệp INCLUDE khi gọi nó 2 lần Hồi phục các thanh ghi mà chương trình con phá vỡ macro và các vấn đề liên quan RET 1, Các lệnh lặp khối lệnh khi dịch chương trình: Tên_chương_trình_con ENDP a, Vấn đề NEAR – FAR: REPT dịch khối lệnh theo số lần đi sau REPT NEAR chương trình con cùng nằm trên 1 segment với chương trình gọi REPT n Khối_lệnh nó → địa chỉ lệnh tiếp theo cất vào STACK (Bước 2) chỉ cần 2 byte ENDM 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 Cú pháp: bậc 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 Thân MACRO đổi 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 2
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT ENDM int 20h [các chương trình con] 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 Cú pháp: Public tên_nhãn Push ax, bx 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 Pop dx, 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ó Cơ chế: Giống nhau khi dịch thay 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 Liên kết C với Assembly Local. 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 .Code phép có các nhãn nhảy trong ASM → khối lệnh chèn vào yếu (vì không Nhãn_chương trình: có 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 mov ah, 4ch giống 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ó .Code assume cs:code,ds:code,ss:code giá 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 3
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT 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ẽ được đặt trên Card đó điều hành đưa địa chỉ đầu của chương trình con → cs:ip → rẽ nhánh vào Int 19h: Lôi boot sector xuống RAM và trao quyền cho chương trình chương trình con nằm trong boot sector Bước 4: Thực hiện các lệnh của chương trình con → RET thì vào Trong boot sector là sector 512 byte chứa tham số đĩa và chứa chương STACK lấy địa chỉ lệnh tiếp theo (đã cất ở bước 2) → cs:ip và trở về trình mồi 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) Bước 5: Tiếp tục chương trình đang dở Kiểm tra thiết bị ngoại vi Chương trình con phục vụ ngắt: Lôi COMMAND.COM vào vùng nhớ RAM – là chương trình dịch các Int n (tác động linh kiện) lệnh của DOS → Mã máy Bước 1: Flag → STACK;Tham số thực → STACK CONFIG.SYS Bước 2: Địa chỉ lệnh tiếp theo → STACK AUTOEXEC.BAT Bước 3: Hệ điều hành quản lý địa chỉ đầu của chương trình con phục C:\> vụ ngắt. Song địa chỉ đầu của chương trình con phục vụ ngắt nằm trong ô 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 Bài tập 1: Phục hồi các thanh ghi 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: ROMBIOS Mov AX,@DATA ROMBIOS 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 Mov AH,4Ch kiểm tra một số lệnh ASM nếu có lỗi thì hiện FATA ERROR. Int 21h Kiểm tra ROMBIOS: trong ROM có 1 byte CHECKSUM (tổng các byte END ProgramStart Cách 2: của ROM) khi khởi động thì có 1 chương trình cộng các byte của ROM lại lưu kết quả vào 1 byte và so sánh byte này với CHECKSUM. Nếu _STACK segment stack ‘stack’ bằng 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 Assume CS: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 And AL,AL chung và nạp vào ROMBIOS chuẩn → thỏa hiệp của các hãng: Ai sản Jz Stop Mov AH,0eh 4
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT 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 hien_string m2 So sánh 2 số nguyên nhập từ bàn phím xem số nào bé hơn call VAOSO Cách 1: mov bx,sohex include C:\HTDAT\INCLUDE\lib1.asm hien_string m3 _stack segment stack 'stack' cmp ax,bx db 100h dup(?) jl L1 _stack ends xchg ax,bx data segment L1: m1 db 10,13,'Vao so thu nhat:$' call HIENSO m2 db 10,13,'Vao so thu hai:$' mov ah,1 m3 db 10,13,'So be la:$' int 21h m4 db 10,13,'Co tiep tuc khong (c/k)?:$' mov ah,4ch data ends int 21h code segment ; assume cs:code,ds:data,ss:_stack VAOSO PROC ps: push ax bx cx dx mov ax,data mov bx,10 mov ds,ax xor cx,cx clrscr mov sohex,cx hienstring m1 VS1: call Vao_so_N mov ah,1 ; Ham nhan 1 ki tu va >al mov bx,ax int 21h hienstring m2 cmp al,0dh call Vao_so_N je VS2 cmp ax,bx sub al,30h jl L1 mov cl,al xchg ax,bx mov ax,sohex L1: mul bx hienstring m3 add ax,cx call Hien_so_N mov sohex,ax hienstring m4 jmp VS1 mov ah,1 VS2: int 21h pop dx cx bx ax cmp al,'c' ret je ps VAOSO ENDP mov ah,4ch ; int 21h HIENSO PROC include C:\HTDAT\INCLUDE\lib2.asm push ax bx cx dx code ends mov bx,10 end ps xor cx,cx So sánh 2 số nhập vào từ bàn phím xem số nào bé hơn HS1: Cách 2: xor dx,dx hien_string MACRO xau div bx ; tuc lay dx:ax chia cho bx kq thuong>ax va du>dx push ax dx add dx,30h ; de dua ra dang ASCCI mov dx,offset xau push dx ; tong 1 chu vao stack mov ah,9 inc cx int 21h cmp ax,0 pop dx ax jnz HS1 ENDM HS2: ; pop ax .model small mov ah,0eh .stack 100h int 10h .data loop HS2 sohex dw ? pop dx cx bx ax temp dw ? ret m1 db 0ah,0dh,'Vao so thu1: $' 5
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT HIENSO ENDP m3 db ' la:$' end ps m4 db 10,13,'Co tiep tuc khong(c/k)?: ' Bài tập 3: data ends code segment Tính trung bình cộng 2 só nguyên nhập từ bàn phím assume cs:code,ds:data,ss:_stack INCLUDE C:\INCLUDE\LIB1.ASM ps: _STACK segment mov ax,data db 100h dup(?) mov ds,ax _STACK ends clrscr DATA segment hienstring m1 M1 db ‘Hay vao so thu 1: $’ call vao_so_N M2 db 0ah,0dh,‘Hay vao so thu 2: $’ hienstring m2 M3 db 0ah,0dh,‘Trung binh cong cua 2 so nguyen la: $’ call Hien_so_N M4 db ‘$’ hienstring m3 M5 db ‘.5$’ call S_N_T M6 db 0ah,0dh,’ Co tiep tuc khong (c/k) ?: $’ mov ax,fv DATA ends call hien_so_N CODE segment hienstring m4 assume cs:code,ds:data,ss:_stack mov ah,1 ps: int 21h mov ax,data cmp al,'c' mov ds,ax je ps clrscr mov ah,4ch HienString M1 int 21h call VAO_SO_N include C:\HTDAT\INCLUDE\lib3.asm mov bx,ax include C:\HTDAT\INCLUDE\lib2.asm HienString M2 code ends call VAO_SO_N end ps HienString M3 Chương trình tính giai thừa của một số n nhập từ bàn phím Add ax,bx Cách 2: And ax,ax 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 push ax 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 dx Cách 1: mov ah,09h include C:\HTDAT\INCLUDE\lib1.asm mov dx,offset msg2 _stack segment stack 'stack' int 21h db 100h dup(?) pop dx _stack ends pop ax data segment call inra fv dw ? mov ah,01h fac dw ? int 21h m1 db 10,13,'Vao so n:$' int 20h m2 db 10,13,'Giai thua cua $' 6
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT ; 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 Bài tập 5: cmp al,0dh 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
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT 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 RET Nhập 2 số vào từ bàn phím và in ra tích của chúng CRLF ENDP EXTRN ; 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 INC CX 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
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT 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 INC CX 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: XOR AX,AX Tính tổng hai số nhập từ bàn phím MOV BL,NUMBER1 CODE_SEG SEGMENT BYTE PUBLIC ADD AL,BL ASSUME CS:CODE_SEG,DS:CODE_SEG PUSH AX ORG 100H cmp dauso1,1 START: JMP FIRST jne khongam MSG DB 'NHAP VAO 2 SO DE CONG :$' call indau MSG1 DB 'SO THU NHAT :$' jmp khongam MSG2 DB 'SO THU HAI :$' ; MSG3 DB 'TONG CUA CHUNG LA :$' khacdau: mov cl,number1 NUMBER1 DB 0 cmp cl,number2 ;SO1>SO2 ? NUMBER2 DB 0 je writeZero ja laydauso1 soam db ? ; dauso1 db ? XOR AX,AX dauso2 db ? MOV BL,NUMBER1 SUB AL,BL FIRST: MOV AH,09H PUSH AX MOV DX,OFFSET MSG INT 21H cmp dauso2,1 call cr_lf jne khongam MOV AH,09H CALL INDAU MOV DX,OFFSET MSG1 JMP KHONGAM INT 21H laydauso1: XOR AX,AX mov soam,0 MOV AL,NUMBER1 mov dauso1,0 SUB AL,NUMBER2 CALL GET_AN_INT_NUM PUSH AX cmp soam,1 cmp dauso1,1 jne so1khongam jne khongam mov dauso1,1 CALL INDAU so1khongam: CMP AX,255 khongam: Jb tieptuclam int 20h POP AX tieptuclam: MOV NUMBER1,AL CALL WRITE_INT_NUMBER CALL CR_LF jmp exit writezero: mov ax,0 MOV AH,09H call write_int_number MOV DX,OFFSET MSG2 9
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT 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
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT 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 Bài tập 9: _STACK ENDS 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 (80NUM_IN1)*2 ;offset de ghi ten o dia mov bx,2 ; cong COM 2 D_TIME EQU (82NUM_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
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT CALL DISPLAY_DRIVE CONTINUE: CALL DISPLAY_TIME XOR DL,DL POP ES INC TICKER POP DS MOV AL,TICKER POP DI CMP AL,18 ;so nhip 18.2 lan trong mot giay POP SI JB NOT_INC ;neu Chua bang thi in ra man hinh POP DX MOV TICKER,DL ;neu qua thi dat lai ticker=0 POP CX INC SECOND ;tang giay POP AX MOV AL,SECOND POPF CMP AL,60 ;neu qua 60 giay thi tang phut PUSHF JB NOT_INC CALL DWORD PTR CS:OLD_INT13 MOV SECOND,DL PUSHF INC MINUTE ;tang phut PUSH AX MOV AL,MINUTE PUSH CX CMP AL,60 PUSH SI JB NOT_INC PUSH DI MOV MINUTE,DL PUSH DS INC HOUR PUSH ES NOT_INC: LEA SI,OLD_CHARS ;CALL DISPLAY_TIME ;thu MOV DI,D_DISK ;POP ES MOV CX,NUM_IN POP DS CALL WRITE_S ;POP SI POP ES POP DI POP DS POP DX POP DI ;POP CX POP SI POP AX POP CX JMP DWORD PTR CS:OLD_INT1C POP AX INT1C ENDP POPF ;thu tuc get_display_base xac dinh doan bo nho man hinh RET 2 ; thay doi AX INT13 ENDP GET_DISPLAY_BASE PROC NEAR INT1C PROC FAR INT 11h ;lay co thiet bi ASSUME CS:CODE,DS:NOTHING AND AX,30h PUSH AX CMP AX,30h ;man hinh don sac ;PUSH CX MOV AX,0B800h PUSH DX JNE GET_BASE PUSH DI MOV AX,0B000h ;PUSH SI GET_BASE: PUSH DS MOV DISPLAY_BASE,AX ;PUSH ES RET ;LDS DI,[DAPTR] ;nap IN_DOS vao DS:DI GET_DISPLAY_BASE ENDP ;CMP BYTE PTR DI,0 ;co DOS co ban khong ;thu tuc savescreen luu manh hinh lai XOR AX,AX ;thay doi AX,si,di,ds,es,cx MOV DS,AX SAVE_SCREEN PROC NEAR MOV AL,BYTE PTR DS:[MOTOSTATUS] ;co o dia nao quay MOV SI,D_DISK ;lay dia chi bo nho man hinh khong MOV DI,OFFSET OLD_CHARS AND AL,3 MOV AX,DISPLAY_BASE CMP AL,0 MOV DS,AX ;ky tu man hinh nam tai DS:SI JNE CONTINUE ;neu ban thi tiep tuc MOV AX,CS ;MOV DX,HARDPORT ;cong dia cung chua byte so 7 la co bao MOV ES,AX ;old_chars nam tai ES:DI 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' 12
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT LEA SI,DISPLAY_DRV ;Thu tuc write_s in chuoi ra man hinh MOV CS:[SI],AL ;thay doi AX,ES,DS 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:BX2 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 MOV AL,AH ;lay so du trong AH PSP(PROG) LESS_M: JE TIEP ;co thi nhay sang MCB khac INC SI MOV AX,DS ;dia chi cua chuong trinh thuong tru INC SI SUB AX,DX ADD AL,'0' ADD AX,ES:[BX].PSP ;addr=PSP(MCB)+(segment(PROG) MOV CS:[SI],AL PSP(PROG)) ADD SI,4 ;dat SI vao offset cua second PUSH ES ;cat ES MOV CS:[SI],DL MOV ES,AX ;ES se chua doan chuong trinh thuong tru MOV AL,SECOND neu da resident XOR AH,AH PUSH DI ;cat DI CMP AX,10 ; giay co lon hon 10 khong MOV SI,DI ;DS:SI se chua magic_code cua chuong JB LESS_S trinh MOV CL,10 MOV CX,OFFSET MAGIC_LENOFFSET MAGIC_CODE ;tinh DIV CL ;ket qua trong AL,so du trong AH chieu dai chuoi ADD AL,'0' REPE CMPSB ;kiem tra xem hai chuoi co bang nhau MOV CS:[SI],AL JCXZ YET_INST ;da co thuong tru ,ket thuc chuong trinh MOV AL,AH ;lay so du trong AH POP DI ;tra lai DI LESS_S: POP ES ;tra lai ES INC SI TIEP: INC SI CMP ES:[BX].IDCODE,LASTMCB ;da het MCB chua ADD AL,'0' JE NOT_INST MOV CS:[SI],AL MOV AX,ES ;khong thi LEA SI,DISPLAY_TM ADD AX,ES:[BX].SIZE ;cong ES voi SIZE+1 cua MCB MOV CX,NUM_IN3 INC AX MOV DI, D_TIME MOV ES,AX ;ES:BX la MCB ke tiep CALL WRITE_S JMP FIND_CODE RET DISPLAY_TIME ENDP NOT_INST: ;neu chua TSR thi khoi tao 13
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT CALL GET_NUM_DISK POP CX POP AX ;xac dinh dia chi co in_dos RET 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 14
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT INT 21h pop ax di si ds es iret MOV AX,251Ch ;dat lai ngat 1c EQUAL1: 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: add ch,79 Chương trình sửa bad track 0 của đĩa mềm jmp PASSBY .model tiny .code TRACK79: org 100h cmp ah,3 start: jne COMEBACK jmp INIT mov ah,1 Oldint13h label dword stc Int13hofs dw ? COMEBACK: Int13hseg dw ? Iret Make db 1 INIT: NEWINT13H: mov si,80h push es ds si di ax lodsb push cs cs push ax pop ds es mov ax,0FEFEh cmp ax,0FEFEh int 13h je ALREADY cmp ax,0EFEFh lea di,Make pop ax cmp ax,0BABAh jne INSTALL je EQUAL0 cmp al,1 cmp ax,0ABABh jbe CHANGETRACK je EQUAL1 mov si,82h jmp CONTINUE lodsw cmp ax,0752Fh ALREADY: je NORMAL pop ax di si ds es cmp ax,0552Fh mov ax,0EFEFh je NORMAL iret lea dx,Error EQUAL0: call WRITE xor al,al ret stosb 15
- Ngôn ng ữ máy ASSEMBLY ĐHQG – HN CNTT CHANGETRACK: mov ax,0ABABh int 13h 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
CÓ THỂ BẠN MUỐN DOWNLOAD
-
Hợp Ngữ ASM-Chương 01-Phần 1- Cấu trúc máy tính
14 p | 1159 | 462
-
Tập lệnh cơ bản 8051
11 p | 1590 | 427
-
ASSEMBLER(Dai hoc quoc gia)
16 p | 887 | 233
-
Tổng quan về các ngôn ngữ lập trình
6 p | 633 | 180
-
KIẾN TRÚC MÁY TÍNH VÀ HỢP NGỮ: LẬP TRÌNH HỢP NGỮ MIPS
9 p | 1168 | 144
-
LẬP TRÌNH HỢP NGỮ MIPS
10 p | 1491 | 139
-
BÁO CÁO MÔN HỌC NGÔN NGỮ LẬP TRÌNH ASSEMBLY
17 p | 398 | 100
-
PH ẦN 1: LẬP TRÌNH HỢP NGỮ CHO HỌ x86
16 p | 745 | 89
-
Cấu trúc lập trình trong C
7 p | 180 | 44
-
[Ngôn Ngữ Máy] Đề Cương Bài Giảng Hợp Ngữ (assembly language) phần 10
9 p | 100 | 14
-
[Ngôn Ngữ Máy] Đề Cương Bài Giảng Hợp Ngữ (assembly language) phần 3
11 p | 119 | 13
-
Tổng quan về ngôn ngữ lập trình
6 p | 91 | 13
-
Assemblies - Global Assembly Cache
4 p | 100 | 11
-
[Ngôn Ngữ Máy] Đề Cương Bài Giảng Hợp Ngữ (assembly language) phần 4
11 p | 83 | 6
-
Hệ UNIX - Ngôn Ngữ C, ANSI C, ISO C, C++ phần 6
8 p | 64 | 6
-
Ngắt asm cơ bản
13 p | 104 | 4
-
Bài giảng Hợp ngữ và lập trình hệ thống: Chương 0 - Phạm Công Hòa
7 p | 83 | 4
Chịu trách nhiệm nội dung:
Nguyễn Công Hà - Giám đốc Công ty TNHH TÀI LIỆU TRỰC TUYẾN VI NA
LIÊN HỆ
Địa chỉ: P402, 54A Nơ Trang Long, Phường 14, Q.Bình Thạnh, TP.HCM
Hotline: 093 303 0098
Email: support@tailieu.vn