微算機原理與實驗 (UEE 2301/1071) Chap 4. MCS-51 Assembly Language Programming 宋開泰 Office:EE709 Phone:5731865( 校內分機 :31865) E-mail:ktsong@mail.nctu.edu.tw URL:http://isci.cn.nctu.edu.tw 1
Assembly Language and Assembler 1. 微控器或微處理器所能執行的是二進制程式碼 (Binary codes), 又稱機器碼 (Machine codes) 2. 機器碼指令很難為程式設計者所瞭解或記憶, 因此每一指令有其助憶碼 (Mnemonic) 3. 程式設計者藉由助憶碼來瞭解各指令之作用, 由此助憶碼所編寫的即是組合語言 (Assembly Language) 指令或程式 4. 組合語言指令必須先轉換成機器碼指令, 然後載入程式記憶體 (Program memory) 中交由微控器執行 5. 將組合語言轉換成機器碼的過程稱為組譯 (Assemble), 做這件工作的程式稱為組譯器 (Assembler) 例如 : MOV A, R7 11101111 (=EFH) Assembler 2
Assembly Language Program Format 1. 組合語言程式之編撰, 通常有四個欄位 (Fields) 標記欄 (Label Field ) 操作欄 (Operation or Mnemonic Field ) 操作元欄 (Operand Field ) 註解欄 (Comment Field ) Label : Operation Operand ; Comment (Mnemonic) 例如 : Test : MOV A, R0 ; move R0 to A ADD A, R1 3
Label 1. 一個 Label 代表它後面指令 ( 或 Data) 的位址 2. 一個 Label 通常用來代表一個跳躍指令的進入點 例如 : JMP DELAY DELAY: 3. 在 Assembling 時,Assembler 會計算出真正的位址來取代 Label 4
Operation (Mnemonic) 1. 操作碼欄可能有下列兩類程式碼 : A. 指令助憶碼 (Mnemonic) B. Directive or pseudo instruction 2. 指令助憶碼可被 Assembler 組譯成機器碼 例如 MOV, ADD, 3. Pseudo instruction or directive, 不會被組譯器組譯成機器碼, 但能幫助 Assembler 產生最後可執行的機器碼 例如 ORG, DB, EQU 5
Operand 1. 組合語言的 Operand 欄位中可能有一個或兩個 Operand, 也有可能沒有 Operand 2. 操作元的個數由指令決定 例如 : MOV A, R0 ;2 個操作元 INC R1 RET ;1 個操作元 ; 沒有操作元 6
Comment 1. 組合語言程式較難閱讀, 加入註解可增加可讀性 2. Comment 通常在程式中指令的最後一個欄位, 在 Assembly 的過程中,Comment 將被忽略, 不作處理 3. 通常註解欄是以分號 (;) 放在開始位置, Assembler 能忽略分號後的資料 因此, 註解可以出現在程式中任何位置, 不會影響程式的執行 4. 分號若出現在程式中一行之開頭, 則此行將被忽略 7
Lab #0 範例 ORG MOV START: MOV LOOP: MOV MOVC CJNE SJMP OUT: MOV ACALL INC SJMP DELAY: MOV DELAY1: MOV DELAY2: DJNZ DJNZ RET ORG DB DB DB END 00H DPTR,#0300H R3,#00H A,R3 A,@A+DPTR A,#11111111B,OUT START P1,A DELAY R3 LOOP R0,#FFH R7,#80H R7,DELAY2 R0,DELAY1 300H 00000001B, 00000010B, 00000100B, 00001000B 00010000B, 00100000B, 01000000B, 10000000B 11111111B 8
8051 組譯器 (Assembler) 與連結器 (Linker) 使用說明 Part I 9
8051 ICE 模擬器 (In Circuit Emulator, ICE) ICE 的主要功能是即時模擬 8051 的特性的, 輔助微算機系統之設計與開發 10
ICE 畫面 工具列 Data Memory 內容 暫存器內容 Memory 內容 11
8051 程式開發流程 程式原始碼 ( 文字檔 *.asm) X8051 目的檔 (*.obj) 目的檔 (*.obj) 目的檔 (*.obj) 目的檔 (*.obj) LINKER 機械碼 (*.hex) 12
8051 程式開發流程 X8051 將程式原始碼組譯成二元 (binary) 的目的檔 (object file) 目的檔是由機械碼組成, 但無法直接執行, 因為機械碼中有些位址資料必須由連結程式 (Linker) 決定 連結程式輸出十六進制檔 (.HEX 檔案 ), 可以讓 ICE 使用或者燒錄到 8051 中 13
建立原始碼 使用文書編輯軟體 ( 如 Windows 中的筆記本 ) 編輯程式內容 編輯完畢存檔, 附檔名為.asm ( 例如 LED.asm) 14
建立原始碼 ( 範例 ) ;=== 簡易跑馬燈 === LEDport reg P1 ; 輸出至 Port1 ORG 0H LOOP2: MOV R1, #07H ; 迴圈變數 MOV A, #11111110B ; 跑馬燈初始狀態 LOOP1: MOV LEDport, A ; 顯示 ACALL DELAY2 RL A ; 往左 shift DJNZ R1, LOOP1 AJMP LOOP2 DELAY2: MOV R3, #0FFH DELAY: MOV R4, #0FFH DELAY1: DJNZ R4, DELAY1 DJNZ R3, DELAY RET 15
建立原始碼 ( 注意事項 ) 分號 (;) 後文字皆為註解 ;=== 簡易跑馬燈 === LEDport reg P1 ORG 0H LOOP2: MOV R1,#07H ; 迴圈變數 指令前必須為標記或空格 標記與常數設定前面不可有空格 分號 (;) 後文字皆為註解 16
組譯原始碼 在 Windows 中直接將寫好的.asm 拖到 x8051 程式上放開 17
組譯原始碼 或者先執行 X8051 8051 Macro Assembler Copyright (C) 1990 by 2500AD Software Inc. Version 5.00b DOS/16M Run-Time Copyright (C) 1987-89 by Rational Systems, Inc. Version 3.88 Listing Destination (N, T, D, E, L, P, <CR> = N) : Input Filename : led Output Filename : ( 所要組譯的程式 ) 18
組譯原始碼 沒有錯誤的話最後就會出現以下畫面 2500 A.D. 8051 Macro Assembler - Version 5.00b ------------------------------------------------ Input Filename : led.asm Output Filename : led.obj Lines Assembled : 15 Assembly Errors : 0 19
組譯原始碼 用於參考及除錯之用的列表檔 (.lst 檔 ), 由使用者自行選擇是否需要產生 產生的方式可以由一開始參數決定, 參數有 (N,T,D,E,L,P) 參數選項如下 : N(None): 不產生列表檔 ( 預設值 ) T(Terminal): 列表檔在螢幕上顯示列表檔 D(Disk): 將列表檔存於磁碟片上, 檔名為原始檔的檔名, 但附檔名為 lst E(Error): 設定錯誤輸出的方式, 選擇後出現下列選項 : Error Only Listing Destination (T, D, P, <CR>=T) : T(Terminal) 顯示於螢幕上 D(Disk) 存於磁碟片上 P(Printer) 從印表機印出來 P(Printer): 列表檔直接從印表機印出來 20
組譯原始碼 範例 : 選擇 T, 在螢幕顯示 2500 A.D. 8051 Macro Assembler - Version 5.00b ------------------------------------------------ Input Filename : led.asm Output Filename : led.obj 1 0090 LEDport reg P1 2 0000 ORG 0H 3 0000 79 07 LOOP2: MOV R1,#07H ; 迴圈變數 4 0002 74 FE MOV A,#11111110B ; 跑馬燈初始狀態 5 0004 F5 90 LOOP1: MOV LEDport,A ; 輸出 6 0006 11 0D ACALL DELAY2 7 0008 23 RL A ; 往左 shift 8 0009 D9 F9 DJNZ R1,LOOP1 9 000B 01 00 AJMP LOOP2 10 000D 7B FF DELAY2: MOV R3,#FFH 11 000F 7C FF DELAY: MOV R4,#FFH 12 0011 DC FE DELAY1: DJNZ R4,DELAY1 13 0013 DB FA DJNZ R3,DELAY 14 0015 22 RET 15 Lines Assembled : 15 Assembly Errors : 0 21
連結 執行 link51.exe 2500 A.D. Linker Copyright (C) 1990 by 2500AD Software Inc. Version 5.00f DOS/16M Run-Time Copyright (C) 1987-89 by Rational Systems, Inc. Version 3.88 Input Filename : led Enter Offset For 'CODE' : Input Filename : Output Filename : Library Filename : ( 所要連結的 obj 檔 ) Options (D,P,U A,C,M,N,R,S,Z E,H,T,X,1,2,3 <CR> = Default) : 22
常用假指令列表 假指令 : 由組譯器提供方便設定以及撰寫程式 ORG:ORG 表示程式的起始位址, 程式經過組譯後是由 ORG 所指令的位址開始存放機器碼 EQU: 指定 EQU 後面的數值給 EQU 前面的標記 例 :VAR1 EQU 50H 即 VAR1=50H END: 程式結束時加 END 假指令, 表示組譯到此結束, 之後的程式碼忽略 23
常用假指令列表 REG: 由使用者自己定義暫存器 例 :OUT REG P0 即 OUT=P0 DB : 定義一個位元組 (Byte) 的資料給某記憶體位址 DB 是 Define Byte 的縮寫 DW: 定義兩個位元組資料 (16Bit) 給某記億體位址 DW 是 Define Word 的縮寫 CALL: 自動選擇 ACALL/LCALL JMP: 自動選擇 SJMP/ AJMP/LJMP 24
語法 數值表示方法 : 二進制 (Binary):B 例 : 10110011b 八進制 (Octal):O 或 Q( 建議以 Q 來標示, 因為 O 與 0 常會被人誤認 ) 例 :25q 十進制 (Decimal):D 或不指定 十六進制 (HexDecimal):H 例 : 0f2h char: 使用單引號或雙引號區分例 : "L" 或 'L' ASCII String: 使用單引號或雙引號區分例 : David Young" 或 'David Young' 25
語法 運算 ( 可預先計算常數值 ): 可用 + - * div / mod 等運算 高位元組 (High Byte) : 要載入 16 位元值的高 8 位元組時可使用 > 符號 例 : MOV TH0,#>-5000 低位元組 (Low Byte) : 要載入 16 位元值的低 8 位元組時可使用 < 符號 例 : MOV TL0,#<-5000 26
語法 位址 : 標記 (Labels) : 所有的標記都應使用英文字母開始, 最長可用 32 個字元 建議標記最好擺在列的開頭 ( 即前面無空格 ), 若不是擺在第一行時必須在標記的最後加上一個 ":". 或 $ : 代表程式計數器 (Program Counter, PC) 的值, 也就是指令本身的位址 27
To store program codes To store Interrupt vectors Program Memory Interrupt Vector Address RESET 0000H (0) External Interrupt 0 0003H (3) Internal Timer/counter 0 000BH (11) External Interrupt 1 0013H (19) Internal Timer/counter 1 001BH (27) Serial Port 0023H (35) External Timer/counter 2 002BH (43) When MCS-51 grants an external hardware interrupt (e.g. RESET), instructions stored in the address begin at a corresponding interrupt vector are executed. The value loaded into the program counter (PC) is determined by the interrupt vector. (e.g. the system RESET vector is 0000H). 28
Range of Program Memory Except the RESET, the interrupt vector space for each hardware interrupt is 8 bytes. This is normally not large enough for an interrupt service routine (ISR). Therefore, usually an unconditional jump instruction (JMP) is placed in the vector address. The range of program memory is 64K bytes When EA = V CC ( EA: External Access, pin 31). A. If the address is less than 4K (8051, 0000H~0FFFH) or 8K (8052, 0000H~1FFFH), the CPU will fetch chip internal memory. B. If the address is larger than 4K (8051), 8K (8052), the CPU will fetch the external memory for instructions. When EA = 0V, the CPU will fetch the external memory, the maximum range is 64K. 29
External Program Memory Program memory can only be read, it may not be written into during execution. When MCS-51 uses external memories, P0 and P2 are used as address bus, (P0: AD0~AD7, P2, A8~A15). The control signals for external memory access: ALE (Address Latch Enable) A. An output signal B. 1 0, To trigger an external latch into latch P0 (A0~A7) PSEN (Program Store Enable) A. An output signal B. 0: To enable a memory IC to output data to P0 for MCS-51 to read. Instruction for read program memories: MOVC MOVC A, @ A+PC; (A)+(PC)=address A (accumulator) register is the destination of program memory read. 30
RAM, to store data Internal Data Memory Data Memory Low 128 bytes (00H~7FH), 8031/8051/8751/8052 High 128 bytes (80H~FFH), A. Special Function Register (SFR) 8031/8051/8751/8052 B. Data memory, 8052 External Data Memory: 64 K 8031/8051/8751/8052 Control signals for access external data memory A. ALE (Address Latch Enable) B. RD (Read) output signal P3.7 0: To let external RAM put Data (D0~D7) to P0. MOVX A, @ R1; 8-bit address MOVX A, @ DPTR; 16-bit address 31
8051 組譯器 (Assembler) 與連結器 (Linker) 使用說明 Part II 32
語法 巨集 (MACRO): 自己定義一段程式成為一新指令例如在程式開頭撰寫以下程式 : ; 宣告巨集 OUTPUT OUTPUT MACRO DATA MOV P1, A MOV R5, #DATA DJNZ R5, $ ENDM ; 結束宣告 則程式中寫到 OUTPUT 5 的部分在組譯時會被取代為 MOV P1, A MOV R5, #5 DJNZ R5, $ 33
1 用文書編輯軟體編輯程式 : 範例 : 利用 EDITOR 編輯下列程式 ( 或用其他文書編輯軟體 ), 編輯完畢將其存檔, 並將檔名設為 LED.ASM START: ORG JMP ORG 0H START 10H CLR C ;(C)=0 MOV A,#0FFH ;(A)=FFH MOV R4,#8 ;(R4)=8 34
LOOP: LOOP1: DELAY: RLC MOV MOV CALL DJNZ MOV RRC MOV MOV CALL DJNZ JMP DJNZ RET END A P1,A R5,#10 DELAY R4,LOOP R4,#8 A P1,A R5,#5 DELAY R4,LOOP1 START R5,$ 35
LED.LST 檔案的內容如下 : *************< SOCURE CODE LIST REPORT BY EP51.EXE >************* FILE : C:\SIM51\LED.ASM DATE : 1999/12/27 -------------------------- 1 0000 ORG 0H 2 0000 020010 JMP START 3 0003 ORG 10H 4 0010 START: 5 0010 C3 CLR C 6 0011 74FF MOV A,#FFH 7 0013 7C08 MOV R4,#8 8 0015 LOOP: 9 0015 33 RLC A 10 0016 F590 MOV P1,A 11 0018 7D0A MOV R5,#10 12 001A 12002D CALL DELAY 13 001D DCF6 DJNZ R4,LOOP 14 001F ; 15 001F 7C08 MOV R4,#8 16 0021 LOOP1: 17 0021 13 RRC A 18 0022 F590 MOV P1,A 19 0024 7D05 MOV R5,#5 20 0026 12002D CALL DELAY 21 0029 DCF7 DJNZ R4,LOOP1 22 002B 0110 JMP START 23 002D DELAY: 24 002D DDFE DJNZ R5,$ 25 002F 22 RET 26 0030 END Total compile line : 27 Total error message : 0 36
ORG 0H JMP START ORG 10H START: CLR C ;(C)=0 MOV A,#FFH ;(A)=FFH MOV R4,#8 ;(R4)=8 LOOP: RLC A MOV P1,A MOV R5,#10 DJNZ R5, $ DJNZ R4,LOOP MOV R4,#8 LOOP1: RRC A MOV P1,A MOV R5,#5 DJNZ R5, $ 改為巨集 OUTPUT DJNZ JMP END R4,LOOP1 START 37
1. 直接將此巨集定義放在原始程式最開頭位置 OUTPUT MACRO DATA MOV P1, A MOV R5, #DATA DJNZ R5, $ ENDM ORG 0H JMP START ORG 10H START: CLR C ;(C)=0 MOV A,#FFH ;(A)=FFH MOV R4,#8 ;(R4)=8 LOOP: RLC A OUTPUT 10 DJNZ R4,LOOP MOV R4,#8 LOOP1: RRC A OUTPUT 5 DJNZ R4,LOOP1 JMP START END 38
組譯結果 : *************< SOCURE CODE LIST REPORT BY EP51.EXE >************* FILE : C:\SIM51\TEST.ASM DATE : 1999/12/27 -------------------------- 1 0000 OUTPUT MACRO DATA 2 0000 MOV P1, A 3 0000 MOV R5, #DATA 4 0000 DJNZ R5, $ 5 0000 ENDM 6 0000 ORG 0H 7 0000 020010 JMP START 8 0003 ORG 10H 9 0010 C3 START: CLR C ;(C)=0 10 0011 74FF MOV A,#FFH ;(A)=FFH 11 0013 7C08 MOV R4,#8 ;(R4)=8 12 0015 33 LOOP: RLC A 13 0016 OUTPUT 10 14 0016 F590 MOV P1, A 15 0018 7D0A MOV R5, #10 16 001A DDFE DJNZ R5, $ 17 001C DCF6 DJNZ R4,LOOP 18 001E 7C08 MOV R4,#8 19 0020 13 LOOP1: RRC A 20 0021 OUTPUT 5 21 0021 F590 MOV P1, A 22 0023 7D05 MOV R5, #5 23 0025 DDFE DJNZ R5, $ 24 0027 DCF7 DJNZ R4,LOOP1 25 0029 0110 JMP START 26 002B END Total compile line : 29 Total error message : 0 39
2. 將巨集定義存放在檔案 TEST2.ASM 中, 在原始程式最開頭位置用虛擬指令 INCLUDE 將此檔案包括進來 TEST1.ASM : INCLUDE TEST2.ASM ORG 0H JMP START ORG 10H START: CLR C MOV A,#FFH MOV R4,#8 LOOP: RLC A OUTPUT 10 DJNZ R4,LOOP MOV R4,#8 LOOP1: RRC A OUTPUT 5 DJNZ R4,LOOP1 JMP START END TEST2.ASM : OUTPUT MACRO DATA MOV P1, A MOV R5, #DATA DJNZ R5, $ ENDM 40
組譯結果 : *************< SOCURE CODE LIST REPORT BY EP51.EXE >************* FILE : test1.asm DATE : 1999/12/27 -------------------------- 1 0000 INCLUDE TEST2.ASM 2 0000 3 0000 OUTPUT MACRO DATA 4 0000 MOV P1, A 5 0000 MOV R5, #DATA 6 0000 DJNZ R5, $ 7 0000 ENDM 8 0000 020010 JMP START 9 0003 ORG 10H 10 0010 C3 START: CLR C 11 0011 74FF MOV A,#FFH 12 0013 7C08 MOV R4,#8 13 0015 33 LOOP: RLC A 14 0016 OUTPUT 10 15 0016 F590 MOV P1, A 16 0018 7D0A MOV R5, #10 17 001A DDFE DJNZ R5, $ 18 001C DCF6 DJNZ R4,LOOP 19 001E 7C08 MOV R4,#8 20 0020 13 LOOP1: RRC A 21 0021 OUTPUT 5 22 0021 F590 MOV P1, A 23 0023 7D05 MOV R5, #5 24 0025 DDFE DJNZ R5, $ 25 0027 DCF7 DJNZ R4,LOOP1 26 0029 0110 JMP START 27 002B END Total compile line : 30 Total error message : 0 41
實驗單板模組 編號 單板模組名稱 F1 MCS-51 SBC F2 EM78P156 & EM78447 MCU F3 7 SEG & DOT MATRIX Display F4 LED Display F5 RS-232 F6 KEYBOARD 4*4 F7 SW-DIP8 & DEBOUNCE CIRCUIT F8 POWER Module F9 LCD, 7SEGx4 Display F10 A/D D/A Converters F11 BUZZER, STEPPING MOTOR,SERIAL FLASH ROM
Lab #1 實驗硬體 LED Demo Board (F4) SW-DIP 8 Demo Board (F7)
46
DEMO 1. 請撰寫一個程式, 做出閃爍燈, 其燈號變化如下,LED 每過 1 秒閃爍 1 次
2. 撰寫一個程式, 做出跑馬燈, 其燈號變化如下所示, 並設定其時間間隔為 1 秒
Lab#1 LED 跑馬燈 & 指撥開關實驗 SW-DIP 8 Demo Board (F7) 49
A:00011111 (X) -------------------------------------------------------------------------------------------------------------- 將 A 反相 : 11100000 (O) 50
實驗步驟 1) 連接 Port 1 至 LED 2) 連接 Port 0 至 SW-DIP 8 的 JP05, 並將 JP03 短路 3) 撰寫讀取 SW-DIP 8 的狀態 4) 撰寫控制燈號亮滅之主迴圈 51
JP03 JP05 52
參考流程圖 1.0 53
DEMO 項目 請撰寫一個程式, 使得 LED 的閃爍與指撥開關同步, 閃爍之時間為亮 2 秒 暗 1 秒 54
會遇到的問題 開關與 LED 非同步 55