bai tap ASM

CÁC BÀI TẬP MẪU THUẦN TÚY

NGÔN NGỮ ASSEMBLY

Bài 1

;--------------------------------------------------------------------------

; a lũy thừa n (với a là số nguyên và n là số nguyên dương) |

;--------------------------------------------------------------------------

Khi chương trình chạy yêu cầu có dang :

Hay vao a : -4

Hay vao n : 3

-4 luy thua 3 la : -64

Co tiep tuc CT (c/k)?_

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 13,10,'Hay vao a : $'

M2 db 13,10,'Hay vao n : $'

crlf db 13,10,'$'

M3 db ' luy thua $'

M4 db ' la : $'

M5 db 13,10,'Co tiep tuc CT (c/k)? $'

.CODE

PS:

mov ax,@data

mov ds,ax

clrscr

HienString M1 ; Hiện thông báo M1 ('Hay vao a : ')

call VAO_SO_N ; Nhận giá trị a

mov bx,ax ; bx = a

HienString M2 ; Hiện thông báo M2 ('Hay vao n : ')

call VAO_SO_N ; Nhận giá trị n

mov cx,ax ; cx = n

HienString crlf ; Quay đầu dòng và xuống hàng

mov ax,bx ; ax=a

call HIEN_SO_N ; Hiện giá trị a lên màn hình

HienString M3 ; Hiện 2 chữ ' luy thua '

mov ax,cx ; ax=n

call HIEN_SO_N ; Hiện giá trị n lên màn hình

HienString M4 ; Hiện chữ ' la : '

mov ax,1 ; Gán ax=1

and cx,cx ; Liệu giá trị n (cx=n) có bằng 0 ?

jz HIEN ; Nếu bằng 0 thì nhảy đến nhãn HIEN

LAP: ; còn không thì thực hiện vòng lặp tính a lũy thừa n

mul bx ; ax=ax*bx

loop LAP

HIEN:

call HIEN_SO_N ; Hiện giá trị a lũy thừa n (giá trị có trong ax)

HienString M5 ; Hiện thông báo M5 ('Co tiep tục CT (c/k) ?' )

mov ah,1 ; Chờ nhận 1 ký tự từ bàn phím

int 21h

cmp al,'c' ; Ký tự vừa nhận có phải là ký tự 'c' ?

jne Exit ; Nếu không phải thì nhảy đến nhãn Exit (về DOS)

jmp PS ; Còn không thì quay về đầu (bắt đầu lại chương trình)

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib2.asm

END PS

Bài 2

;----------------------

; n! (n từ 0 đến 7) |

;----------------------

Khi chương trình chạy yêu cầu có dang :

Hay vao n : 6

Giai thua cua 6 la : 720

Co tiep tuc CT (c/k)?_

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 13,10,'Hay vao n : $'

M2 db 13,10,'Giai thua cua $'

M3 db ' la : $'

M4 db 13,10,'Co tiep tuc CT (c/k)? $'

.CODE

PS:

mov ax,@data

mov ds,ax

clrscr

HienString M1 ; Hiện thông báo M1 ('Hay vao n : ')

call VAO_SO_N ; Nhận 1 số vào từ bàn phím

mov cx,ax ; cx = n

HienString M2 ; Hiện thông báo M2 ('Giai thua cua ')

call HIEN_SO_N ; Hiện giá trị n

HienString M3 ; Hiện thông báo M3 (' la : ')

mov ax,1 ; ax=1

cmp cx,2 ; Liệu n ≤ 2

jb HIEN ; Đúng là ≤ 2 thì nhảy đến nhãn HIEN

LAP: ; còn không thì thực hiện vòng lặp tính n!

mul cx ; ax=ax*cx

loop LAP

HIEN:

call HIEN_SO_N ; Hiện giá trị n! (có trong ax)

HienString M4 ; Hiện thông báo M4 ('Co tiep tuc CT (c/k) ?')

mov ah,1 ; Chờ nhận 1 ký tự từ bàn phím

int 21h

cmp al,'c' ; Ký tự vừa nhận có phải là ký tự 'c' ?

jne Exit ; Nếu không phải thì nhảy đến nhãn Exit (về DOS)

jmp PS ; Còn không thì quay về đầu (bắt đầu lại chương trình)

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib2.asm

END PS

Bài 3

;---------------------------------------

; Trung bình cộng 2 số nguyên |

;---------------------------------------

Khi chương trình chạy yêu cầu có dang :

Hay vao so thu 1 : -12

Hay vao so thu 2 : 5

Trung binh cong 2 so nguyen la : -3.5

Co tiep tuc CT (c/k)?_

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 13,10,'Hay vao so thu 1: $'

M2 db 13,10,'Hay vao so thu 2: $'

M3 db 13,10,'Trung binh cong 2 so nguyen la : $'

dautru db '-$'

M4 db '.5$'

M5 db 13,10,'Co tiep tuc CT (c/k)? $'

.CODE

PS:

mov ax,@data

mov ds,ax

clrscr

HienString M1 ; Hiện thông báo M1 ('Hay vao so thu 1 : ')

call VAO_SO_N ; Nhận giá trị số thứ 1

mov bx,ax ; bx = giá trị số thứ 1

HienString M2 ; Hiện thông báo M2 ('Hay vao so thu 2 : ')

call VAO_SO_N ; Nhận giá trị số thứ 2

HienString M3 ; Hiện thông báo M3 ('Trung binh cong 2 so nguyen la :')

add ax,bx ; Tổng 2 số (ax=ax+bx)

and ax,ax ; Giá trị tổng là âm hay dương?

jns L1 ; Tổng là dương thì nhảy đến L1

HienString dautru ; còn âm thì hiện dấu '-'

neg ax ; và đổi dấu số bị chia

L1:

shr ax,1 ; Chia đôi làm tròn dưới

pushf ; Cất giá trị cờ vào stack (thực chất là giá trị cờ Carry)

call HIEN_SO_N ; Hiện giá trị trung bình cộng làm tròn dưới

popf ; Lấy lại giá trị cờ từ stack (lấy lại trạng thái bit cờ Carry)

jnc L2 ; Nếu Carry=0 (giá trị tổng là chẳn) thì nhảy

HienString M4 ; còn Carry # 0 thì hiện thêm '.5' lên màn hình

L2:

HienString M5 ; Hiện thông báo M5 ('Co tiep tuc CT (c/k)? ')

mov ah,1 ; Chờ nhận 1 ký tự từ bàn phím

int 21h

cmp al,'c' ; Ký tự vừa nhận có phải là ký tự 'c' ?

jne Exit ; Nếu không phải thì nhảy đến nhãn Exit (về DOS)

jmp PS ; Còn không thì quay về đầu (bắt đầu lại chương trình)

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib2.asm

