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 :
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 : ‘
Hay vao a : -4
Hay vao n : 3
-4 luy thua 3 la : -64
Co tiep tuc CT (c/k)?_
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 :
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 : ‘)
Hay vao n : 6
Giai thua cua 6 la : 720
Co tiep tuc CT (c/k)?_
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 :
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 '-$'
Hay vao so thu 1 : -12
Hay vao so thu 2 : 5
Trung binh cong 2 so nguyen la :
-3.5
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 :
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
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)?_
; 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 :
Hay vao so bi chia : -20
Hay vao so chia : 3
Thuong la : -6.66
Co tiep tuc CT (c/k)?_
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 : ‘)
Hay vao n : 3
Hay vao d : 2
Hay vao u1 : 1
Tong cap so cong la : 9
Co tiep tuc CT (c/k)?_
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 =u
i
và lúc đầu bằng u
1
)
dec cx ; Giảm cx đi 1 (n-1)
L1:
add dx,bx ; dx = u
i
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 : $ '
Hay vao n : 3
Hay vao q : 2
Hay vao u1 : 1
Tong cap so nhan la : 7
Co tiep tuc CT (c/k)?_
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 =u
i
và lúc đầu bằng u
1
)
dec cx ; Giảm cx đi 1 (n-1)
L1:
mul bx ; ax = ax*bx = u
i
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
∑
=
N
i
i
1
|
;
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
Hay vao N : 5
Tong tu 1 den 5 la : 15
Co tiep tuc CT (c/k)?_
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 a
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 a
n
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 <iotream.h>
#include <conio.h>
int a,n;
extern int LT();
void main(void)
{
clrscr();
cout<<”\nHay vao a : “; cin>>a;
cout<<”\nHay vao n : “; cin>>n;
cout<<”\n”<<a<<” luy thua “<<n<<” la : “<<LT();
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 a
n
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 <iotream.h>
#include <conio.h>
int n;
extern int LT(int i1);
void main(void)
{
int a;
clrscr();
cout<<”\nHay vao a : “; cin>>a;
cout<<”\nHay vao n : “; cin>>n;
cout<<”\n”<<a<<” luy thua “<<n<<” la : “<<LT(a);
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 a
n
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 <iotream.h>
#include <conio.h>
extern int LT(int i1, int i2);
void main(void)
{
int a,n;
clrscr();
cout<<”\nHay vao a : “; cin>>a;
cout<<”\nHay vao n : “; cin>>n;
cout<<”\n”<<a<<” luy thua “<<n<<” la : “<<LT(a,n);
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 a
n
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 <iotream.h>
#include <conio.h>
int n;
extern int GT();
void main(void)
{
clrscr();
cout<<”\nHay vao n : “; cin>>n;
cout<<”\nGiai thua cua ”<<n<<” la : “<<GT();
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 < 0 (tức là n=0 hoặc 1)
jb L2 ; Nếu n < 0 thì nhảy đến L2
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 <iotream.h>
#include <conio.h>
extern int GT(int i);
void main(void)
{
int n;
clrscr();
cout<<”\nHay vao n : “; cin>>n;
cout<<”\nGiai thưa cua ”<<n<<” la : “<<GT(n);
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 < 0 (tức là n=0 hoặc 1)
jb L2 ; Nếu n < 0 thì nhảy đến L2
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 <iotream.h>
#include <conio.h>
int so1,so2,flag=0;
extern int AVERAGE();
void main(void)
{
clrscr();
cout<<”\nHay vao so1 : “; cin>>so1;
cout<<”\nHay vao so2 : “; cin>>so2
cout<<”\nTrung binh cong 2 so nguyen la : “<<AVERAGE()+0.5*flag;
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 <iotream.h>
#include <conio.h>
int flag=0;
extern int AVERAGE(itn i1, int i2);
void main(void)
{
int so1,so2;
clrscr();
cout<<”\nHay vao so1 : “; cin>>so1;
cout<<”\nHay vao so2 : “; cin>>so2
cout<<”\nTrung binh cong 2 so nguyen la : “<<AVERAGE(so1,so2)+0.5*flag;
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 <iotream.h>
#include <conio.h>
extern int AVERAGE(itn i1, int i2,int far* i3);
void main(void)
{
int so1,so2,flag=0;
clrscr();
cout<<”\nHay vao so1 : “; cin>>so1;
cout<<”\nHay vao so2 : “; cin>>so2
cout<<”\nTrung binh cong 2 so nguyen la : “<<AVERAGE(so1,so2,&flag)+0.5*flag;
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 <iotream.h>
#include <conio.h>
int n, a[100];
extern int SUM();
void main(void)
{
clrscr();
cout<<”\nHay vao so luong thanh phan : “; cin>>n;
for (i=0;i<n;i++)
{
cout<<”\na[“<<i<<”] = “;
cin>>a[i];
cout<<”\nTong cua day so nguyen la : “<<SUM();
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 <iotream.h>
#include <conio.h>
extern int SUM(int i1, int far *i2);
void main(void)
{
int n,a[100];
clrscr();
cout<<”\nHay vao so luong thanh phan : “; cin>>n;
for (i=0;i<n;i++)
{
cout<<”\na[“<<i<<”] = “;
cin>>a[i];
cout<<”\nTong cua day so nguyen la : “<<SUM(n,a);
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
∑
=
N
i
i
1
|
;
Phân công nhiệm vụ :
− Ngôn ngữ C
++
:
• Nhận N,
• Gọi chương trình con tính
∑
=
N
i
i
1
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
i
i
1
Cách 1: Hàm Assembly không đối (N khai báo biến toàn cục)
Tệp C
++
:
#include <iotream.h>
#include <conio.h>
int N;
extern int TONG();
void main(void)
{
clrscr();
cout<<”\nHay vao n : “; cin>>N;
cout<<”\nTong tu 1 den “<<N<<” la : “<<TONG();
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 <iotream.h>
#include <conio.h>
extern int TONG(int i);
void main(void)
{
int N;
clrscr();
cout<<”\nHay vao N : “; cin>>N;
cout<<”\nTong tu 1 den ”<<N<<” la : “<<TONG(N);
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 <iotream.h>
#include <conio.h>
int n,d,u1;
extern int CSC();
void main(void)
{
clrscr();
cout<<”\nHay vao n : “; cin>>n;
cout<<”\nHay vao d : “; cin>>d;
cout<<”\nHay vao u1 : “; cin>>u1;
cout<<”\nTong cap so cong la : “<<CSC();
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 = u
i
add ax,dx ; ax = (tổng các thành phần từ u
1
đến u
i-1
) + u
i
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 <iotream.h>
#include <conio.h>
int d,u1;
extern int CSC(int i1);
void main(void)
{
int n;
clrscr();
cout<<”\nHay vao n : “; cin>>n;
cout<<”\nHay vao d : “; cin>>d;
cout<<”\nHay vao u1 : “; cin>>u1;
cout<<”\nTong cap so cong la : “<<CSC(n);
getch();
}
Tệp Assembly:
.MODEL large