




版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領
文檔簡介
1、第四章 匯編語言程序設計匯編語言程序設計 所謂程序設計,就是按照給定的任務要求,編寫出完整的計算機程序。要完成同樣的任務,使用的方法或程序并不是唯一的。因此,程序設計的質量將直接影響到計算機系統的工作效率、運行可靠性。 前面我們學過了匯編語言形式的指令系統,本章重點介紹匯編語言程序結構以及如何利用匯編語言指令進行程序設計的方法。 4.1 匯編語言程序設計概述4.1.1 匯編語言程序設計步驟 使用匯編語言設計一個程序大致上可分為以下幾個步驟。 (1) 分析題意,明確要求。 (2) 確定算法。 (3) 畫程序流程圖,用圖解來描述和說明解題步驟。圖4.1 常用的流程圖符號 (4)分配內存工作單元,確
2、定程序與數據區的存放地址。 (5) 編寫源程序 (6) 程序優化。 (7)上機調試、修改和最后確定源程序。 4.2.2 偽指令語句 偽指令并不是真正的指令,也不產生相應的機器碼,它們只是在計算機將匯編語言轉換為機器碼時,指導匯編過程,告訴匯編程序如何匯編。下面介紹一些MCS-51匯編程序常用的偽指令。 (1)匯編起始偽指令ORG 格式:標號: ORG 16位地址 功能:規定程序塊或數據塊存放的起始地址。如: ORG 8000H START: MOV A ,#30H 該指令規定第一條指令從地址8000H單元開始存放,即標號START的值為8000H。 (2)匯編結束偽指令END 格式:標號: E
3、ND 表達式 功能:結束匯編。 例如: ORG 2000H START: MOV A ,# 00H END START 表示標號START開始的程序段結束。 (3)等值指令EQU 格式:字符名稱 EQU 項 例如,TEST EQU R0 MOV A,TEST (4)定義字節指令DB 格式:標號: DB 8位二進制數表 DB命令是從指定的地址單元開始,定義若干個8位內存單元的內容。例如, ORG 1000H TAB; DB 23H,73, “6”, “B” TABl: DB 110B 以上偽指令經匯編以后,將對從1000H開始的若干內存單元賦值: (1000H)=23H (1001H)=49H
4、(1002H)=36H (1003H)=42H (1004H)=06H 其中36H和42H分別是字符6和B的ASCII碼,其余的十進制數(73)和二進制數(110B)也都換算為十六進制數了。 (5)定義字命令 DW 格式:標號: DW 16位二進制數表 例如, ORG 1000H TAB: DW 1234H , 0ABH , 10 匯編后: (1000H)=12H (1001H ) = 34H (1002H ) = 00H ( 1003H ) = ABH (1004H ) =00H (1005H) =0AH DB、DW偽指令都只對程序存儲器起作用,不能用來對數據存儲器的內容進行賦值或進行其它初
5、始化的工作。 4.2 順序程序設計 順序結構程序是一種最簡單、最基本的程序(也稱為簡單程序),它是一種無分支的直線形程序,按照程序編寫的順序依次執行。 【例4-1】 兩個8位無符號數相加,和仍為8位。 假設兩個無符號數X1, X2分別存放于內部RAM60H、61H單元中,求其和并將和送入62H單元。 程序如下:ORG0000H CLRC MOVR0 ,# 60H;設R0為數據指針MOVA ,R0;取X11NCR0 ADDCA ,R0;X1+X21NCR0 MOVR0,A;保存結果END 【例4-2】兩個無符號雙字節數相加。設被加數存放在內部存儲器30H(高位字節)、31H(低位字節)單元,加數
6、存放在內部存儲器40H(高位字節)、41H(低位字節)單元,和存入30H(高位字節)、31H(低位字節)單元。 程序如下: ORG0000H CLRC;將C清零 MOVR0 ,#31H;送被加數首址 MOVR1 ,#41H;送加數首址 MOVA ,R0;取被加數低字節 ADDA ,R1;兩個低字節相加 MOVR0 ,A;低字節和存人被加數低字節 DECR0;修改指針,指向被加數高字節DECR1 ;修改指針,指向加數高字節MOVA,R0;取被加數高字節 ADDCA,R1;高字節相加 MOVR0 , A;存結果 END 【例4-3】編寫16位二進制數求補程序 二進制數的求補可歸結為“求反加1”的過
7、程,求反可用CPL指令實現;加1時應注意,加1只能加在低8位的最低位上。因為現在是16位數,有兩個字節,因此要考慮進位問題,即低8位取反加1,高8位取反后應加上低8位加1時可能產生的進位,還要注意這里的加1不能用INC指令,因為INC指令不影響CY標志。 程序如下: ORG0200H MOVA ,R0;低8位送ACPLA;取反ADDA ,#01H;加lMOVR2 ,A;存結果MOVA ,R1;高8位送A CPLA;取反ADDCA ,#00H;加進位MOVR3 ,A;存結果END 【例4-4】編程將20H單元中的8位無符號二進制數轉換成3位BCD碼,并存放在22H(百位)和21H(10位,個位)
8、兩個單元中。 程序如下: ORG1000H MOVA ,20H;取數送AMOVB ,# 64H;除數100送B中DIVAB;商(百位數BCD碼)在A中,余數在B中MOV22H ,A;百位數送22HMOVA , B ;余數送A做被除數MOVB , #0AH ;除數10送B中DIVAB;十位數BCD碼在A中,個位數在B中 SWAPA;十位數BCD碼移至高4位 ORLA , B;并入個位數的BCD碼MOV21H , A;十位、個位BCD碼存人21H END 分支程序的結構有兩種,如圖4.2所示。 圖4.2 分支程序結構 圖4.2(a) 結構使用條件轉移指令來實現分支,當給出的條件成立時,執行程序段,
9、否則執行程序段。 圖4.2 (b) 結構使用散轉指令JMP來實現多分支轉移,它首先將分支程序按序號的值來實現分支轉移。 【例4-5】設補碼X放在內部RAM30H單元中,函數Y與X有如下的關系式: 試編寫程序,根據X的值求出Y,并放回原單元。 解 取出X后先做取值范圍的判斷,用累加器A狀態轉移指令判斷X是否為0,用位狀態轉移指令判斷X是大于0還是小于0。程序流程圖如圖4.3所示。 程序如下: 4.3 分支程序設計MOV A,30HJZ ZER0JNB ACC.7,PLUSADD A,#5MOV 30H,APLUS: SJMP $ZERO: MOV 30H,#20HSJMP $END 開始結束A=
10、0?A0?(30H) A(30H)+5 (30H)20H (30H)圖4.3 例4-5程序框圖 【例4-6】內部RAM40H和41H單元中各有一無符號數,比較其大小,將大數存放于內部RAM60H單元,小數存放于內部RAM61H單元,如兩數相等,則分別送往這2個單元。 解 用比較不等轉移指令CJNE比較力兩個無符號書,先確定它們是否相等,若不相等時再根據借位標志確定這兩個無符號書的大小。程序框圖如圖4.4所示。程序如下: Y開始A (41H)A與(61H)交換結束(40H) (60H)A (60H)N圖4.4 例4-6程序框圖(40H) A MOVA, 40H MOV61H, 41H CJNEA
11、 , 4 1 H , LOOP AJMPAGEQ LOOP: JNCAGEQ;A(41H)則無借位 XCHA, 61H;A(41H)有借位AGEQ:MOV60H, A;A與(61H)交換 SJMP END 【例4-7】某溫度控制系統,采集的溫度值(Ta)放在累加器A中。此外,在內部RAM54H單元存放控制溫度下限制(T54),在55H單元存放控制溫度上限制(T55)。若Ta T55,程序轉向JW(降溫處理程序);若TaT55,轉降溫處理程序 CJNEA,54H,LOOP2;TaT54,轉向LOOP2 AJMPFH;Ta=54,返回LOOP2:JCSW;若(CY)=1,表明Ta09H?(A)10
12、H?F0 1返 回NNNN圖 4.5 例 4-8程 序 框 圖 【例4-9】N路分支程序,N8。要求程序根據其運行中所產生的寄存器R3的值,來決定如何進行分支。 解:為實現N路分支,可以多次使用比較轉移指令:CJNE R3, #data , rel流程圖如圖4.6所時,但這樣比較次數太多,當N較大時,執行速度就較慢。 我們可以用變址尋址的轉移指令JMPA+DPTR使問題得到解決。首先安排存放一個轉移分支入口的地址表,把入口地址表的首地址送到DPTR,再把R3的內容送累加器A。現以4個分支為例寫出程序。假設4個分支的不同功能分別是給不同的位置。 程序如下: MOV A ,R3MOV DPTR ,
13、#BRTABMOVC A ,A+DPTRJMP A+DPTRBRTAB DB BR0-BRTABDB BRl-BRTABDB BR2-BRTABDB BR3-BRTABBR0: SETB P1.0SJMP BRKBR1: SETB P1.1SJMP BRKBR2: SETB P1.2SJMP BRKBR3: SETB P1.3BRK: SJMP BRK R3=0R3=2R3=1YYNNNY轉向第0分支轉向第1分支轉向第2分支4.4 循環程序設計 循環程序一般由4部分組成。 (1)置循環初值。 (2)循環體。 (3)循環修改。 (4)循環控制。 圖4.7(a)結構是“先執行后判斷”,適用于循環次
14、數已知的情況。 圖4.7(b)結構是“先判斷后執行”,適用于循環次數未知的情況。 YN開始置循環初值循環處理循環修改結束處理循環結束?結束Y(a)先執行后判斷開始結束置循環初值循環結束?循環處理循環修改結束處理N(b)先判斷后執行二、程序清單ORG OOOOHSTART: MOVA,#01H;使L1燈亮,其它不亮LOOP:MOV P1,A;從P1口輸出到發光二極管MOV R1,#10H;延時1秒DEL1:MOV R2,#200DEL2:MOVR3,#126DEL3:DJNZ R3,DEL3DJNZR2,DEL2DJNZ R1,DEL1RL A;左移一位,下一個發光二極管亮AJMPLOOP;循環
15、END 【例4-10】多個單字節數求知。 已知有10個單字節數,依次存放在內部RAM 40H單元開始的數據存儲區中,求和并將結果存人寄存器R2、R3中(高位存R2,低位存R3)。 本題中,要重復進行加法運算,因此采用循環結構程序。循環次數就是數據塊字節數,這是已知的。在置初值時,將數據塊長度置人寄存器R5;將數據塊首地址送人寄存器R0,即以R0作為數據塊的地址指針,采用間接尋址方式:每做一次加法之后,修改地址指針,以便取出下一個數來相加,并且使計數器R5減l。到R5減為0時,求和結束。程序流程圖如圖4.8所示。 ORG2000H SUM: MOVR0,#40H;設地址指針 MOVR5,#0AH
16、;計數器初值送R5SUM: MOVA,#00H MOVR2,A LP:ADDA,R0 JNCLP1 INCR2;若有進位,和的高八位+1LP1:INCR0;地址指針+1 DJNZR5,LP;判循環結束條件 MOVR3,A;存和的低八位 END 【例4-11】從內存BLOCK單元開始有一個無符號數的數據塊,其長度為LEN,試求出其最大值,并存入MAX單元。 這是一個搜索問題。這里采用依次進行比較和取代的方法來尋找最大值。具體做法是:先取出第一個數作為基準,和第二個數比較,若比較結果基準數大,不作變動;若比較結果基準數小,則用大數來代替原基準數,然后再和下一個數作比較。到比較結束時,基準數就是所求
17、的最大值。 為了進行兩數的比較,采用兩數相減以后判斷CY的值來確定哪個數大,這比用CJNE指令更簡單。比較時將基準數放在累加器A中。若A中先放人零,比較次數等于LEN;若A中先放人第一個數,則比較次數等于LEN-1。采用R2作為計數器,R1作為地址指針。程序流程如圖4.9所示。 ORG 8000H COMP:CLRA MOVR2,# LEN MOVR1,# BLOCK LOOP:CLRC ;清CY SUBBA,R1;用減法作比較 JNCNEXT ;若(A) (R1) , 轉移 MOVA,R1;若(A) ( ( R 1 ) ) ?( ( R 1 ) ) A( R 1 ) + 1 R 1( R 2
18、 ) - 1 = 0 ?存 最 大 數Y 【例4-12】假設從內存RAM的50H單元,連續存放一串字符,以回車符(其ASCII碼為0DH)作為結束標志,要求測出該字符串的長度。測試方法可采用將該字符串的每一個字符與回車符依次相比,若不相等,則將統計字符串長度的計數器加l,繼續比較;若比較相等,則表示該字符串結束,這時計數器中的值就是字節符串的長度。 程序如下: ORG 8000HCOUNT: MOV R2,# 0FFH MOV R0,# 4FH LOOP: INC R0 INC R2 CJNE R0, #0DH, LOOP SJMP 程序中使用指令CJNE R0,# 0DH , LOOP實現字
19、符串比較及控制循環的任務。由于在循環體中比較轉移之前,將 R2和R0的內容加,因此R2和R0的初值要減去。循環次數由對于循環條件的判定而定,當循環結束時,R2中的內容就是字符串的長度。 【例4-13】編制用軟件方法延時S的程序軟件延時時間與執行指令的時間有關。如果使用6MHz晶振,一個機器周期為2s。計算出執行每一條指令以及一個循環所需要的時間,根據要求的延時時間確定循環次數,如果單循環時間不夠長,可以采用多重循環。 程序如下: MOV R5, #05HDELY0: MOV R6, #0C8HDELY1: MOV R7, #0F8H NOPDELY2: DJNZ R7, DELY2 DJNZ
20、R6, DELY1 DJNZ R5, DELY0 這是一個三重循環程序。前條指令的機器周期數為,后條指令的機器周期數為。執行內循環所用的機器周期數為2482=496,執行中間循環所用的機器周期數(496+4)200=100000;執行外循環所用的機器周期數為(100000+3)5=500015,再加上(執行第一條指令)就是執行整段程序所用的機器周期數。因此這段程序的延時時間位(500015+1)2s=1.000032s。 【例4-14】編寫無符號數排序程序。 假設在片內RAM中,起始地址為40H的10個單元中存放有10個無符號數。試進行升序排序。 解 數據排序常用方法是冒泡排序法。這種方法的過
21、程類似水中氣泡上浮,故稱冒泡法。執行時從前向后進行相鄰數的比較,如數據的大小次序與要求的的順序不符就將這兩個數互換,否則不互換。對于升序排序通過這種相鄰數的互換,使小數向前移動,大數向后移動;從前向后進行一次冒泡(相鄰數的互換),就會把最大的數換到最后;再進行一次冒泡就會把次大的數排在倒數第二的位置。依此類推,完成由小到大的排序。 編程中選用R7做比較次數計數器,初始值為09H,位地址00H作為冒泡過程中是否有數據互換的標志位,若(00H) =0,表明無互換發生,已排序完畢。 (00H) =1,表明有互換發生。流程圖如圖4-11所示。 ORG0400H START:MOVR0,#40H;數據區
22、首址送R0 MOVR7,#09H;各次冒泡比較次數送R7 CLR00H;互換標志位清零LOOP:MOVA,R0;取前數送A中 MOV2BH,A;暫存到2BH單元中 INCR0;修改地址指針 MOV2AH,R0;取后數暫存到2AH單元中 CLRC;清CY SUBBA,R0;前數減后數 JCNEXT;前數小于后數,則轉(不互換) MOVR0,2BH;前數大于后數,兩數交換 DECR0 MOVR0,2AH INCR0;地址加1,準備下一次比較 SETB00H;置互換標志NEXT:DJNZR7,LOOP;未比較完,進行下一次比較 JB00H,START;有交換,表示未排完序,進行下一輪冒泡 END ;
23、無交換,表示已排好序,結束 開始數據區受地址 R0比較次數 R7置交換標志取前一個操作數取后一個操作數前數 后數?前數和后數交換置交換標志?本輪比較完畢?本輪有交換?結束YYNYN圖4.10 程序流程圖4.5 子程序設計 在匯編語言源程序中使用子程序時,一般要注意兩個問題:參數傳遞和現場保護。參數傳遞一般可采用以下方法: 傳遞數據。將數據通過工作寄存器R0R7或累加器來傳送。即主程序和子程序在交接處,上述寄存器和累加器存儲的是同一參數。 傳送地址。數據存放在數據寄存器中,參數傳遞時只通過R0、R1、DPTR傳遞數據所存放的地址。 通過堆棧傳遞參數。在調用之前,先把要傳送的參數壓入堆棧,進入子程
24、序之后,再將壓入堆棧的參數彈出到工作寄存器或者其他內存單元。 通過位地址傳送參數。例如: SUBROU: PUSH ACC PUSH B PUSH R0 POP R0 POP B POP PSW POP ACC RET 至于每個具體的子程序是否需要現場保護,以及哪些參數應該保護,則應視具體情況而定。 【例4-15】單字節二進制數據轉換為BCD碼子程序SBTOD。 功能:將單字節二進制數轉換為三位BCD碼。 入口:R2中存放要轉換的二進制數。 出口:(R0)給出百位BCD碼的存放地址。(R0)+1給出十位和個位BCD碼的存放地址,高半字節放十位,低半字節放個位。 占用寄存器:A,B,R0,R2。
25、 SBTOD:MOVSP,#60H PUSHACC MOVA,R2;取數 MOVB,#64H DIVAB;除以100,(A)為百位數 MOVR0,A;存人(R0)單元 MOVA,#0AH XCHA,B;余數(B)送A DIVA,B;除以10,得十位和個位 SWAPA;十位數放于高半字節 ADDA,B;個位數放于低半字節 INCR0 MOVR0,A;個位存入(R0)+1單元 POPACC RET 【例4-16】將內部數據存儲器某一單元中的一個字節的十六進制數轉換成兩位ASCII碼,結果存放在內部數據存儲器的兩個連續單元中。 假設一個字節的十六進制數在內部數據存儲器40H單元,結果存于41H、42H單元中,用堆棧進行參數傳遞。 MAIN:MOVSP,#55H MOVR1,#41H;R1為存結果指針 MOVA,40H;取要轉換的數據 SWAPA;先轉換高位字節 PUSHACC;壓棧 LCALLHEASC;調用低半字節轉換成 ASCII碼程序 POPACC; 要轉換的數據出棧 M
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
- 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
- 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
- 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年加脂劑項目資金申請報告代可行性研究報告
- 求職個人簡歷
- 安徽省2025年中考第三次模擬考試化學試卷(含答案)
- 2025年企業可持續發展目標(SDGs)實踐策略深度分析報告
- 圍棋很難的題目及答案
- 網絡套路題目及答案解析
- DB50-T 1748-2024 蜂蜜生產管理規范
- 滁州職業技術學院《中外經典劇作導讀》2023-2024學年第二學期期末試卷
- 預防腦出血治療方案講課件
- 內蒙古工業職業學院《邊坡工程與地基處理》2023-2024學年第二學期期末試卷
- 誰是消費“領頭羊”:人口周期改變消費模式221mb
- 2025年蘇教版科學六年級下冊小升初期末檢測題附答案
- 2024福建省閩投深海養殖裝備租賃有限責任公司招聘7人筆試參考題庫附帶答案詳解
- 2025年江西省贛州市八年級中考模擬預測生物試題(含答案)
- 2025屆上海市閔行區21學校七年級生物第二學期期末調研試題含解析
- 車牌過戶協議書范本
- 火災自動報警系統故障應急預案
- 《拓印新貌》教學課件-2024-2025學年滬書畫版(五四學制)(2024)初中美術六年級下冊
- 湖北省武漢市2025年中考語文二模試題(含答案)
- 2025-2030中國海底光纜產業市場發展分析及前景趨勢與投資研究報告
- 建筑光伏一體化(BIPV開發及設計技術標準)
評論
0/150
提交評論