# Chapter 6 Assembly Language Programming for PIC18F: Part 1 ###### tags: `microcontroller` ## Introduction - code 會轉成 ASCII 後再被 assembler 轉成 Binary Op-Code 。 - 如果在 operand 只有寫數字,沒有多餘的表示符號,一律會被視為 16 進位。 - 如果要被視為 ASCII characters 要表示成 '(string)' or A'(string)' 。 - **ORG** 表示開始程式碼的 starting address 。 - (variable) **EQU** (value) ,可以使 variable 賦值,之後可以當 literal 使用,也可以拿來當作 address 使用。 - **DB** 用來存 8-bit wide 的數, **DW** 用來存 16-bit wide 的數。 :::warning 這邊我在 mplab 裡面執行都找不到存進去的數值到底在哪裡,哭阿。 ( 應該是從 ORG 開始存? ) ::: - 要記得 low byte 會先存, high byte 後存。 - assembler 會把 source file ( .asm ) 轉成 object file ( .obj & .lst )。 - .obj 是一個 binary file containing the mechine code and data 。 - .lst 是一個 list file shows how the assembler interpretes the source file 。 ## PIC18F Instruction Format - 分四種: 1. Byte-oriented operations - 多有以下三種 operands : 1. The file register ( specified by 'f' ) 2. The destination of the result ( specified by 'd' ) 3. The access memory ( specified by 'a' ) 2. Bit-oriented operations - 有以下三種 operands : 1. The file register ( specified by 'f' ) 2. The bit in the file register ( specified by 'b' ) 3. The accessed memory ( specified by 'a' ) 3. Literal operations 4. Control operations - 大部分的 instructions 是 16-bit wide 但只有 4 個 instructions 是 double-word instruction ( 32-bit wide ),而且執行會佔用 two instruction cycles 。 ## PIC18F Instruction Set - PIC18F contains a total of 75 core instructions. - all instructions 由以下 10 項延伸而來: 1. Data movement instructions 2. Arigthmetic instructions 3. Logic instructions 4. Rotate instructions 5. Bit manipulation insturctions 6. Jump/Branch instructions 7. Test, Compare, and Skip instructions 8. Table Read/Write instructions 9. Subroutine instructions 10. System control insturctions - 講了一堆指令,去做實驗你就會ㄌ :::info - 使用 ```ADDWF``` 時,可以使用 'W' 或 'F' 來取代 'd' 的 0 跟 1 。。 - 當 a = 0 ,會存在 file register 的 0x00 ~ 0x7F 裡面( access bank )。 ::: ## Data Movement Insturcton #### CLRF F, a ( e.g. CLRF 0x20 ) - 把 F register 清除成 0 。 - 當 a = 0 時代表 F register 在 access bank 裡;當 a = 1 時代表 F register 在 BSR 裡面。 - 當清除完成時 STATUS register 的 Z-flag 會被設為 1 。 #### LFSR F, K ( e.g. LFSR 2, 0x0020 ) - 會把 K 的 low <font color="#F00"> 12 bits </font> 讀進 FSRx 中,使 FSR register 可以指向某一個 data register 。 - FSR register 的 high 4 bits 全是 0 。 #### MOVLB K ( e.g. MOVLB 0x01 ) - 把 K 放入 BSR register 裡面,而且會把 BSR register 的 high 4 bits 清為 0 。 ( 用來更改bank位置 ? ) #### MOVLW data8 ( e.g. MOVLW 0x25 ) - 把 8-bit literal 放入 WREG 裡面。 #### MOVWF F, a ( e.g. MOVWF 0x40 ) - 把 WREG register 裡面的值,放入 F register 裡面。 - 當 a = 0 代表 F 在 access bank 裡;當 a = 1 代表 F 在 BSR bank 裡面。 #### MOVFF Fs, Fd ( e.g. MOVFF 0x04, 0x03 ) - 把資料從 source data register 放入 destination data register 裡面。 - Fs 和 Fd 可以在範圍 0x000 ~ 0xFFF 之間。( data memory address 有 12-bit wide ) #### MOVF F, d, a ( e.g. MOVF 0x30, W or MOVF 0x30, F ) - 當 d = W 時,會把 F register 裡面的值搬到 WREG register 裡面;當 d = F 時,會把 F register 裡面的東西,搬回自己裡面( function same as NOP operation )。 #### SETF F, a ( e.g. SETF 0x20 ) - 把 F register 裡面的值設為 0xFF 。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 :::success 可以用來 configure an I/O port ,像是如果 ```SETF TRISB``` ,代表 Port B 被設為 input port 。 ::: #### SWAPF F, d, a ( e.g. SWAPF 0x60, W or SWAPF 0x60, F ) - 把 F register 裡面的 low order 4 bits 和 high order 4 bits 調換。 - 當 d = W 時,會把結果存在 WREG register 裡面;當 d = F 時,會把結果存在原本的 register 裡面。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 :::danger ppt 後面都是例子,自己看。 ::: ## Arithmetic Instruction - PIC18F 提供以下類別的 arithmetic instruction : 1. 8-bit addition and substraction ( include signed and unsigned ) 2. 8-bit by 8-bit unsigned multiplication 3. Negate instruction 4. Decrement and Increment Instructions 5. BCD Adjust ( BCD Correction ) ### Add and Substract Instruction #### ADDLW data8 ( e.g. ADDLW 0x02 ) - 把 8-bit content 和 WREG register 裡面的值加在一起,並存入 WREG register 。 #### ADDWF F, d, a ( e.g. ADDWF 0x50, W or ADDWF 0x50, F ) - 會把 WREG register 裡面的值和 F register 裡面的值加在一起,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### ADDWF F, d, a ( e.g. ADDWFC 0x60, W or ADDWFC 0x60, F ) - 會把 WREG register 裡面的值和 F register 裡面的值以及 carry flag 加起來,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。 #### SUBLW data8 ( e.g. SUBLW 0x07 ) - 會把 8-bit immediate data 減掉 WREG register 裡面的值,結果會存入 WREG register 中。 :::warning 去看一下 ppt 上的例子, final carry 的 1's complement 會是是否為 true borrow 。 ::: #### SUBWF F, d, a ( e.g. SUBWF 0x20, W or SUBWF 0x20, F ) - 會把 F register 裡面的值減掉 WREG register 裡面的值,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### SUBWFB F, d, a ( e.g. SUBWFB 0x30, W or SUBWFB 0x30, F ) :::warning ![](https://i.imgur.com/5J0A5IA.png) 這邊的 $C$ ( carry bit )要取 toggle 。所以下面的 SUBFWB 應該也是同理。 ::: - 會把 F register 裡面的值減掉 WREG register 和 carry flag ,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### SUBFWB F, d, a ( e.g. SUBFWB 0x20, W or SUBFWB 0x20, F ) - 會把 WREG register 裡面的值減掉 F register 和 carry flag ,當 d = W 時會存入 WREG register 中;當 d = F 時會存在 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 :::danger 要記得如果是減法,會是寫在後面的減掉寫在前面的。 ( 除了SUBLW ) ::: ### Multiplication Instruction - 不會有任何的 status flag 出現。 #### MULLW data8 ( e.g. MULLW 0x03 ) - 會把 WREG register 裡面的值乘上 immediate data 。 - 會把結果存入 PRODH 和 PRODL 中,在 WREG register 中的直是不改變的。 #### MULWF F, a ( e.g. MULWF 0x50 ) - 會把 WREG register 中的值和 F register 中的值乘起來。 - 會把結果存入 PRODH 和 PRODL 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 ### Negate Instruction #### NEGF F, a ( e.g. NEGF 0x70 ) - 會把 F register 中的值,轉換換成 2's complement ,並存入 F register 中。 ### Decrement and Increment Instructions #### DECF F, d, a ( e.g. DECF 0x50, W or DECF 0x50, F) - 會把 F register 裡面的值減 1 。 - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### INCF F, d, a ( e.g. INCF 0x50, W or INCF 0x50, F ) - 會把 F register 裡面的值加 1 。 - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 ### BCD adjust ( BCD correction ) Instruction #### DAW ( e.g. DAW ) - 似乎是會把上面那行的運算(加減乘除),轉成 BCD 來進行,並最後的結果也會轉成 BCD 。 :::success 後面也是一堆例子啦,自己看~ ::: ## Logic Instruction - PIC18F include logic AND, NOT ( one's complement ), OR and XOR operation. #### ANDLW data8 ( e.g. ANDLW 0x8F ) - 會把 WREG register 中的值和 immediate data 做 AND 。並把結果存入 WREG register 中。 #### ANDWF F, d, a ( ANDWF 0x60, W or ANDWF 0x60, F ) - 會把 WREG register 中的值和 F register 中的值做 AND 。 - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### COMF F, d, a ( e.g. COMF 0x50, W or COMF 0x50, F ) - 會把 F register 中的值做 one's complement 。 - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### IORLW data8 ( e.g. IORLW 0x7F ) - 會把 WREG register 中的值和 immediate data 做 OR 。並把結果存入 WREG register 中。 #### IORWF F, d, a ( e.g. IORWF 0x50, W or IORWF 0x50, F) - 會把 WREG register 中的值和 F register 中的值做 OR - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### XORLW data8 ( e.g. XORLW 0x02 ) - 會把 WREG register 中的值和 immediate data 做 XOR 。並把結果存入 WREG register 中。 #### XORWF F, d, a ( e.g. XORWF 0x42, W or XORWF 0x42, F ) - 會把 WREG register 中的值和 F register 中的值做 XOR 。 - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 ## Rotate Instruction #### RLCF F, d, a ( e.g. RLCF 0x40, W or RLCF 0x40, F ) - 會把 F register 中的值像左推,而且會經過 carry flag 。 - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### RLNCF F, d, a ( e.g. RLNCF 0x70, W or RLNCF 0x70, F ) - 會把 F register 中的值向左推,不考慮 carry flag 的影響。 - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### RRCF F, d, a ( e.g. RRCF 0x30, W or RRCF 0x30, F ) - 會把 F register 中的值像右推,而且會經過 carry flag 。 - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### RRNCF F, d, a ( e.g. RRNCF 0x60, W or RRNCF 0x60, F ) - 會把 F register 中的值向右推,不考慮 carry flag 的影響。 - 當 d = W 時會把結果存入 WREG register 中;當 d = F 時,會把結果存入 F register 中。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 :::success 又是一堆ㄉ例子,去看 ppt 喔~ ::: ## Bit Manipulation Instructions - 不會影響任何 STATUS register 的 flag 。 #### BCF F, b, a ( e.g. BCF 0x50, 2 ) - 會把 F register 中的第 b 個 bit 設為 0 。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 #### BSF F, b, a ( e.g. BSF 0x50, 2 ) - 會把 F register 中的第 b 個 bit 設為 1 。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 :::success 可以直接修改 STATUS register 的值,太爽了吧!!! ::: #### BTG F, b, a ( e.g. BTG 0x40, 2 ) - 會把 F register 中的第 b 個 bit 做 one's complement 。 - 當 a = 0 代表 F register 在 access bank 裡;當 a = 1 代表 F register 在 BSR bank 裡面。 :::success 又是一堆ㄉ example 哭阿。 :::