bai tap mau ASM

Màu nền
Font chữ
Font size
Chiều cao dòng

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 :

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 :

Hay vao n : 

3

Hay vao d :  

2

Hay vao u1 :

1

Tong cap so cong la : 9

Co tiep tuc CT (c/k)?_

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 :

Hay vao n : 

3

Hay vao q :  

2

Hay vao u1 :

1

Tong cap so nhan la : 7

Co tiep tuc CT (c/k)?_

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 :

Hay vao N : 

5

Tong tu 1 den 5 la :  

15

Co tiep tuc CT (c/k)?_

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 <iotream.h>

#include <conio.h>

int a,n;

extern int LT();

void main(void)

{

                        clrscr();

                        cout<<”

Hay vao a : “; cin>>a;

                        cout<<”

Hay vao n : “; cin>>n;

                        cout<<”

”<<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 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 <iotream.h>

#include <conio.h>

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

”<<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 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 <iotream.h>

#include <conio.h>

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

”<<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 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 <iotream.h>

#include <conio.h>

int n;

extern int GT();

void main(void)

{

                        clrscr();

                        cout<<”

Hay vao n : “; cin>>n;

                        cout<<”

Giai 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<<”

Hay vao n : “; cin>>n;

                        cout<<”

Giai 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<<”

Hay vao so1 : “; cin>>so1;

                        cout<<”

Hay vao so2 : “; cin>>so2

                        cout<<”

Trung 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<<”

Hay vao so1 : “; cin>>so1;

                        cout<<”

Hay vao so2 : “; cin>>so2

                        cout<<”

Trung 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<<”

Hay vao so1 : “; cin>>so1;

                        cout<<”

Hay vao so2 : “; cin>>so2

                        cout<<”

Trung 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<<”

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

                        for (i=0;i<n;i++)

                           {

                             cout<<”

a[“<<i<<”] = “;

                             cin>>a[i];

                        cout<<”

Tong 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<<”

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

                        for (i=0;i<n;i++)

                           {

                             cout<<”

a[“<<i<<”] = “;

                             cin>>a[i];

                        cout<<”

Tong 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

  |

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

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 <iotream.h>

#include <conio.h>

int N;

extern int TONG();

void main(void)

{

                        clrscr();

                        cout<<”

Hay vao n : “; cin>>N;

                        cout<<”

Tong 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<<”

Hay vao N : “; cin>>N;

                        cout<<”

Tong 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<<”

Hay vao n : “; cin>>n;

                        cout<<”

Hay vao d : “; cin>>d;

                        cout<<”

Hay vao u1 : “; cin>>u1;

                        cout<<”

Tong 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 = 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 <iotream.h>

#include <conio.h>

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 : “<<CSC(n);

                        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 <iotream.h>

#include <conio.h>

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 : “<<CSC(n,d);

                        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 <iotream.h>

#include <conio.h>

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 : “<<CSC(n,d,u1);

                        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 <iotream.h>

#include <conio.h>

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 : “<<CSN();

                        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 <iotream.h>

#include <conio.h>

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 : “<<CSN(n);

                        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 <iotream.h>

#include <conio.h>

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 : “<<CSN(n,q);

                        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 <iotream.h>

#include <conio.h>

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 : “<<CSN(n,q,u1);

                        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

số lượng ổ mềm -1

1… có ổ mềm

0… không có ổ mềm

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

May tinh dang dung co o mem khong ? Co

So luong o mem la : 1

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

0 0 0… không có cổng COM

0 0 1… có 1 cổng COM

0 1 0. .. có 2 cổng COM

0 1 1… có 3 cổng COM

. . .

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 :

May tinh dang dung co cong COM khong ? Co

So luong cong COM  la : 2

Dia chi cac cong COM la : 3f8  2f8

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

0  0 … không có cổng LPT

0  1… có 1 cổng LPT

1  0. .. có 2 cổng LPT

1  1… có 3 cổng LPT

. . .

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 :

May tinh dang dung co cong LPT khong ? Co

So luong cong LPT  la : 4

Dia chi cac cong LPT la : 3BC  378  278  9F0

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

   1  1 … mono

≠ 1  1 … color

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

Loai card dieu khien man hinh ma may tinh co la : Color

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: Truyen2U.Pro