END PS

Bài 4

;-----------------------------

; Tổng 1 dãy số nguyên |

;-----------------------------

Khi chương trình chạy yêu cầu có dang :

Hay vao so luong thanh phan : 4

a[0] = -10

a[1] = 5

a[2] = -15

a[3] = 8

Day so vua vao la : -10 5 -15 8

Tong day so nguyen la : -12

Co tiep tuc CT (c/k)?_

INCLUDE lib1.asm

.MODEL small

.DATA

M1 db 10,13,'Hay vao so luong thanh phan : $'

M2 db 10,13,'a[$'

M3 db ']= $'

M4 db 10,13,'Day so vua vao la : $'

M5 db ' $'

M6 db 10,13,'Tong day so nguyen la : $'

M7 db 13,10,'Co tiep tuc CT (c/k) ? $'

sltp dw ?

i dw ?

a dw 100 dup(?)

.CODE

PS:

mov ax,@data

mov ds,ax

CLRSCR

HienString M1 ; Hiện thông báo M1 ('Hay vao so luong thanh phan :')

call VAO_SO_N ; Nhận số lượng thành phần

mov sltp,ax ; Cất giá trị số lượng thành phần vào biến sltp

; Vòng lặp nhận các số đưa vào mảng

mov cx,ax ; cx=số lượng thành phần (chỉ số vòng lặp LOOP)

lea bx,a ; bx là con trỏ offset của a[0]

mov i,0 ; Gán giá trị biến nhớ i=0

L1:

HienString M2 ; Hiện thông báo M2 ('a[')

mov ax,i ; Hiện giá trị i

call HIEN_SO_N

HienString M3 ; Hiện thông báo M3 ('] =')

call VAO_SO_N ; Nhận các thành phần a[i]

mov [bx],ax ; Đưa giá trị a[i] vào mảng a do bx trỏ đến

inc i ; Tăng giá trị i lên 1

add bx,2 ; bx trỏ đến thành phần tiếp theo của mảng a

loop L1

; Vòng lặp đưa các số của mảng lên màn hình

HienString M4 ; Hiện thông báo M4 ('Day so vua vao la : ')

mov cx,sltp ; cx=số lượng thành phần (chỉ số vòng lặp)

lea bx,a ; bx trỏ đến a[0]

L2:

mov ax,[bx] ; ax=a[i]

call HIEN_SO_N ; Hiện giá trị a[i] lên màn hình

HienString M5 ; Hiện 2 dấu cách (space)

add bx,2 ; bx trỏ đến thành phần tiếp theo của mảng

loop L2

; Vòng lặp tính tổng

HienString M6 ; Hiện thông báo M6 ('Tong day so nguyen la : ')

mov cx,sltp ; cx=số lượng thành phần của mảng (chỉ số vòng lặp)

lea bx,a ; bx trỏ đến a[0] (con trỏ offset)

xor ax,ax ; ax chứa tổng (lúc đầu bằng 0)

;--------------------------------------------------------------------------------------

; L3: |

; add ax,[bx] ; ax=ax+a[i] |

; add bx,2 ; bx trỏ đến thành phần tiếp theo của mảng a |

; loop L3 |

;--------------------------------------------------------------------------------------

call HIEN_SO_N ; Hiện giá trị tổng

HienString M7 ; Hiện thông báo M7 (Co tiep tuc CT (c/k) ?')

mov ah,1 ; Chờ nhận 1 ký tự từ bàn phím

int 21h

cmp al,'c' ; Ký tự vừa nhận có phải là ký tự 'c' ?

jne Exit ; Nếu không phải thì nhảy đến nhãn Exit (về DOS)

jmp PS ; Còn không thì quay về đầu (bắt đầu lại chương trình)

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib2.asm

END PS

Chú ý :

a) Tổng các thành phần âm của mảng

L3:

mov dx,[bx] ; dx = a[i]

and dx,dx ; Dựng cờ dấu (S=1 thì dx chứa số âm, S=0 thì dx chứa số dương)

jns L4 ; Nếu giá trị a[i] dương thì nhảy đến L4

add ax,[bx] ; còn giá trị a[i] âm thì cộng vào tổng nằm ở ax

L4:

add bx,2 ; bx trỏ đến thành phần tiếp theo của mảng a

loop L3

b) Tổng các thành phần dương của mảng

L3:

mov dx,[bx] ; dx = a[i]

and dx,dx ; Dựng cờ dấu (S=1 thì dx chứa số âm, S=0 thì dx chứa số dương)

js L4 ; Nếu giá trị a[i] âm thì nhảy

add ax,[bx] ; còn giá trị a[i] dương thì cộng vào tổng nằm ở ax

L4:

add bx,2 ; bx trỏ đến thành phần tiếp theo của mảng a

loop L3

c) Tổng các thành phần chẵn của mảng

L3:

mov dx,[bx] ; dx = a[i]

shr dx,1 ; Bit thấp nhất vào cờ Carry (C=1-> a[i] là lẻ, C=0 -> a[i] là chẵn)

jc L4 ; Nếu giá trị a[i] là lẻ thì nhảy đến l4

add ax,[bx] ; còn giá trị a[i] là chẵn thì thì cộng vào tổng nằm ở ax

L4:

add bx,2 ; bx trỏ đến thành phần tiếp theo của mảng a

d) Tổng các thành phần lẻ của mảng

L3:

mov dx,[bx] ; dx = a[i]

shr dx,1 ; Bit thấp nhất vào cờ Carry (C=1-> a[i] là lẻ, C=0 -> a[i] là chẵn)

jnc L4 ; Nếu giá trị a[i] là chẵn thì nhảy đến nhãn L4

add ax,[bx] ; còn giá trị a[i] là lẻ thì cộng vào tổng nằm ở ax

L4:

add bx,2 ; bx trỏ đến thành phần tiếp theo của mảng a

Bài 5

;---------------------------------------------

; Chia 2 số với số bị chia là nguyên |

; còn số chia là nguyên dương |

; ( 2 chữ số sau dấu thập phân) |

;---------------------------------------------

Khi chương trình chạy yêu cầu có dang :

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 10,13,'Hay vao so bi chia : $'

M2 db 10,13,'Hay vao so chia : $'

M3 db 10,13,'Thuong la : $ '

dautru db '-$'

daucham db '.$'

M4 db 10,13,'Co tiep tuc (c/k) ? $'

.CODE

PS:

mov ax,@data

mov ds,ax

CLRSCR ; Xóa màn hình

HienString M1 ; Hiện thông báo M1 ('Hay vao so bi chia : ')

call VAO_SO_N ; Nhận giá trị số bị chia

mov bx,ax ; bx = số bị chia

HienString M2 ; Hiện thông báo M2 ('Hay vao so chia : ')

