Thông báo

Collapse
No announcement yet.

Sử dụng Macro trong lập trong lập trình ASM cho 8051

Collapse
X
 
  • Lọc
  • Giờ
  • Show
Clear All
new posts

  • Sử dụng Macro trong lập trong lập trình ASM cho 8051

    Vấn đề này không phải là mới lạ trong lập trình, nó là một trong những tiện ích khá hay mà trình dịch mang lại. Đối với mỗi trình dịch thì cách định nghĩa macro cũng khác nhau, bài viết này tôi chỉ nói về cách định nghĩa sử dụng macro và một số macro bổ ích cho trình dịch ASEM51 thông dụng nhất hiện nay.

    Lợi ích của nó là gì, một ví dụ đơn giản trước khi bắt đầu, đó là phép so sánh lớn hơn trong ASM, việt nhớ các cờ Carry, hay cờ Z, cờ OV cho mỗi lệnh đôi khi gây ra lẫn lộn, vậy nếu định nghĩa thành công 1 lần thì sẽ dùng được ở các lần khác với 1 từ gợi nhớ, chứ không phải là các bit
    Ví dụ về định nghĩa và sử dụng Macro Jump If Great Than, sẽ nhảy đến 1 nhãn nếu giá trị của thanh ghi A lớn hơn...
    PHP Code:
    ;//định nghĩa
    %*DEFINE (JGT (VALUELABEL)) ( CJNE     A#%VALUE+1, $+3
                                   
    JNC      %LABEL
                                 

    ;
    //sử dụng

    %JGT(55hGREAT_THAN)
    ...
    GREAT_THAN:
    ... 
    Cụ thể, những lợi ích sử dụng macro như sau:

    [+] Chương trình nguồn sử dụng Macro dễ đọc hơn, dùng mã gợi nhớ, có thể nhìn chương trình một cách tổng quát
    [+] Chương trình nhìn ngắn gọn hơn (thực tế mã sinh ra không ít hơn)
    [+] Giảm thiểu các lỗi, chỉnh sửa hàng loạt
    [+] Không bận tâm đến xử lý chi tiết quá mức


    Định nghĩa Macro:
    PHP Code:
    %*DEFINE (Biểu đồ gọi) (nội dung Macro
    Ví dụ đơn giản nhất, cất thanh ghi DPTR và ngăn xếp:
    PHP Code:
    ;//Định nghĩa
    %*DEFINE (PUSH_DPTR) ( PUSH DPH
                          PUSH DPL
                        

    ;
    //sử dụng
    %PUSH_DPTR 
    Tiếp theo, việc truyền tham số cho Macro giúp chúng ta tùy biến mỗi Macro cho nhiều tình huống trong chương trình:
    PHP Code:
    %DEFINE (tên macro (danh sánh tham số)) (Nội dung macro
    Ví dụ về Macro có tham số, Skip If Equa, nếu giá trị của A khác giá trị của tham số, thì bỏ qua lệnh tiếp theo, (giống lệnh của Pic CPFSEQ )
    PHP Code:
    ;//định nghĩa
    %*DEFINE (SIE(VALUE)) ( CJNE A,#%VALUE, $+3
                           

    ;
    //Sử dụng
    %SIE(20h)
    SJMP BANG
    KHONG_BANG
    :
    ...
    BANG:
    ... 
    Tiếp theo là sử dụng các nhãn cục bộ trong Macro
    PHP Code:
    ;//Chú ý là nội dung nằm giữa cặp dấu [] là tùy chọn, có thể có hoặc không 

     
    %*DEFINE (tên macro[(danh sách tham số)])
                  [
    LOCAL danh sách nhãn] (nội dung Macro
    Ví dụ về sử dụng nhãn cục bộ, định nghĩa macro giảm giá trị của thanh ghi DPTR (chỉ có lệnh INC DPTR mà không có, nên cái này gội là ...tự chế )
    PHP Code:
    ;//Định nghĩa
    %*DEFINE (DEC_DTPRLOCAL SKIP
                    
    (DEC    DPL
                     MOV    A
    ,DPL
                     CJNE   A
    ,#0FFH, %SKIP
                     
    DEC    DPH
                
    %SKIP: )

    ;
    //sử dụng
    %DEC_DPTR 
    Ngoài ra còn có 1 số macro được định nghĩa sẵn, và công việc của chúng ta là sử dụng cho đúng mục đích
    [+] REAPEAT
    ví dụ, về Macro lặp lại 100 lần lệnh nop
    PHP Code:
    %REPEAT(100)(NOP)
    ;
    //điều này chẳng mang lại lợi lộc gì lớn lao ngoài trừ ngoài chuyện
    ;//bạn không mất công ngồi gõ 100 lần cái lệnh này
    ;//có nghĩa là trình dịch viết giúp bạn 100 lấn đấy thôi
    ;//cũng có nghĩa là mã sinh ra cũng có 100 cái lệnh này 
    [+] IF THEN
    PHP Code:
    NUM EQU 1
    %IF(NUMTHEN (
     ;
    //code ở đây, nếu NUM được định nghĩa khác 0
    ) ELSE (
    ;
    //code này được sử dụng nếu NUM được định nghĩa là 0

    Ngoài ra còn 1 lưu ý, nếu bạn định nghĩa Macro mà sau đó, nội dung xuống dòng phải có 1 dấu *
    PHP Code:
    %*DEFINE (EXAM(VALUE,LABLE))
                          *(
    CJNE A,#%VALUE,%LABEL) 
    và sau đây là một số Macro thông dụng đã sưu tập được
    PHP Code:
    ;//[*] Nhảy đến "LABEL" nếu A nhỏ hơn "VALUE"
    %DEFINE (JLT (VALUELABEL))
                *(
    cjne  a,#%VALUE, $+3
                  
    jc    %LABEL)
    ;
    //--------------------------------------------

    ;//[*] Nhảy đến "LABEL" nếu A lớn hơn "VALUE"
    %DEFINE (JGT (VALUELABEL))
                *(
    cjne  a,#%VALUE+1, $+3
                  
    jnc    %LABEL)
    ;
    //--------------------------------------------

    ;//[*] Nhảy đến "LABEL" nếu A nhỏ hơn hoặc bằng "VALUE"
    %DEFINE (JLE (VALUELABEL))
                *(
    cjne  a,#%VALUE-1, $+3
                  
    jc    %LABEL)

    ;
    //[*]Nhảy đến "LABEL" nếu A lớn hơn hoặc bằng "VALUE"
    %DEFINE (JGE (VALUELABEL))
                *(
    cjne  a,#%VALUE, $+3
                  
    jnc    %LABEL)

    ;
    //[*] Nhảy đến "LABEL" nếu A nằm ngoài (Out Of Range) dải "lower" & "upper"
    %DEFINE (JOR (lower,upperLABEL))
                *(
    cjne  a,#%lower, $+3
                  
    jc    %LABEL
                  cjne  a
    ,#%upper+1, $+3
                  
    jnc    %LABEL )

    ;
    //[*]và một số ví dụ 
    PS: Tham khảo sách của thầy Tống Văn On, Họ Vi Điều Khiển 8051 ..v..v
    Diễn đàn Vi điều khiển:

Về tác giả

Collapse

minhtuan04 Tìm hiểu thêm về minhtuan04

Bài viết mới nhất

Collapse

Đang tải...
X