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 - Pdf 21

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

;
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

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’ ?

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:

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

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

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)

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:

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) |
;

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();

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

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>

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

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>

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];

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

=
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

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
++


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();
}


Nhờ tải bản gốc

Tài liệu, ebook tham khảo khác

Music ♫

Copyright: Tài liệu đại học © DMCA.com Protection Status