call VAO_SO_N ; Nhận giá trị số chia (ax = số chia)

xchg ax,bx ; Đổi chéo (ax=số bị chia, bx=số chia)

HienString M3 ; Hiện thông báo M3 ('Thuong la : ')

and ax,ax ; Dựng cờ dấu của số bị chia (dấu thương cùng dấu số bị chia)

jns CHIA1 ; Nếu dấu số bị chia là dương thì nhảy đến nhãn CHIA1

HienString dautru ; còn nếu số bị chia là âm thì hiện dấu '-' lên màn hình (dấu âm)

neg ax ; Đổi dấu số bị chia (để thành số nguyên dương)

CHIA1:

xor dx,dx ; dx = 0

div bx ; dx:ax chia cho bx (ax=thương còn dx=dư)

call HIEN_SO_N ; Hiện giá trị của thương lên màn hình

and dx,dx ; Dựng cờ của phần dư (Z=1 thì dư=0, còn Z=0 thì dư≠0)

jz KT ; Dư bằng 0 thì nhảy đến kết thúc quá trình chia

HienString daucham ; còn không thì hiện dấu chấm ('.') và tiếp tục chia

mov cx,2 ; Số chữ số sau dấu thập phân

mov si,10 ; si = 10

CHIA2:

mov ax,dx ; Đưa phần dư vào ax

mul si ; Nhân phần dư cho 10

div bx ; dx:ax chia cho bx

call HIEN_SO_N ; Hiện giá trị của thương lên màn hình

and dx,dx ; Dựng cờ của phần dư (Z=1 thì dư=0, còn Z=0 thì dư≠0)

jz KT ; Phần dư bằng 0 thì nhảy đến kết thúc quá trình chia

loop CHIA2

KT:

HienString M4 ; Hiện dòng nhắc M4 ('Co tiep tuc CT (c/k) ?')

mov ah,1 ; Chờ nhận 1 ký tự từ bàn phím

int 21h

cmp al,'c' ; Ký tự vừa nhận có phải là ký tự 'c' ?

jne Exit ; Nếu không phải thì nhảy đến nhãn Exit (về DOS)

jmp PS ; Còn không thì quay về đầu (bắt đầu lại chương trình)

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib2.asm

END PS

Bài 6

;-----------------------------------------------------------------

; Tổng cấp số cộng khi biết n (số lượng thành phần) |

; d (công sai) và u1 (giá trị thành phần đầu tiên) |

;-----------------------------------------------------------------

Khi chương trình chạy yêu cầu có dang :

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 10,13,'Hay vao n : $'

M2 db 10,13,'Hay vao d : $'

M3 db 10,13,'Hay vao u1 : $ '

M4 db 10,13,' Tong cap so cong la : $'

M5 db 10,13,'Co tiep tuc (c/k) ? $'

.CODE

PS:

mov ax,@data

mov ds,ax

CLRSCR ; Xóa màn hình

HienString M1 ; Hiện thông báo M1 ('Hay vao n : ')

call VAO_SO_N ; Nhận giá trị n

mov cx,ax ; cx = n

HienString M2 ; Hiện thông báo M2 ('Hay vao d : ')

call VAO_SO_N ; Nhận giá trị d

mov bx,ax ; bx = d

HienString M3 ; Hiện thông báo M3 ('Hay vao u1 : ')

call VAO_SO_N ; Nhận giá trị u1

mov dx,ax ; dx = ax = u1 (ax = tổng = u1; dx =ui và lúc đầu bằng u1)

dec cx ; Giảm cx đi 1 (n-1)

L1:

add dx,bx ; dx = ui

add ax,dx ; ax = tổng

loop L1

HienString M4 ; Hiện thông báo M3 ('Tong cap so cong la : ')

call HIEN_SO_N ; Hiện tổng cấp số cộng

HienString M5 ; Hiện dòng nhắc M4 ('Co tiep tuc CT (c/k) ?')

mov ah,1 ; Chờ nhận 1 ký tự từ bàn phím

int 21h

cmp al,'c' ; Ký tự vừa nhận có phải là ký tự 'c' ?

jne Exit ; Nếu không phải thì nhảy đến nhãn Exit (về DOS)

jmp PS ; Còn không thì quay về đầu (bắt đầu lại chương trình)

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib2.asm

END PS

Bài 7

;-----------------------------------------------------------------

; Tổng cấp số nhân khi biết n (số lượng thành phần) |

; q (công bội) và u1 (giá trị thành phần đầu tiên) |

;-----------------------------------------------------------------

Khi chương trình chạy yêu cầu có dang :

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 10,13,'Hay vao n : $'

M2 db 10,13,'Hay vao q : $'

M3 db 10,13,'Hay vao u1 : $ '

M4 db 10,13,' Tong cap so nhan la : $'

M5 db 10,13,'Co tiep tuc (c/k) ? $'

.CODE

PS:

mov ax,@data

mov ds,ax

CLRSCR ; Xóa màn hình

HienString M1 ; Hiện thông báo M1 ('Hay vao n : ')

call VAO_SO_N ; Nhận giá trị n

mov cx,ax ; cx = n

HienString M2 ; Hiện thông báo M2 ('Hay vao q : ')

call VAO_SO_N ; Nhận giá trị q

mov bx,ax ; bx = q

HienString M3 ; Hiện thông báo M3 ('Hay vao u1 : ')

call VAO_SO_N ; Nhận giá trị u1

mov si,ax ; si = ax = u1 (si = tổng = u1; ax =ui và lúc đầu bằng u1)

dec cx ; Giảm cx đi 1 (n-1)

L1:

mul bx ; ax = ax*bx = ui

add si,ax ; si = tổng

loop L1

HienString M4 ; Hiện thông báo M3 ('Tong cap so nhan la : ')

mov ax,si ; Chuyển tổng từ si đến ax

call HIEN_SO_N ; Hiện tổng cấp số nhân

HienString M5 ; Hiện dòng nhắc M4 ('Co tiep tuc CT (c/k) ?')

mov ah,1 ; Chờ nhận 1 ký tự từ bàn phím

int 21h

cmp al,'c' ; Ký tự vừa nhận có phải là ký tự 'c' ?

jne Exit ; Nếu không phải thì nhảy đến nhãn Exit (về DOS)

jmp PS ; Còn không thì quay về đầu (bắt đầu lại chương trình)

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib2.asm

END PS

Bài 8

;---------------------------

; Tính biểu thức |

;---------------------------

Khi chương trình chạy yêu cầu có dang :

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 10,13,'Hay vao N : $'

M2 db 10,13,'Tong tu 1 den $'

M3 db 10,13,' la : $ '

M4 db 10,13,'Co tiep tuc (c/k) ? $'

.CODE

PS:

mov ax,@data

mov ds,ax

