




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、 5. 移位指令 移位指令有如下循環左移、 帶進位位循環左移、 循環右移和帶進位位循環右移 4 條指令, 移位只能對累加器A進行。 循環左移RL A ; (A n+1) (An) , (A0) (A7) , 23 帶進位位循環左移 RLC A ; (A n+1) (An ), (CY) (A7 ), (A0 ) (CY) , 33 循環右移 RRA ; (An) (A n+1 ), (A7 ) (A0) , 03帶進位位循環右移 RRC A ; (An) (A n+1 ), (CY) (A0), (A7) (CY) , 13 以上移位指令操作, 可用圖 3 5 表示。 圖 3 5 移位指令操作
2、示意圖 另外, 值得一提的是在前述數據傳送類指令中有一條累加器A的內容半字節交換指令: SWAP A ; (A)74 (A)30 , C4 它實際上相當于執行循環左移指令 4 次。 該指令在BCD碼的變換中是很有用的, 如 3.3.2 節的例 4。 例如: 設(A)=43H, (CY)=0, 則執行指令: RL A ; RLC A ; RR A ; RRC A ; 結果為: (A)=86H, (CY)=0 (A)=0CH, (CY)=1 (A)=06H, (CY)=1 (A)=83H, (CY)=0當A的最高位(D7)為0時,執行一次RL指令相當于對A進行一次乘2操作。 01111011 10
3、 0000000001111011 11110110當A的最低位(D0)為0時,執行一次RR指令相當于對A進行一次除2操作。即除是乘的反操作。 3.3.4 控制轉移類指令 控制轉移類指令共計 17 條, 可分為無條件轉移指令、 條件轉移指令、 子程序調用及返回指令。 有了豐富的控制轉移類指令, 就能很方便地實現程序的向前、 向后跳轉, 并根據條件分支運行、 循環運行、 調用子程序等。 1. 無條件轉移指令 無條件轉移指令有如下 4 條指令, 它們提供了不同的轉移范圍和尋址方式: LJMP addr16; (PC) addr16, addr 158 addr 70 AJMP addr11; (P
4、C) (PC)+2, addr108 00001 addr 70 (PC)100 addr11 SJMP rel ; (PC) (PC)+2+rel , 80rel JMP A+DPTR ; (PC) (A)+DPTR , 73 (1) LJMP 稱為長轉移指令, 三字節指令, 提供 16 位目標地址addr16。 例如: 在程序存儲器0000H單元存放一條指令: LJMP 3000H; (PC) 3000H, 02 3000 則上電復位后程序將跳到3000H 單元去執行用戶程序。 (2) AJMP稱為絕對轉移指令, 雙字節指令。 它的機器代碼是由 11 位直接地址addr11和指令特有操作碼
5、 00001, 按下列分布組成的: 該指令執行后, 程序轉移的目的地址是由AJMP指令所在位置的地址PC值加上該指令字節數 2, 構成當前PC值。 取當前PC值的高 5 位與指令中提供的 11 位直接地址形成轉移的目的地址, 即: a10 a9 a8 0 0 0 0 1 a7 a6 a5 a4 a3 a2 a1 a0 PC15 PC14 PC13 PC12 PC11 a10 a9 a8 a7 a6 a5 a4 a3 a2 a1 a0PC 轉移目的地址: 由于 11 位地址的范圍是 0000000000011111111111, 即 2 KB范圍, 而目標地址的高 5 位是由PC當前值固定的,
6、所以程序可轉移的位置只能是和PC當前值在同一 2 KB的范圍之內。 本指令轉移可以向前也可以向后, 指令執行后不影響狀態標志位。 例如: 若AJMP指令地址(PC)=2300H。 執行指令: AJMP 0FFH ; (PC) (PC)+2=2302H, 01 FF (PC)100 00011111111 結果為: 轉移目的地址 (PC)=20FFH , 程序向前轉向 20FFH單元開始執行。 又如: 若AJMP指令地址(PC)=2FFFH。 執行指令: AJMP 0FFH; (PC) (PC)+2=3001H, 01 FF (PC)100 00011111111 結果為: 轉移目的地址 (PC
7、)=30FFH , 程序向后轉向 30FFH單元開始執行。 (3) SJMP稱為短轉移指令, 雙字節指令, 指令的操作數是相對地址rel。 由于rel是帶符號的偏移量, 所以程序可以無條件向前或向后轉移, 轉移的范圍是在SJMP指令所在地址PC值(源地址)加該指令字節數2的基礎上, 以-128+127 為偏移量(256 個單元)的范圍內實現相對短轉移, 即: 目的地址=源地址+2+rel 用匯編語言編程時, 指令中的相對地址rel往往用欲轉移至的地址的標號(符號地址)表示, 能自動算出相對地址值; 但人工將程序翻譯成機器代碼時, 需自己計算相對地址rel。 rel的計算公式如下: 向前轉移:
8、rel=FE(源地址與目的地址差的絕對值) 向后轉移: rel=(源地址與目的地址差的絕對值)2 若rel值大于 80H, 程序向前轉移; 若rel值小于 80H, 則程序向后轉移。 例如: 設(PC)=2100H, 若轉向215CH去執行程序, 則: rel=(215CH2100H)2H=5AH (4) JMP稱為間接長轉移指令。 它是以數據指針DPTR的內容為基址, 以累加器A的內容為相對偏移量, 在 64 KB范圍內可無條件轉移的單字節指令。 該指令的特點是轉移地址可以在程序運行中加以改變。 例如: 根據累加器A的數值, 轉不同處理程序的入口。 MOV DPTR, TABLE ; 表首址
9、送DPTR JMP A+DPTR ; 依據A值轉移 TABLE: AJMPTAB1; 當(A)=0時轉TAB1執行 AJMPTAB2; 當(A)=2時轉TAB2執行 AJMPTAB3; 當(A)=4時轉TAB3執行 2. 條件轉移指令(判跳指令) 條件轉移指令是當某種條件滿足時, 程序轉移執行; 條件不滿足時, 程序仍按原來順序繼續執行。 條件轉移的條件可以是上一條指令或者更前一條指令的執行結果(常體現在標志位上), 也可以是條件轉移指令本身包含的某種運算結果。 1) 累加器判零轉移指令 這類指令有 2 條: JZ rel;若 (A)=0, 則 (PC) (PC)+2+rel 60 rel 若
10、 (A)0, 則 (PC) (PC)+2 JNZ rel ; 若 (A)0, 則 (PC) (PC)+2+rel, 70 rel 若 (A)=0, 則 (PC) (PC)+2 例 1: 將外部數據RAM的一個數據塊傳送到內部數據RAM, 兩者的首址分別為DATA1 和 DATA2, 遇到傳送的數據為零時停止。 解: 外部RAM向內部RAM的數據傳送一定要以累加器A作為過渡, 利用判零條件轉移正好可以判別是否要繼續傳送或者終止。 完成數據傳送的參考程序如下: MOV R0, DATA1 ; 外部數據塊首址送R0 MOV R1, DATA2 ; 內部數據塊首址送R1LOOP:MOVX A, R0
11、; 取外部RAM數據入AHERE:JZ HERE ; 數據為零則終止傳送 MOV R1, A ; 數據傳送至內部RAM單元 INCR0 ; 修改地址指針, 指向下一數據地址 INCR1 SJMP LOOP ; 循環取數 2) 比較轉移指令 比較轉移指令共有 4 條, 其一般格式為: CJNE目的操作數, 源操作數, rel 這組指令是先對兩個規定的操作數進行比較, 根據比較的結果來決定是否轉移到目的地址。 4 條比較轉移指令如下: CJNE A, data , rel ; B4 data rel CJNE A, direct, rel ; B5direct rel CJNE Ri, data,
12、 rel ; B6B7data rel CJNER n, data, rel ; B8Bfdata rel 這 4 條指令的含義分別為: 第 1 條指令: 累加器內容與立即數比較, 不等則轉移; 第 2 條指令: 累加器內容與內部RAM(包括特殊功能寄存器)內容比較, 不等則轉移; 第 3 條指令: 內部RAM內容與立即數比較, 不等則轉移; 第 4 條指令: 工作寄存器內容與立即數比較, 不等則轉移。 以上 4 條指令的差別僅在于操作數的尋址方式不同, 均完成以下操作: 若目的操作數=源操作數, 則 (PC) (PC)+3 ; 若目的操作數源操作數, 則 (PC) (PC)+3+rel, C
13、Y=0; 若目的操作數源操作數, 則 (PC) (PC)+3+rel, CY=1; 指令的操作過程如圖 3 6 所示。 偏移量rel 的計算公式為: 向前轉移: rel = FD(源地址與目的地址差的絕對值) 向后轉移: rel =(源地址與目的地址差的絕對值)-3 例如: 當 P1 口輸入為 3AH時, 程序繼續進行, 否則等待, 直至P1口出現 3AH。 參考程序如下: MOV A, 3AH ; 立即數3A送A; 74 3AWAIT: CJNE A, P1, WAIT ; (P1)3AH, 則等待, B5 90 FD圖 3 6 比較轉移指令操作示意圖 3) 減 1 條件轉移指令(循環轉移指
14、令)減 1 條件轉移指令有如下兩條: DJNZ direct, rel; (direct) (direct)1 , D5 direct rel 若(direct)=0, 則(PC) (PC)+3 否則, (PC) (PC)+3+relDJNZ Rn, rel ; (Rn) (Rn)1 , D8DF rel 若(Rn)=0, 則(PC) (PC)+2 否則, (PC) (PC)+2+rel 這組指令是把減1功能和條件轉移結合在一起的一組指令。 程序每執行一次該指令, 就把第一操作數減 1, 并且結果保存在第一操作數中, 然后判斷操作數是否為零。 若不為零, 則轉移到規定的地址單元, 否則順序執行
15、。 轉移的目標地址是在以PC當前值為中心的128+127 的范圍內。 如果第一操作數原為 00H, 則執行該組指令后, 結果為FFH, 但不影響任何狀態標志。 例 2: 軟件延時程序: MOV R1, 0AH; 給R1賦循環初值 DELAY: DJNZ R1, DELAY; (R1) (R1)1, 若(R1)0則循環 由于DJNZ R1, DELAY 為雙字節雙周期指令, 當單片機主頻為 12 MHz時, 執行一次該指令需 24 個振蕩周期約 2 s。 因此, R1 中置入循環次數為 10 時, 執行該循環指令可產生20 s 的延時時間。 例 3: 將內部RAM中從DATA單元開始的 10 個
16、無符號數相加, 相加結果送SUM 單元保存。 解: 設相加結果不超過8位二進制數, 則相應的程序如下: MOV R0, 0AH ; 給 R0 置計數器初值 MOV R1, DATA ; 數據塊首址送R1 CLR A ; A清零 LOOP: ADD A, R1 ; 加一個數 INC R1 ; 修改地址, 指向下一個數 DJNZ R0, LOOP ; R0 減 1, 不為零循環 MOV SUM, A ; 存 10 個數相加和 4) 空操作指令 NOP ; (PC) (PC)+1, 00 空操作指令是一條單字節單周期指令。 它控制CPU不做任何操作, 僅僅是消耗這條指令執行所需要的一個機器周期的時間
17、, 不影響任何標志, 故稱為空操作指令。 但由于執行一次該指令需要一個機器周期, 所以常在程序中加上幾條NOP指令用于設計延時程序, 拼湊精確延時時間或產生程序等待等。 3.3.5位操作類指令 位操作又稱為布爾變量操作, 它是以位(bit)作為單位來進行運算和操作的。 MCS51系列單片機內設置了一個位處理器(布爾處理機), 它有自己的累加器(借用進位標志CY), 自己的存儲器(即位尋址區中的各位), 也有完成位操作的運算器等。 這一組指令的操作對象是內部RAM中的位尋址區, 即20H2FH中連續的 128 位(位地址00H7FH), 以及特殊功能寄存器SFR中可進行位尋址的各位。 在指令中,
18、 位地址的表示方法主要有以下 4 種(均以程序狀態字寄存器PSW的第五位 F0 標志為例說明): (1) 直接位地址表示方式: 如D5H; (2) 點操作符表示(說明是什么寄存器的什么位)方式: 如PSW.5, 說明是PSW的第五位; (3) 位名稱表示方法: 如F0 ; (4) 用戶定義名表示方式: 如用戶定義用FLG這一名稱(位符號地址)來代替F0, 1. 位傳送指令 位傳送指令有如下互逆的兩條雙字節單周期指令, 可實現進位位CY與某直接尋址位bit間內容的傳送。 MOV C, bit ; (CY) (bit) , A2 bit MOV bit, C ; (bit) (CY) , 92 b
19、it 上述指令中: bit為直接尋址位, C為進位標志CY的簡寫。 第1條指令是把bit中的一位二進制數送位累加器CY中, 不影響其余標志。 第2條指令是將C中的內容傳送給指定位。 由于兩個尋址位之間沒有直接的傳送指令, 常用上述兩條指令并通過C作為中間媒介來進行尋址位間的傳送。 例如: 將內部RAM中20H 單元的第7位(位地址為07H)的內容, 送入P1口的P1.0中的程序如下: MOV C, 07H ; (CY) (07H) MOV P1.0, C ; (P1.0) (CY) 當(20H)=A3H, (P1)=11111110B時, 執行上述指令后修改了P1 口第 0 位, 即(CY)=
20、1, (P1)=11111111B。 2. 位置位指令 對進位標志CY以及位地址所規定的各位都可以進行置位或清零操作, 共有如下4條指令: CLR bit ; (bit) 0 , C2 bit CLR C; (CY) 0 , C3 SETB bit ; (bit) 1 , D2 bit SETB C ; (CY) 1 , D3 前兩條指令為位清零指令, 后兩條指令為位置 1 指令。 當第 1、 3 條指令的直接尋址位為某端口的某位時, 指令執行時具有讀修改寫功能。 例如: 將P1 口的P1.7 置位, 并清進位位的程序如下: SETB P1.7 ; (P1.7) 1 CLR C ; (CY)
21、0 當(P1)=00001111B時, 執行完上述指令后, (P1)=10001111B, (CY)=0。 3. 位邏輯指令 位邏輯指令包含“與”ANL、 “或”ORL、 “非”CPL位邏輯運算操作, 共有如下 6 條指令: ANL C, bit ; (CY) (CY)( ) , 82bitANL C, / bit ; (CY) (CY)( ) , B0bitORL C, bit ; (CY) (CY)( ) , 72bitORL C, / bit ; (CY) (CY)( ) , A0bitCPL bit ; (bit) ( ) , B2bitCPL C ; (CY) (C) , B3 例
22、1: 完成(Z)=(X) (Y)異或運算, 其中: X、 Y、 Z表示位地址。 解: 異或運算可表示為: (Z)=(X)( )+( )(Y), 參考子程序如下: PR1: MOV C, X ; (CY) (X) ANL C, /Y ; (CY) (X)( ) MOV Z, C ; 暫存Z中 MOV C, Y ; (CY) (Y) ANL C, /X ; (CY)( ) (Y) ORL C, Z ; (CY) (X)( )+( )(Y) MOV Z, C ; 保存異或結果 RET 例 2: 利用位邏輯指令, 模擬圖 3 7 所示硬件邏輯電路功能。 參考子程序如下: PR2: MOV C, P1.
23、1 ; (CY) (P1.1) ORL C, P1.2 ; (CY) (P1.1)(P1.2) = A ANL C, P1.0 ; (CY) (P1.0)A CPL C ; (CY) MOV F0, C ; F0內暫存B MOV C, P1.3 ; (CY) (P1.3) ANL C, /P1.4 ; (CY) (P1.3) ORL C , F0 ; (CY) BD MOV P1.5, C ; 運算結果送入P1.5 RET 3. 位條件轉移指令 位條件轉移指令是以進位標志CY或者位地址bit的內容作為是否轉移的條件, 共有 5 條指令。 (1) 以CY內容為條件的雙字節雙周期轉換指令。 JC
24、rel ; 若(CY)=1, 則(PC) (PC)+2+rel轉移 , 40 rel 否則, (PC) (PC)+2 順序執行 JNC rel ; 若(CY)=0, 則(PC) (PC)+2+rel轉移 , 50 rel 否則, (PC) (PC)+2順序執行 這兩條指令常和比較條件轉移指令CJNE一起使用, 先由CJNE指令判別兩個操作數是否相等, 若相等就順序執行; 若不相等則依據兩個操作數的大小置位或清零CY(參見圖 3 - 6), 再由JC 或JNC指令根據CY的值決定如何進一步分支, 從而形成三分支的控制模式, 如圖 3 - 8 所示。 圖 3 7 例 2 硬件邏輯電路 圖 3 8C
25、JNE 與JC(或JNC)一起構成三分支模式 例 3: 比較內部RAM I、 J單元中A、 B兩數的大小。 若A=B, 則使內部RAM的位K置 1; 若AB, 則大數存M單元, 小數存N單元。 設A、 B數均為帶符號數, 以補碼數存入I、 J中, 該帶符號數比較子程序的比較過程示意圖如圖 3 9 所示。 參考子程序如下: 圖 3 9 帶符號數比較過程示意圖 MOV A, I ; A數送累加器A ANL A, 80H ; 判A數的正負 JNZ NEG ; A0 則轉至NEG MOV A, J ; B數送累加器A ANL A, 80H ; 判B數的正負 JNZ BIG1 ; A0, B0, 轉BI
26、G1 SJMP COMP ; A0, B0, 轉COMPNEG: MOV A, J ; B數送累加器A ANL A, 80H ; 判B數的正負 JZ SMALL ; A0, B0, 轉SMALL COMP:MOV A, I ; A數送累加器A CJNE A, J, BIG ; AB則轉BIG SETB K ; A=B, 位K置 1 RETBIG: JC SMALL ; A0 Y= 0 X=0 -1 X0則轉移到POSI MOV A, 0FFH ; 若X0 時A=1 COMP: MOV FUNC, A ; 存函數Y值 HERE: AJMP HERE ; 結束程序 例 4: 3 個無符號單字節整數
27、分別存于R1、 R2、 R3 中, 找出其中最大數放于R0 中。 解: 首先將 R0 清零, 然后進行(R1)與(R0)減法, 若(R1)(R0)0, 則(R1)(R0), 把(R1) 送(R0); 否則(R0)保持不變。 再將(R0)分別與(R2)和(R3)比較, 比較處理的方法與上面相同, 這樣比較 3 次后, R0 中即為 3 數中的最大數。 程序清單如下: BR2: ORG 2500H MOV R0, 00H ; R0 清零 MOV A, R1 ; 第一個數(R1)送A ACALL COMP ; 比較(R1)與(R0)大小 MOV A, R2 ; 第二個數(R2)送A ACALL CO
28、MP ; 比較(R2)與(R0)大小 MOV A, R3 ; 第三個數(R3)送A ACALL COMP ; 比較(R3)與(R0)大小 HERE: AJMP HERE COMP: MOV R4, A ; R4 暫存A的內容 CLR C ; 清進位位C SUBB A, R0 ; (A)(R0) JC M1 ; (A)(R0)時大數存R0 M1: RET 例: 把片外RAM的首地址為10H開始存放的數據塊,傳送給片內RAM首地址為20H開始的數據塊中去,如果數據為“0”,就停止傳送。程序如下:ORG 2000HMOV R0, #10HMOV R1, #20HLOOP:MOVX A, R0 ; A
29、片外RAM數據HERE:JZ HERE ; 數據=0終止,程序原地踏步MOV R1, A ; 片內RAMAINC R0 INC R1 SJMP LOOP ; 循環傳送 END 3.5.4 循環結構程序設計 在解決實際問題時, 往往會遇到同樣的一組操作需要重復多次的情況, 這時應采用循環結構, 以簡化程序, 縮短程序的長度及節省存儲空間。 例如, 要做 1 到 100 的加法, 沒有必要寫 100 條加法指令, 而只需寫一條加法指令, 使其執行 100 次, 每次執行時操作數亦作相應的變化, 同樣能完成原來規定的操作。 循環程序一般由 3 部分組成: (1) 置循環初值: 即設置循環開始時的狀態
30、。 (2) 循環體: 即要求重復執行的部分。 (3) 循環控制部分: 它包括循環參數修改和依據循環結束條件判斷循環是否結束兩部分。 例 5: 從BLOCK單元開始有一個無符號數數據塊, 其長度存于LEN單元,試求出數據塊中最大的數并存入MAX單元。 解: 該問題解決方法與例 4 相同, 所不同的是無符號數個數增加, 即搜索尋找最大值的范圍擴大了。 因此, 本例題采用直到型單重循環的程序結構方式比較合理。 程序框圖如圖 3 14 所示。 圖 3 14 例 5 程序框圖 程序清單: LOOP: ORG 2000H MOV R0, BLOCK ; 數據塊首址送R0 MOV R1, LEN ; 數據塊
31、長度送R1 MOV MAX, 00H ; 存最大數單元清零 LOOP1: MOV A, MAX ; (A) (MAX) CLR C ; 清C SUBB A, R0 ; (MAX)(R0) JNC NEXT ; 若(MAX)(R0), 則轉移 MOV MAX, R0 ; 若(MAX)(R0), 則(MAX) (R0) NEXT: INC R0 ; 修改地址指針 DJNZ R1, LOOP1 ; 若(R1)0則循環搜索 RET 例 6: 設計 100 ms延時程序。 解: 計算機執行一條指令需要一定的時間, 由一些指令組成一段程序, 并反復循環執行, 利用計算機執行程序所用的時間來實現延時, 這種
32、程序稱為延時程序。 如當系統使用 12 MHz晶振時, 一個機器周期為 1 s , 執行一條雙字節雙周期DJNZ指令的時間為 2 s, 因此, 執行該指令 50 000 次, 就可以達到延時 100 ms的目的。 對于 50 000 次循環可采用外循環、 內循環嵌套的多重循環結構。 本例題的程序流程如圖315所示。 程序清單: START: ORG 1000H MOV R6, 0C8H ; 外循環 200 次 LOOP1: MOV R7, 0F8H ; 內循環 248 次 NOP ; 時間補償 LOOP2: DJNZ R7, LOOP2 ; 延時 2 s248=496 s DJNZ R6, L
33、OOP1; 延時 500 s200=100 ms RET 圖 3 15 例 6 程序框圖 返回 以上程序執行MOV Rn, data 指令的時間為 1 s, DJNZ指令 2 s, NOP指令1 s, 所以, 內循環延遲時間: 1 s+1 s+2 s248=498 s, 外循環延遲時間: 1 s+(內環延時+2 s)200=100.001 ms。 3.5.5 子程序結構程序設計 在一個程序中, 將反復出現的程序段編制成一個個獨立的程序段, 存放在內存中, 這些完成某一特定任務可被重復調用的獨立程序段被稱為子程序。 在前面所舉的例子中, 已有一些程序段是以帶有RET指令的子程序形式出現的。 在匯
34、編語言編程時, 恰當地使用子程序, 可使整個程序的結構清楚, 閱讀和理解方便, 而且還可以減少源程序和目標程序的長度, 不必多次重復書寫和翻譯同樣的指令。 在匯編語言源程序中使用子程序, 需要強調注意兩個問題, 即子程序中參數傳遞和現場保護的問題。 一般在匯編語言中采用的參數傳遞方法有以下 3 種。 (1) 用累加器或工作寄存器來傳遞參數。 (2) 用指針寄存器傳遞參數。 (3) 用堆棧來傳遞參數。 例 7: 將HEX單元存放的兩個十六進制數分別轉換成ASCII碼, 并存入ASC和ASC+1 單元。 解: 由于偽指令DB在匯編后, 使字節以ASCII碼形式存放, 所以采用查表子程序的方式來實現
35、十六進制數到ASCII碼的轉換。 轉換子程序為HASC, 調用時傳遞參數采用堆棧來完成。 程序清單如下: ORG 2000H PUSH HEX ; 第一個十六進制數入棧 ACALL HASC ; 調查表轉換子程序 POP ASC ; 低 4 位轉換值保存 MOV A, HEX ; 十六進制數送A SWAP A ; 高 4 位低 4 位交換 PUSH A ; 第二個十六進制數入棧 ACALL HASC ; 調查表轉換子程序 POP ASC+1 ; 高 4 位轉換值保存 HERE: AJMP HERE ; 結束源程序 HASC: DEC SP ; DEC SP ; 修改SP到參數位置 POP A
36、; 彈出十六進制數到A ANL A, 0FH ; 取A低 4 位 ADD A, 07H ; 為查表進行地址調整 MOV CA, A+PC ; 查表轉換 PUSH A ; 轉換結果入棧 INC SP ; INC SP ; 恢復返回地址 RET ASCTAB: DB 0, 1, 2, 3, 4, 5, 6, 7 DB 8, 9, A, B, C, D, E, F END 由于堆棧操作是“先入后出”, 因此, 先壓入堆棧的參數應后彈出, 才能保證恢復原來的狀態。 例如: SUBROU: PUSH A PUSH PSW PUSH DPL PUSH DPH POP DPH POP DPL POP PSW
37、 POP A RET3.6.3 代碼轉換程序設計【例3-46】 編寫一子程序,將8位二進制數轉換為BCD碼。設要轉換的二進制數在累加器A中,子程序的入口地址為BCD1,轉換結果存入R0所指示的RAM中。程序如下: BCD1:MOVB, #100 DIVAB ; A百位數,B余數MOVR0, A ; (R0)百位數INCR0MOVA, #10XCHA, BDIVAB ; A十位數,B個位數SWAPAADDA, B ; 十位數和個位數組合到AMOVR0, A ; 存入(R0) RET 例 1 : 十六進制數到ASCII碼的轉換子程序設計。 解: 該轉換的算法為: 凡大于等于 10 的十六進制數加
38、37 H, 凡小于 10 的十六進制數加 30 H, 便可得到相應的ASCII碼。 入口: R2(高4位為 0000, 低 4 位為 00001111 的一個十六進制數0F)。 出口: R2(相應的ASCII碼)。 程序清單如下: HASC1: MOV A, R2 ; 十六進制數送A ADD A, 0F6H ; (A)+(-10)補 MOV A, R2 ; 恢復十六進制數 JNC AD30H ; 若(A)10 則轉AD30H ADD A, 07H ; (A) 10 則先加 07H AD30H: ADD A, 30H ; (A)+30H MOV R2, A ; ASCII碼存R2 RET 例 2
39、: ASCII碼到十六進制數的轉換子程序設計。 解: 該轉換的算法為: 若為 09 的ASCII碼, 則減去 30H; 若為AF的ASCII碼,則減去 37H, 便可得到相應的十六進制數 0F。 入口: R2(09 或AF的ASCII碼)。 出口: R2(高 4 位為 0000, 低 4 位為00001111)。 程序清單如下: ASCH1: MOV A, R2 ; ASCII碼值送A ADD A, 0D0H ; (A)+(-30H)補 MOV R2, A ; R2暫存減結果 ADD A, 0F6H ; A+(-10)補 JNC RET1 ; 若(A)10 轉RET1 MOV A, R2 ;
40、若(A)10 則(R2)送A ADD A, 0F9H ; (A)+(-07H)補 MOV R2, A ; 十六進制數存R2 RET1: RET 3.6.2 運算子程序設計 在 3.3.2 節例 1、 例 2 中已經介紹了雙字節無符號數的加法、 減法程序, 在 3.3.2 節例3中介紹了雙字節數乘單字節數, 以及在 3.3.2 節例 5 、 例 6、 例 7 中介紹了BCD碼加法和利用DA調整指令進行十進制減法程序等。 下面再分別介紹雙字節乘法、 除法子程序。 例 3: 雙字節無符號數乘法子程序設計。 解: 算法: 兩個雙字節無符號數被分別放在R7、 R6和R5、 R4中。 由于MCS51指令中
41、只有 8 位數的乘法指令MUL, 用它來實現雙字節數相乘時, 可把被乘數分解為: (R7)(R6)=(R7)28+(R6),(R5)(R4)=(R5)28+(R4)則這兩個數的乘積可表示為: (R7)(R6)(R5)(R4)=(R7) 28 +(R6)(R5) 28 8+(R4)=(R7)(R5)216+(R7)(R4) 28+ (R6)(R5) 28 +(R6)(R4)=(R04)(R03)(R02)(R01) 顯然, 我們將(R6)(R4)放入(R02)(R01)中, 將(R7)(R4)和 (R6)(R5)累加到(R03) (R02)中; 再將(R7)(R5)累加到(R04)(R03)中即
42、可得到乘積結果。 入口: (R7 R6)=被乘數; (R5 R4)=乘數; (R0)=乘積的低位字節地址指針。 出口: (R0)=乘積的高位字節地址指針, 指向 32 位積的高 8 位。 工作寄存器: R3、 R2 存放部分積; R1存放進位位。 程序清單如下: MUL1:MOV A , R6 MOV B , R4 MUL AB ; (R6)(R4) MOV R0, A ; R01 存乘積低 8 位 MOV R3, B ; R3暫存(R6)(R4)的高 8 位 MOV A , R7 MOV B , R4 MUL AB ; (R7)(R4) ADD A, R3 ; (R7)(R4)低 8 位加(
43、R3)MOV R3, A ; R3暫存28 部分項低 8 位MOV A, B ; (R7)(R4)高 8 位送AADD CA, 00H ; (R7)(R4)高 8 位加進位CYMOV R2, A ; R2暫存 28 部分項高 8 位MOV A, R6MOV B, R5MUL AB ; (R6)(R5)ADD A, R3 ; (R6)(R5)低 8 位加(R3)INC R0 ; 調整R0 地址為R02 單元MOV R0, A ; R02 存放乘積 158 位結果MOV R1, 00H ; 清暫存單元MOV A, R2ADD CA, B ; (R6)(R5)高 8 位加(R2)與CYMOV R2,
44、 A ; R2暫存 28部分項高 8 位JNC NEXT ; 28 項向 216 項無進位則轉移INC R1 ; 有進位則R1 置 1 標記 NEXT: MOV A , R7 MOV B, R5 MUL AB ; (R7)(R5) ADD A, R2 ; (R7)(R5)低 8 位加(R2) INC R0 ; 調整 R0 地址為R03 MOV R0, A ; R03 存放乘積 2316 位結果 MOV A , B ADD CA, R1 ; (R7)(R5) 高 8 位加 28 項進位 INC R0 ; 調整 R0 地址為 R04 MOV R0, A ; R04 存放乘積 3124 位結果 RE
45、T 例 4: 雙字節帶符號數乘法子程序設計。 解: 算法: 由于帶符號數乘法和無符號數乘法的基本算法是一樣的, 因此可以根據入口條件調用例 3 MUL1子程序進行計算。 不同之處有以下 3 點: (1) 需根據被乘數和乘數的符號計算乘積的符號; (2) 當被乘數和乘數為負數時, 應對它們取補, 形成 2 的補碼, 然后才能調用MUL1進行運算; (3) 當積為負數時, 計算的結果尚需取補后才是正確的積(絕對值), 積為 31 位。 乘積符號的算法在本程序中分兩步完成: 首先用ANL指令判斷兩數是否均為負, 若與操作的結果為 1, 則兩數均為負, 乘積應為正, 對與的結果取反即為積的符號, 存入
46、SIG;若不屬于此情況, 則用ORL指令算出積的符號存入SIG。 程序中SIG、 SIG1 、 SIG2均為內部RAM中的可尋址位。 入口: (R7 R6)=帶符號位被乘數; (R5 R4)=帶符號位乘數; (R0)=乘積的低位字節地址指針。 出口: (R0)=乘積的高位地址指針。 程序清單如下: MUL2: MOV A, R7 ; 被乘數高 8 位送A RLC A ; (R7)的符號位送CY MOV SIG1, C ; SIG1 存被乘數符號 MOV A, R5 ; 乘數高 8 位送A RLC A ; (R5)的符號位送CY MOV SIG2, C ; SIG2 存放乘數符號 ANL C,
47、SIG1 ; 計算積的符號 JC POSI ; 若兩數均負積為正則轉POSI MOV C, SIG1 ; 計算兩數非全負時積的符號 ORL C, SIG2 SJMP SIGN POSI: CPL C SIGN: MOV SIG, C ; 存積的符號 MOV A, R7 JB A.7, CPL1 ; 被乘數為負轉求補 STEP1: MOV A, R5 JB A.7, CPL2 ; 乘數為負轉求補 STEP2: ACALL MUL1 ; 調(R7 R6)(R5 R4)子程序 JB SIG, CPL3 ; 積符號為負轉求補 RETCPL1: MOV A, R6 ; 被乘數求補 CPL A ADD A
48、, 01H MOV R6, A MOV A, R7 CPLA ADDC A, 00H MOV R7, A SJMP STEP1 CPL2: MOV A, R4 ; 乘數求補 CPL A ADD A, 01H MOV R4, A MOV A, R5 CPLA ADD CA, 00H MOV R5, A SJMP STEP2 CPL3: DEC R0 ; 乘積結果求補 DEC R0 DEC R0 ; 使R0指向乘積低字節地址 MOV R2, 03H ; 待取補數字節數-1 送R2 ACALL CPL4 ; 調用多字節數求補子程序 RETCPL4: MOVA , R0 ; 多字節數求補 CPL A
49、ADD A, 01H MOV R0, A STEP3: INC R0 MOV A, R0 CPL A ADD CA, 00H MOV R0, A DJNZ R2, STEP3 ; 字節未轉換完轉移 RET CPL4為多字節數求補子程序, 入口為(R0)=待取補數低字節地址指針; (R2)=待取補數字節數-1。 出口為(R0)=求補后的高位字節地址指針。 例 5: 雙字節無符號數除法子程序設計。 解: MCS51 除法指令只能進行8位無符號數相除運算, 而對于多字節除法, 還需用一般的除法算法進行。 常用的除法算法采用“移位相減法”, 即: 先設余數為0, 并將被除數和余數分別左移一位, 使被除
50、數的最高位移入余數的最低位, 再求(余數除數)之差, 若差為正, 則令差代替余數, 商為1; 若差為負, 則不作任何操作。 然后重復以上移位相減的過程, 使每位被除數都參與了運算為止。 圖 3 16例 5 程序框圖(a) 除法程序框圖; (b) 四舍五入處理框圖 入口: (R7 R6)=被除數, (R5 R4)=除數。 出口: (R7 R6)=商數, (OVER)=溢出標志(FFH為溢出)。 工作寄存器:(R3 R2)=部分余數, (R1)=計數器, (R0)=差值暫存。 程序清單如下: DIV: MOV A, R5 ; 除數高 8 位送A JNZ BEGIN ; 除數非零則轉BEGIN MO
51、V A, R4 ; 除數低 8 位送A JZ OVER ; 除數為零置溢出標志 BEGIN: MOV A, R7 ; 被除數高 8 位送A JNZ BEGIN1 ; 被除數非零則轉BEGIN1 MOV A, R6 ; 被除數低 8 位送A JNZ BEGIN1 ; 被除數非零則轉BEGIN1 RE T ; 被除數為零則返回BEGIN1: CLR A ; 清余數單元 MOV R2, A MOV R3, A MOV R1, 10H ; 雙字節除法計數器置 16 DIV1: CLR C ; 開始R3 R2 R7 R6 左移 MOV A, R6 ; 被除數低 8 位送A RLC A ; R6循環左移一
52、位 MOV R6, A ; 左移結果回送 MOV A, R7 ; 被除數高 8 位送A RLC A ; R7 循環左移一位 MOV R7, A ; 左移結果回送 MOV A, R2 ; 余數左移一位 RLC A MOV R2, A MOV A, R3 RLC A MOV R3, A DIV2: MOV A, R2 ; 開始部分余數減除數 SUBB A, R4 ; 低 8 位先減 MOV R0, A ; 暫存差值 MOV A, R3 SUBB A, R5 ; 高 8 位相減 JCN EXT ; 若部分余數除數則轉NEXT INC R6 ; 若部分余數除數則商為1 MOV R3, A ; 新余數存
53、R3 R2 MOV A, R0 MOV R2, A NEXT: DJN ZR1, DIV1 ; 16 位未除完則返回 MOV A, R3 ; 開始四舍五入處理 JB A.7, ADD1 ; 若余數最高位為 1 則進 1 CLR C ; 開始余數乘 2 處理 MOV A, R2 RLC A ; 余數低 8 位乘 2 MOV R2, A MOV A, R3 RLC A ; 余數高 8 位乘 2 SU BBA, R5 ; 余數2除數 JC NOOVER ; 若余數2除數則轉 JN ZADD1 ; 若夠減則轉進 1 MOV A, R2 ; 高 8 位相等時比較低 8 位 SUBB A, R4 JC N
54、OOVER ; 余數2除數則轉 ADD1: MOV A, R6 ; 開始商進1處理 ADD A, 01H MOV R6, A MOV A, R7 ADDC A, 00H MOV R7, A NOOVER: MOV OVER, 00H ; 清溢出標志 RET OVER: MOV OVER, 0FFH ; 置溢出標志 RET 雙字節帶符號數除法的算法與無符號數除法的算法基本相同, 所不同的是在計算除法之前先進行商的符號確定。 商的符號確定方法與例4帶符號數乘法中乘積符號的確定方法相同。所以雙字節帶符號除法程序首先要進行商的符號確定, 再調用無符號數除法子程序DIV即可, 這里不再重復。 3.6.3
55、 查表程序設計 查表, 就是根據變量x, 在表格中查找y, 使y = f (x)。 單片機應用系統中, 查表程序 是一種常用程序, 它被廣泛應用于LED顯示器控制, 打印機打印以及數據補償、 計算、 轉換等功能程序中(如 3.3.1 節例 1、 2、 4; 3.5.4 節例 7 )。 例 6: 設有一巡檢報警裝置, 需要對 16 路值進行比較, 當每一路輸入值超過該路的報警值時, 實現報警。 要求編制一個查表子程序, 依據路數xi, 查表得yi的報警值。 解: xi為路數, 查表時按照 0, 1, 2, , 15 取值, 故為單字節規則量。 表格依xi順序列表, 僅存二字節報警值yi, 其表格
56、構造見表34。 表 3 4 路數xi與報警值yi對應關系 程序入口 : (R2)=路數xi。 程序出口: (R4 R3)=對應xi的報警值yi。 查表子程序如下: STA1: MOV A, R2 ; 路數xi送A RL A ; x-i2 MOV R4, A ; 暫存 ADD A, TABL(rel) ; 加上表首偏移量 MOV CA, A+PC ; 查y-i第一字節 XCH A, R4 ; 第一字節送R4 ADD A, TABL(rel)+1 ; 形成第二字節表址 MOV CA, A+PC ; 取yi第二字節 MOV R3, A ; 第二字節送R3 RET TAB2: DW 050FH, 0E
57、89H, A695H, 1EAAH ; 報警值表 DW 0D9BH, 7F93H, 0373H, 26D7H DW 2710H, 9E3FH, 1A66H,22E3H DW 1174H, 16EFH, 33E4H,6CA0H 上述查表程序中使用RL A使(A)乘 2, 這是由于DW定義的是雙字節空間, 為了保證指向正確的查表地址, 所以要進行乘 2 處理。 另外, 程序中使用MOVCA, A+PC指令, 使表格偏移不得超過255個字節。 當表格偏移大于255個字節時, 應使用MOVCA, A+DPTR 查表指令。 表 3 5 x與表地址對應關系 編制一個查表程序, 將查得的函數值yi存入R4、
58、 R3 中。 解: 入口: (R3R2)=由其它程序得到的xi規則量, 即: xi = 0000H, 0001H, 0002H, 。 出口: (R5 R4)=依據 xi查得的函數值yi。 查表程序如下: STA: MOV DPTR, TABL ; 置表首地址 MOV A, R2 ; 求yi在表中序號 CLRC RLCA MOV R2, A MOV A, R3 RLC A MOV R3, A MOV A, R2 ; 求yi在表中地址 ADD A, DPL MOV DPL, A MOV A, R3 ADD CA, DPH MOV DPH, A CLR A MOV CA, A+DPTR ; 查表得y
59、i高位 MOV R5, A INC DPTR ; 表格地址加 1 CLR A MOV CA, A+DPTR ; 查表得yi低位 MOV R4, A RET TAB1: DW ; 函數值yi表 例 8: 輸入一個ASCII命令符, 要求按照輸入的命令字符轉去執行相應的處理程序。 設命令為單字節字符 A、 D、 E、 L、 M、 X、 Z七種, 相應的處理程序入口標號分別為雙字節XA、 XD、 XE、 XL、 XM、 XX、 XZ。 解: 對于上述情況, 由于xi與yi 均為非規則量, 因此在表格中必須存放相應的xi、 yi值, xi為輸入命令符, yi為相應處理程序入口地址, 其表格構造見表 3 6。表 3 6 存儲內容與表地址關系 這類表格xi、 yi可以是單字節、 雙字節或多字節, 它以兩種方式給出表格的容量。 一種是用表格結束標志 0 來表示, 另一種則是給出表格中的項數。 本程序采用結束標志 0 表示。 該查表子程序的算法為: 當輸入一個ASCII命令符
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025知識產權合同范本:網絡游戲軟件授權許可合同
- 2025屆東北三省四城市聯考暨遼寧省沈陽市高三下學期質量監測(二)物理試卷答案
- 酒店內部設計合同范本
- 幼兒照護知到課后答案智慧樹章節測試答案2025年春孝感市工業學校
- 外貿家具出售合同范本
- 2025共同投資合同
- 2025年建筑行業《基礎設施建設租賃合同》
- 2025中介租房合同示范文本
- 2024年先進技術成果西安轉化中心招聘真題
- 2024年南充市教育和體育局南充衛生職業學院招聘真題
- 2024-2025學年北師大版七年級數學上冊期末復習壓軸題12個(84題)含答案
- 2023年北京市大興區小升初數學模擬試卷(含答案)
- 2025年河南工業和信息化職業學院單招職業技能測試題庫參考答案
- 2025年河南交通職業技術學院單招職業技能測試題庫審定版
- 政府審計 課件匯 蔣秋菊 第5-12章 金融審計- 政府審計報告
- 第二十一章傳導熱療法講解
- 2025年河南職業技術學院高職單招語文2018-2024歷年參考題庫頻考點含答案解析
- 2025年福建福州港務集團有限公司招聘筆試參考題庫含答案解析
- 智能硬件發展特點及趨勢分析
- 關于物業客服培訓的
- 廣西能匯投資集團有限公司招聘筆試沖刺題2025
評論
0/150
提交評論