Tải bản đầy đủ (.doc) (61 trang)

Tuyển tập các bài tập và lời giải về lập trình hệ thống của PGS,TS Đặng Thanh Sơn

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (304.56 KB, 61 trang )

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

×