CLRSCR ; Xóa màn hình

HienString M1 ; Hiện thông báo M1 ('Hay vao N : ')

call VAO_SO_N ; Nhận giá trị N

mov cx,ax ; cx = N (chỉ số vòng lặp)

HienString M2 ; Hiện thông báo M2 ('Tong tu 1 den ')

call HIEN_SO_N ; Hiện giá trị N

HienString M3 ; Hiện thông báo M3 (' la : ')

dec cx ; Giảm cx đi 1 (n-1)

L1:

add ax,cx ; ax = ax+cx

loop L1

call HIEN_SO_N ; Hiện giá trị biểu thức

HienString M4 ; Hiện dòng nhắc M4 ('Co tiep tuc CT (c/k) ?')

mov ah,1 ; Chờ nhận 1 ký tự từ bàn phím

int 21h

cmp al,'c' ; Ký tự vừa nhận có phải là ký tự 'c' ?

jne Exit ; Nếu không phải thì nhảy đến nhãn Exit (về DOS)

jmp PS ; Còn không thì quay về đầu (bắt đầu lại chương trình)

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib2.asm

END PS

LIÊN KẾT NGÔN NGỮ BẬC CAO VỚI ASSEMBLY

Bài 1

;--------------------------------------------------------------------------

; a lũy thừa n (với a là số nguyên và n là số nguyên dương) |

;--------------------------------------------------------------------------

Phân công nhiệm vụ :

 Ngôn ngữ C++ :

• Nhận a và n,

• Gọi chương trình con tính an do Assembly viết,

• Hiện kết quả lên màn hình.

 Ngôn ngữ Assembly : Chương trình con tính an

Cách 1: Hàm Assembly không đối (a và n khai báo biến toàn cục)

Tệp C++:

#include

#include

int a,n;

extern int LT();

void main(void)

{

clrscr();

cout

Hay vao a : "; cin>>a;

cout

Hay vao n : "; cin>>n;

cout

"

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _a:word, _n:word

.CODE

PUBLIC @LT$qv

@LT$qv PROC

mov bx,_a ; bx = a

mov cx,_n ; cx = n

mov ax,1 ; ax = 1

and cx,cx ; Dựng cờ để xét liệu n = 0

jz L2 ; Nếu n = 0 thì nhảy đến L2

L1:

mul bx ; còn n # 0 thì tiến hành vòng lặp tính an

loop L1

L2:

ret

@LT$qv ENDP

END

Cách 2: Hàm Assembly có 1 đối (a là tham số thực và n vẫn khai báo biến toàn cục)

Tệp C++:

#include

#include

int n;

extern int LT(int i1);

void main(void)

{

int a;

clrscr();

cout

Hay vao a : "; cin>>a;

cout

Hay vao n : "; cin>>n;

cout

"

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _n:word

.CODE

PUBLIC @LT$qi

@LT$qi PROC

push BP ; Cất giá trị BP hiện thời vào stack

mov BP,SP ; BP = SP

mov bx,[BP+6] ; bx = a (lấy giá trị a trong stack đưa vào bx)

mov cx,_n ; cx = n

mov ax,1 ; ax = 1

and cx,cx ; Dựng cờ để xét liệu n = 0

jz L2 ; Nếu n = 0 thì nhảy đến L2

L1:

mul bx ; còn n # 0 thì tiến hành vòng lặp tính an

loop L1

L2:

pop BP ; Hồi phục giá trị của BP

ret

@LT$qi ENDP

END

Cách 3: Hàm Assembly có 2 đối (a và n đều là tham số thực)

Tệp C++:

#include

#include

extern int LT(int i1, int i2);

void main(void)

{

int a,n;

clrscr();

cout

Hay vao a : "; cin>>a;

cout

Hay vao n : "; cin>>n;

cout

"

getch();

}

Tệp Assembly:

.MODEL large

.CODE

PUBLIC @LT$qii

@LT$qii PROC

push BP

mov BP,SP

mov bx,[BP+6] ; bx = a (lấy giá trị a trong stack đưa vào bx)

mov cx,[BP+8] ; cx = n (lấy giá trị n trong stack đưa vào cx)

mov ax,1 ; ax = 1

and cx,cx ; Dựng cờ để xét liệu n = 0

jz L2 ; Nếu n = 0 thì nhảy đến L2

L1:

mul bx ; còn n # 0 thì tiến hành vòng lặp tính an

loop L1

L2:

pop BP ; Hồi phục giá trị BP

ret

@LT$qii ENDP

END

Bài 2

;----------------------

; n! (n từ 0 đến 7) |

;----------------------

Phân công nhiệm vụ :

 Ngôn ngữ C++ :

• Nhận n,

• Gọi chương trình con tính n! do Assembly viết,

• Hiện kết quả lên màn hình.

 Ngôn ngữ Assembly : Chương trình con tính n!

Cách 1: Hàm Assembly không đối (n khai báo biến toàn cục)

Tệp C++:

#include

#include

int n;

extern int GT();

void main(void)

{

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Giai thua cua "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _n:word

.CODE

PUBLIC @GT$qv

@GT$qv PROC

mov cx,_n ; cx = n

mov ax,1 ; ax = 1

cmp cx,2 ; So sánh n

jb L2 ; Nếu n

L1:

mul cx ; còn n ≥ 0 thì tiến hành vòng lặp tính n!

loop L1

L2:

ret

@GT$qv ENDP

END

Cách 2: Hàm Assembly có 1 đối (n là tham số thực)

Tệp C++:

#include

#include

extern int GT(int i);

void main(void)

{

int n;

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Giai thưa cua "

getch();

}

Tệp Assembly:

.MODEL large

.CODE

PUBLIC @GT$qi

@GT$qi PROC

push BP

mov BP,SP

mov cx,[BP+6] ; cx = a (lấy giá trị n trong stack đưa vào cx)

mov ax,1 ; ax = 1

cmp cx,2 ; So sánh n

jb L2 ; Nếu n

L1:

mul cx ; còn n ≥ 0 thì tiến hành vòng lặp tính n!

loop L1

L2:

pop BP ; Hồi phục giá trị BP

ret

@GT$qi ENDP

END

Bài 3

;---------------------------------------

; Trung bình cộng 2 số nguyên |

;---------------------------------------

Phân công nhiệm vụ :

 Ngôn ngữ C++ :

• Nhận 2 số nguyên,

• Gọi chương trình con tính trung bình cộng do Assembly viết,

• Hiện kết quả lên màn hình.

 Ngôn ngữ Assembly : Chương trình con tính trung bình cộng 2 số nguyên

Cách 1: Hàm Assembly không đối (so1, so2 và flag khai báo biến toàn cục)

Tệp C++:

#include

#include

int so1,so2,flag=0;

extern int AVERAGE();

void main(void)

{

clrscr();

cout

Hay vao so1 : "; cin>>so1;

cout

Hay vao so2 : "; cin>>so2

cout

Trung binh cong 2 so nguyen la : "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _so1:word,_so2:word,_flag:word

.CODE

PUBLIC @AVERAGE$qv

@AVERAGE$qv PROC

mov ax,_so1 ; ax = so1

mov bx,_so2 ; ax = so2

add ax,bx ; ax = ax + bx (ax = so1 + so2)

sar ax,1 ; ax = chia đôi làm tròn dưới

jnc L1 ; Nếu tổng là chẵn (C=0) thì nhảy đến L1

mov cx,1 ; còn không thì biến cờ flag =1

mov _flag,cx

L1:

ret

@AVERAGE$qv ENDP

END

Cách 2: Hàm Assembly có 2 đối (giá trị so1,so2 là tham số thực - cất vào stack, còn flag vẫn là biến toàn cục)

Tệp C++:

#include

#include

int flag=0;

extern int AVERAGE(itn i1, int i2);

void main(void)

{

int so1,so2;

clrscr();

cout

Hay vao so1 : "; cin>>so1;

cout

Hay vao so2 : "; cin>>so2

cout

Trung binh cong 2 so nguyen la : "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _flag:word

.CODE

PUBLIC @AVERAGE$qii

@AVERAGE$qii PROC

push BP

mov BP,SP

mov ax,[BP+6] ; ax = so1

mov bx,[BP+8] ; ax = so2

add ax,bx ; ax = ax + bx (ax = so1 + so2)

sar ax,1 ; ax = chia đôi làm tròn dưới

jnc L1 ; Nếu tổng là chẵn (C=0) thì nhảy đến L1

mov cx,1 ; còn không thì biến cờ flag =1

mov _flag,cx

L1:

pop BP ; Hồi phục giá trị BP

ret

@AVERAGE$qii ENDP

END

Cách 3: Hàm Assembly có 3 đối (giá trị so1,so2, flag là tham số thực - cất vào stack)

Tệp C++:

#include

#include

extern int AVERAGE(itn i1, int i2,int far* i3);

void main(void)

{

int so1,so2,flag=0;

clrscr();

cout

Hay vao so1 : "; cin>>so1;

cout

Hay vao so2 : "; cin>>so2

cout

Trung binh cong 2 so nguyen la : "

getch();

}

Tệp Assembly:

.MODEL large

.CODE

PUBLIC @AVERAGE$qiini

@AVERAGE$qiini PROC

push BP

mov BP,SP

mov ax,[BP+6] ; ax = so1

mov bx,[BP+8] ; ax = so2

add ax,bx ; ax = ax + bx (ax = so1 + so2)

sar ax,1 ; ax = chia đôi làm tròn dưới

jnc L1 ; Nếu tổng là chẵn (C=0) thì nhảy đến L1

mov cx,1 ; còn không thì biến cờ flag =1

les bx,[BP+10] ; es:[bx] trỏ đến vùng nhớ chứa biến cờ flag

mov es:[bx],cx

L1:

pop BP ; Hồi phục giá trị BP

ret

@AVERAGE$qiini ENDP

END

Bài 4

;---------------------------------------

; Tính tổng một dãy số nguyên |

;---------------------------------------

Phân công nhiệm vụ :

 Ngôn ngữ C++ :

• Nhận số lượng thành phần n,

• Nhận các số của dãy số đưa vào một mảng,

• Gọi chương trình con tính tổng các thành phần của mảng do Assembly viết,

• Hiện kết quả lên màn hình.

 Ngôn ngữ Assembly : Chương trình con tính tổng các thành phần của mảng.

Cách 1: Hàm Assembly không đối (n và địa chỉ a[0] khai báo biến toàn cục)

Tệp C++:

#include

#include

int n, a[100];

extern int SUM();

void main(void)

{

clrscr();

cout

Hay vao so luong thanh phan : "; cin>>n;

for (i=0;i

{

cout

a["

cin>>a[i];

cout

Tong cua day so nguyen la : "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _n:word, _a:dword

.CODE

PUBLIC @SUM$qv

@SUM$qv PROC

mov cx,_n ; cx = n

mov ax,SEG _a ; ax = phần địa chỉ segment của a[0]

mov es,ax ; es = phần địa chỉ segment của a[0]

mov bx,OFSET _a ; bx = phần địa chỉ offset của a[0]

xor ax,ax ; ax = tổng và lúc đầu tổng = 0

L1:

add ax.es:[bx] ; ax = ax + a[i] (do es:[bx] trỏ đến)

add bx,2 ; bx trỏ đến thành phần tiếp theo của mảng a

loop L1

ret

@SUM$qv ENDP

END

Cách 2: Hàm Assembly có 2 đối (n và địa chỉ a[0] là tham số thực của hàm-để vào stack)

Tệp C++:

#include

#include

extern int SUM(int i1, int far *i2);

void main(void)

{

int n,a[100];

clrscr();

cout

Hay vao so luong thanh phan : "; cin>>n;

for (i=0;i

{

cout

a["

cin>>a[i];

cout

Tong cua day so nguyen la : "

getch();

}

Tệp Assembly:

.MODEL large

.CODE

PUBLIC @SUM$qini

@SUM$qini PROC

push BP

mov BP,SP

mov cx,[BP+6] ; cx = n (lấy từ stack)

les bx,[BP+8] ; es:[bx] trỏ đến a[0]

xor ax,ax ; ax = tổng lúc đầu tổng = 0

L1:

add ax.es:[bx] ; ax = ax + a[i] (do es:[bx] trỏ đến)

add bx,2 ; bx trỏ đến thành phần tiếp theo của mảng a

loop L1

pop BP ; Hồi phục giá trị BP

ret

@SUM$qini ENDP

END

Bài 5

;-----------------------------------------

; Tính biểu thức |

;-----------------------------------------

Phân công nhiệm vụ :

 Ngôn ngữ C++ :

• Nhận N,

• Gọi chương trình con tính do Assembly viết,

• Hiện kết quả lên màn hình.

 Ngôn ngữ Assembly : Chương trình con tính

Cách 1: Hàm Assembly không đối (N khai báo biến toàn cục)

Tệp C++:

#include

#include

int N;

extern int TONG();

void main(void)

{

clrscr();

cout

Hay vao n : "; cin>>N;

cout

Tong tu 1 den "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _N:word

.CODE

PUBLIC @TONG$qv

@TONG$qv PROC

mov cx,_N ; cx = N

mov ax,cx ; ax = N

dec cx ; cx= N-1

L1:

add ax,cx ; ax = tổng

loop L1

L2:

ret

@TONG$qv ENDP

END

Cách 2: Hàm Assembly có 1 đối (N là tham số thực)

Tệp C++:

#include

#include

extern int TONG(int i);

void main(void)

{

int N;

clrscr();

cout

Hay vao N : "; cin>>N;

cout

Tong tu 1 den "

getch();

}

Tệp Assembly:

.MODEL large

.CODE

PUBLIC @TONG$qi

@TONG$qi PROC

push BP

mov BP,SP

mov cx,[BP+6] ; cx = a (lấy giá trị n trong stack đưa vào cx)

mov ax,cx ; ax = N

dec cx ; cx= N-1

L1:

add ax,cx ; ax = tổng

loop L1

L2:

pop BP ; Hồi phục giá trị BP

ret

@TONG$qi ENDP

END

Bài 6

;-----------------------------------------------------------------

; Tổng cấp số cộng khi biết n (số lượng thành phần) |

; d (công sai) và u1 (giá trị thành phần đầu tiên) |

;-----------------------------------------------------------------

Phân công nhiệm vụ :

 Ngôn ngữ C++ :

• Nhận n,d và u1,

• Gọi chương trình con tính tổng cấp số cộng do Assembly viết,

• Hiện kết quả lên màn hình.

 Ngôn ngữ Assembly : Chương trình con tính tổng cấp số cộng

Cách 1: Hàm Assembly không đối (n,d và u1 khai báo biến toàn cục)

Tệp C++:

#include

#include

int n,d,u1;

extern int CSC();

void main(void)

{

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Hay vao d : "; cin>>d;

cout

Hay vao u1 : "; cin>>u1;

cout

Tong cap so cong la : "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _n:word, _d:word,_u1:word

.CODE

PUBLIC @CSC$qv

@CSC$qv PROC

mov cx,_n ; cx = n

mov bx,_d ; bx = d

mov ax,_u1 ; ax = u1

mov dx,ax ; dx = u1

dec cx ; cx = n-1

L1:

add dx,bx ; dx = ui

add ax,dx ; ax = (tổng các thành phần từ u1 đến ui-1) + ui

loop L1

ret

@CSC$qv ENDP

END

Cách 2: Hàm Assembly có 1 đối (n là tham số thực - cất vào stack, còn d,u1 vẫn là biến toàn cục)

Tệp C++:

#include

#include

int d,u1;

extern int CSC(int i1);

void main(void)

{

int n;

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Hay vao d : "; cin>>d;

cout

Hay vao u1 : "; cin>>u1;

cout

Tong cap so cong la : "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _d:word, _u1:word

.CODE

PUBLIC @CSC$qi

@CSC$qi PROC

push BP

mov BP,SP

mov cx,[BP+6] ; cx = n (lấy giá trị n từ stack)

mov bx,_d ; bx = d

mov ax,_u1 ; ax = u1

mov dx,ax ; dx = u1

dec cx ; cx = n-1

L1:

add dx,bx ; dx = ui

add ax,dx ; ax = (tổng các thành phần từ u1 đến ui-1) + ui

loop L1

pop BP ; Hồi phục giá trị của BP

ret

@CSC$qi ENDP

END

Cách 3: Hàm Assembly có 2 đối (n, d là tham số thực - cất vào satck, còn u1 vẫn là biến toàn cục)

Tệp C++:

#include

#include

int u1;

extern int CSC(int i1,int i2);

void main(void)

{

int n,d;

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Hay vao d : "; cin>>d;

cout

Hay vao u1 : "; cin>>u1;

cout

Tong cap so cong la : "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _u1:word

.CODE

PUBLIC @CSC$qii

@CSC$qii PROC

push BP

mov BP,SP

mov cx,[BP+6] ; cx = n (lấy giá trị n từ stack)

mov bx,[BP+8] ; bx = d (lấy giá trị d từ stack)

mov ax,_u1 ; ax = u1

mov dx,ax ; dx = u1

dec cx ; cx = n-1

L1:

add dx,bx ; dx = ui

add ax,dx ; ax = (tổng các thành phần từ u1 đến ui-1) + ui

loop L1

pop BP ; Hồi phục giá trị BP

ret

@CSC$qii ENDP

END

Cách 4: Hàm Assembly có 3 đối (n, d và u1 đều là tham số thực - cất vào satck)

Tệp C++:

#include

#include

extern int CSC(int i1,int i2,int i3);

void main(void)

{

int n,d,u1;

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Hay vao d : "; cin>>d;

cout

Hay vao u1 : "; cin>>u1;

cout

Tong cap so cong la : "

getch();

}

Tệp Assembly:

.MODEL large

.CODE

PUBLIC @CSC$qiii

@CSC$qiii PROC

push BP

mov BP,SP

mov cx,[BP+6] ; cx = n (lấy giá trị n từ stack)

mov bx,[BP+8] ; bx = d (lấy giá trị d từ stack)

mov ax,[BP+10] ; ax = u1 (lấy từ stack)

mov dx,ax ; dx = u1

dec cx ; cx = n-1

L1:

add dx,bx ; dx = ui

add ax,dx ; ax = (tổng các thành phần từ u1 đến ui-1) + ui

loop L1

pop BP ; Hồi phục giá trị BP

ret

@CSC$qiii ENDP

Bài 7

;-----------------------------------------------------------------

; Tổng cấp số nhân khi biết n (số lượng thành phần) |

; q (công bội) và u1 (giá trị thành phần đầu tiên) |

;-----------------------------------------------------------------

Phân công nhiệm vụ :

 Ngôn ngữ C++ :

• Nhận n,q và u1,

• Gọi chương trình con tính tổng cấp số nhân do Assembly viết,

• Hiện kết quả lên màn hình.

 Ngôn ngữ Assembly : Chương trình con tính tổng cấp số nhân

Cách 1: Hàm Assembly không đối (n,q và u1 khai báo biến toàn cục)

Tệp C++:

#include

#include

int n,q,u1;

extern int CSN();

void main(void)

{

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Hay vao q : "; cin>>q;

cout

Hay vao u1 : "; cin>>u1;

cout

Tong cap so cong la : "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _n:word, _q:word,_u1:word

.CODE

PUBLIC @CSN$qv

@CSN$qv PROC

mov cx,_n ; cx = n

mov bx,_q ; bx = q

mov ax,_u1 ; ax = u1

mov si,ax ; si = u1

dec cx ; cx = n-1

L1:

mul bx ; ax = ui *q

add si,ax ; si = (tổng các thành phần từ u1 đến ui-1) + ui

loop L1

mov ax,si ; Đưa giá trị tổng có ở si vào ax

ret

@CSN$qv ENDP

END

Cách 2: Hàm Assembly có 1 đối (n là tham số thực - cất vào stack, còn q và u1 vẫn là biến toàn cục)

Tệp C++:

#include

#include

int q,u1;

extern int CSN(int i1);

void main(void)

{

int n;

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Hay vao d : "; cin>>d;

cout

Hay vao u1 : "; cin>>u1;

cout

Tong cap so cong la : "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _q:word,_u1:word

.CODE

PUBLIC @CSN$qi

@CSN$qi PROC

push BP

mov BP,SP

mov cx,[BP+6] ; cx = n (lấy giá trị n từ stack)

mov bx,_q ; bx = q

mov ax,_u1 ; ax = u1

mov si,ax ; si = u1

dec cx ; cx = n-1

L1:

mul bx ; ax = ui *q

add si,ax ; si = (tổng các thành phần từ u1 đến ui-1) + ui

loop L1

mov ax,si ; ax = giá trị tổng

pop BP ; Hồi phục giá trị BP

ret

@CSN$qi ENDP

END

Cách 3: Hàm Assembly có 2 đối (n, q là tham số thực - cất vào satck, còn u1 vẫn là biến toàn cục)

Tệp C++:

#include

#include

int u1;

extern int CSN(int i1,int i2);

void main(void)

{

int n,q;

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Hay vao d : "; cin>>d;

cout

Hay vao u1 : "; cin>>u1;

cout

Tong cap so cong la : "

getch();

}

Tệp Assembly:

.MODEL large

.DATA

EXTRN _u1:word

.CODE

PUBLIC @CSN$qii

@CSN$qii PROC

push BP

mov BP,SP

mov cx,[BP+6] ; cx = n (lấy giá trị n từ stack)

mov bx,[BP+8] ; bx = q (lấy giá trị d từ stack)

mov ax,_u1 ; ax = u1

mov si,ax ; si = u1

dec cx ; cx = n-1

L1:

mul bx ; ax = ui *q

add si,ax ; si = (tổng các thành phần từ u1 đến ui-1) + ui

loop L1

mov ax,si ; ax = giá trị tổng

pop BP ; Hồi phục giá trị BP

ret

@CSN$qii ENDP

END

Cách 4: Hàm Assembly có 3 đối (n, q và u1 đều là tham số thực - cất vào satck)

Tệp C++:

#include

#include

extern int CSN(int i1,int i2,int i3);

void main(void)

{

int n,q,u1;

clrscr();

cout

Hay vao n : "; cin>>n;

cout

Hay vao q : "; cin>>d;

cout

Hay vao u1 : "; cin>>u1;

cout

Tong cap so cong la : "

getch();

}

Tệp Assembly:

.MODEL large

.CODE

PUBLIC @CSN$qiii

@CSN$qiii PROC

push BP

mov BP,SP

mov cx,[BP+6] ; cx = n (lấy giá trị n từ stack)

mov bx,[BP+8] ; bx = q (lấy giá trị q từ stack)

mov ax,[BP+10] ; ax = u1 (lấy từ stack)

mov si,ax ; si = u1

dec cx ; cx = n-1

L1:

mul bx ; ax = ui

add si,ax ; si = (tổng các thành phần từ u1 đến ui-1) + ui

loop L1

mov ax,si ; ax = tổng cấp số nhân

pop BP ; Hồi phục giá trị BP

ret

@CSN$qiii ENDP

END

CÁC BÀI TẬP LẬP TRÌNH HỆ THỐNG

Bài 1

Hãy viết chương trình cho biết máy tính bạn đang dùng có ổ mềm nào hay không? Nếu có thì bao nhiêu ổ?

Cách giải : Chú ý byte của có địa chỉ 0:410h của vùng dữ liệu ROM BIOS có chứa các thông tin liên quan đến thông tin về ổ đĩa mềm, cụ thể như sau :

x

x x

Khi chương trình chạy yêu cầu có dạng :

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 'May tinh dang dung co o mem không ? $'

co db 'Co $'

khong db ' Khong $'

M2 db 13,10,'So luong o mem ma may tinh co la : $'

.CODE

PS:

mov ax,@data

mov ds,ax

CLRSCR

HienString M1 ; Hiện thông báo ('May tinh dang dung co o mem khong ?')

int 11h ; Ngắt hệ thống thực hiện việc đưa nội dung ô nhớ 0:410h -> al

shr al,1 ; Đưa bit thấp nhất vào bit cờ Carry

jc L1 ; Nếu bit cờ Carry=1 thì nhảy đến L1

HienString khong ; còn khômg thì hiện thông báo 'Khong'

jmp Exit ; Nhảy đến nhãn Exit

L1:

HienString co ; Hiện thông báo 'Co'

HienString M2 ; Hiện thông báo 'So luong o mem ma may tinh co la : '

mov cl,5 ; Chuyển 2 bit (số lượng ổ mềm -1) sang phải 5 lần

shr al,cl

inc al ; al = số lượng ổ mềm

add al,30h ; al là mã ASCII số lượng ổ mềm

mov ah,0eh ; Chức năng hiện 1 ký tự ASCII lên màn hình

int 10h

Exit:

mov ah,4ch ; Về DOS

int 21h

END PS

Bài 2

Hãy viết chương trình cho biết máy tính bạn đang dùng có cổng COM nào hay không? Nếu có thì bao nhiêu cổng và cho biết địa chỉ các cổng đó (địa chỉ cổng phải là HEXA).

Cách giải : Chú ý byte của có địa chỉ 0:411h của vùng dữ liệu ROM BIOS có chứa các thông tin liên quan đến thông tin về số lượng cổng COM mà máy tính đang dùng có, cụ thể như sau :

x x x

Chú ý : Địa chỉ COM1 có trong 2 byte có địa chỉ 0:400h và 0:401h

Địa chỉ COM2 có trong 2 byte có địa chỉ 0:402h và 0:403h

....

Khi chương trình chạy yêu cầu có dạng :

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 'May tinh dang dung co cong COM không ? $'

co db 'Co $'

khong db ' Khong $'

M2 db 13,10,'So luong cong COM ma may tinh co la : $'

M4 db 13,10,'Dia chi cac cong COM la : $'

space db ' $'

.CODE

PS:

mov ax,@data

mov ds,ax

CLRSCR

HienString M1 ; Hiện thông báo 'May tinh dang dung co cong COM khong ?'

int 11h ; Ngắt hệ thống thực hiện việc đưa nội dung ô nhớ 0:411h -> ah

mov al,ah ; Đưa nội dung 0:411h -> al

and al,00001110b ; Tách 3 bit chứa số lượng cổng COM

shr al,1 ; al = số lượng cổng COM

jnz L1 ; Nếu al # 0 (có cổng COM thì nhảy)

HienString khong ; còn không thì hiện thông báo 'Khong'

jmp Exit ; Nhảy đến nhãn Exit

L1:

HienString co ; Hiện thông báo 'Co'

mov cl,al

xor ch,ch ; cx = số lượng cổng COM (chỉ số vòng lặp hiện địa chỉ)

HienString M2 ; Hiện thông báo 'So luong cong COM ma may tinh co la : '

add al,30h ; al là mã ASCII số lượng cổng COM

mov ah,0eh ; Chức năng hiện 1 ký tự ASCII lên màn hình

int 10h

HienString M3 ; Hiện thông báo 'Dia chi cac cong COM la : '

xor ax,ax

mov es,ax

lea bx,400h ; es:bx = 0:400h (nơi chứa địa chỉ cổng COM1)

L2:

mov ax,es:[bx] ; ax = địa chỉ COM

call HIEN_HEXA ; Hiện địa chỉ dạng HEXA lên màn hình

HienString space ; Hiên một số dấu cách

add bx,2 ; bx trỏ đến các byte chứa địa chỉ cổng COM tiếp theo

loop L2

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib3.asm ; lib3.asm chứa chương trình con HIEN_HEXA

END PS

lib3.asm

;---------------------------------------------------

; Chương trình con hiện nội dung có trong |

; thanh ghi AX lên màn hình dạng HEXA |

;---------------------------------------------------

HIEN_HEXA PROC

push ax bx cx dx

mov bx,16 ; bx = 16 là số chia

xor cx,cx ; cx = số lương lần cất phần dư (sau khi chia vào stack)

xor dx,dx ; dx = 0

div bx ; dx:ax chia cho bx (16)

cmp dx,10 ; So sánh phần dư với 10

jb HX1 ; Nếu phần dư ≤ 10 thì nhảy đến HX1

add dx,7 ; Cộng phần dư với 7

HX1:

add dx,30h ; Chuyển sang dạng ASCII

push dx ; Cất vào stack

inc cx ; Đếm số lần cất vào stạck (chỉ số vòng lặp sau này)

and ax,ax ; Dựng cờ Z (Liệu thương bằng/khác 0)

jnz HX1 ; Nếu thương chưa bằng 0 thì nhảy đến tiếp tục chia

HX2: ; Còn thương bằng 0 thì thiết lập vòng lặp lôi các sô (dạng ASCII

pop ax ; vào AL để hiện)

mov ah,0eh ; Chức năng hiện 1 ký tự ASCII nằm ở AL lên màn hình

int 10h

loop HX2

pop dx cx bx ax

ret

HIEN_HEXA ENDP

Bài 3

Hãy viết chương trình cho biết máy tính bạn đang dùng có cổng LPT nào hay không? Nếu có thì bao nhiêu cổng và cho biết địa chỉ các cổng đó (địa chỉ cổng phải là HEXA).

Cách giải : Chú ý byte của có địa chỉ 0:411h của vùng dữ liệu ROM BIOS có chứa các thông tin liên quan đến thông tin về số lượng cổng LPT mà máy tính đang dùng có, cụ thể như sau :

x x

Chú ý : Địa chỉ LPT1 có trong 2 byte có địa chỉ 0:408h và 0:409h

Địa chỉ LPT2 có trong 2 byte có địa chỉ 0:40ah và 0:40bh

....

Khi chương trình chạy yêu cầu có dạng :

Chú ý : Giống bài 2

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 'May tinh dang dung co cong LPT không ? $'

co db 'Co $'

khong db ' Khong $'

M2 db 13,10,'So luong cong LPT ma may tinh co la : $'

M4 db 13,10,'Dia chi cac cong LPT la : $'

space db ' $'

.CODE

PS:

mov ax,@data

mov ds,ax

CLRSCR

HienString M1 ; Hiện thông báo 'May tinh dang dung co cong LPT khong ?'

int 11h ; Ngắt hệ thống thực hiện việc đưa nội dung ô nhớ 0:411h -> ah

mov al,ah ; Đưa nội dung 0:411h -> al

mov cl,6

shr al,cl ; al = số lượng cổng LPT

jnz L1 ; Nếu al # 0 (có cổng LPT thì nhảy)

HienString khong ; còn không thì hiện thông báo 'Khong'

jmp Exit ; Nhảy đến nhãn Exit

L1:

HienString co ; Hiện thông báo 'Co'

mov cl,al

xor ch,ch ; cx = số lượng cổng LPT (chỉ số vòng lặp hiện địa chỉ)

HienString M2 ; Hiện thông báo 'So luong cong LPT ma may tinh co la : '

add al,30h ; al là mã ASCII số lượng cổng LPT

mov ah,0eh ; Chức năng hiện 1 ký tự ASCII lên màn hình

int 10h

HienString M3 ; Hiện thông báo 'Dia chi cac cong LPT la : '

xor ax,ax

mov es,ax

lea bx,408h ; es:bx = 0:408h (nơi chứa địa chỉ cổng LPT1)

L2:

mov ax,es:[bx] ; ax = địa chỉ LPT

call HIEN_HEXA ; Hiện địa chỉ dạng HEXA lên màn hình

HienString space ; Hiên một số dấu cách

add bx,2 ; bx trỏ đến các byte chứa địa chỉ cổng COM tiếp theo

loop L2

Exit:

mov ah,4ch ; Về DOS

int 21h

INCLUDE lib3.asm ; lib3.asm chứa chương trình con HIEN_HEXA

END PS

Bài 4

Hãy viết chương trình cho biết máy tính bạn đang dùng có card điều khiển màn hình loại gì (mono hay color)?

Cách giải : Chú ý byte của có địa chỉ 0:410h của vùng dữ liệu ROM BIOS có chứa các thông tin liên quan đến loại card điều khiển màn hình, cụ thể như sau :

x x

Khi chương trình chạy yêu cầu có dạng :

INCLUDE lib1.asm

.MODEL small

.STACK 100h

.DATA

M1 db 'Loai card dieu khien man hinh ma may tinh co la : $'

color db 'Color $'

mono db 'Mono $'

.CODE

PS:

mov ax,@data

mov ds,ax

CLRSCR

HienString M1 ; Hiện 'Loai card dieu khien man hinh ma may tinh co la :'

int 11h ; Ngắt hệ thống thực hiện việc đưa nội dung ô nhớ 0:410h -> al

and al,00110000b ; Tách 2 bit có thông tin liên quan đến loại card đ/k màn hình

cmp al,00110000b ; Liệu có phải loại card điều khiển màn hình là mono?

jne L1 ; Không phải là card mono thì nhảy đến L1

HienString mono ; còn phải thì hiện thông báo 'Mono'

jmp Exit ; Nhảy đến nhãn Exit

L1:

HienString color ; Hiện thông báo 'Color'

Exit:

mov ah,4ch ; Về DOS

int 21h

END PS

Bạn đang đọc truyện trên: AzTruyen.Top

Tags: #qaaaa