汇编语言程序设计技巧详解(附例题)
目錄
1、順序結構
2、分支結構
(1)先建立可供條件轉移指令測試的條件。
(2)選用合適的條件轉移指令。
(3)在轉移的目的地址處設定標號。
多重分支程序
a.多次使用條件轉移指令,形成兩個以上判斷框。
b.按分支號轉移
(1)用地址表法。設分支號已存入A。
(2)轉移表法。用分支轉移指令 JMP @A+DPTR
3、循環結構
(1)循環初始化
(2)循環體
(3)循環控制
多重循環循環體中套循環結構
4、子程序
(1)子程序入口用標號作為子程序名。
(2)調用子程序之前設置好堆棧。
(3)用返回指令RET結束子程序,并保證堆棧棧頂為調用程序的返回地址。
(4)子程序嵌套須考慮堆棧容量。
(5)提供足夠的調用信息:
1.寄存器傳送參數
2.存儲器傳送參數
3.堆棧傳送參數
模塊化設計
匯編語言程序設計技巧
四種基本結構:順序結構、分支結構、循環結構和子程序。
1、順序結構
【例】將R0單元內的兩位BCD碼拆開并轉換成ASCII碼,存入RAM兩個單元中R2 (存高位)和R1 (存低位)中 。
參考程序:
??????? ORG? 2000H
??????????????? MOV? A,R0????? ;取值
??????? ANL?? A,#0FH? ;取低4位
??????? ADD? A,#30H?? ;轉換成ASCII碼
??????? MOV? R1,A?????? ;保存結果
??????? MOV? A,R0?????? ;取值
??????? SWAP? A???????????? ;高4位與低4位互換
??????? ANL? A,#0FH?? ;取原來的高4位??????
??????? ADD? A,#30H?? ;轉換成ASCII碼
??????? MOV? R2,A?????? ;保存結果
??????? SJMP? $??
?????????????? END
2、分支結構
(1)先建立可供條件轉移指令測試的條件。
(2)選用合適的條件轉移指令。
(3)在轉移的目的地址處設定標號。
【例】求R2中補碼絕對值,正數不變,負數變補。
?????? ????? MOV A,R2
?????? ????? JNB ACC.7,NEXT;為正數?
?????? ????? CPL A???? ???? ;負數變補
?????? ????? INC A
?????? ????? MOV R2,A
??? NEXT:SJMP NEXT? ;結束
多重分支程序
a.多次使用條件轉移指令,形成兩個以上判斷框。
【例】?求符號函數Y=SGN(X)
??????????????????? +1? 當 X>0
SGN(X)=????? 0? 當 X=0
???????????????????? -1? 當 X<0
SYMB: MOV? A,40H ?? ;取X
?????? ?? JZ ??? STOR????? ??????? ?????? ;X=0,Y=X
?????? JB ??? ACC7,MINUS;X<0
?????? MOV? A,# 1?? ?? ;X>0,Y=+1
?????? ?? SJMP? STOR
MINUS:MOV? A,#0FFH;X<0,Y= -1
STOR:? MOV? 41H,A ? ;保存Y
??????????????? RET
b.按分支號轉移
如:分支號=0,程序轉移到ADDR0處;當分支號=1,程序轉移到ADDR1處;… 。
(1)用地址表法。設分支號已存入A。
MTJS:MOV?? DPTR,#TAB? ;取表首地址
?????? ? CLR???? C ????
?????? ? RLC???? A????????????????????? ;分支號×2
?????? ? MOV?? R2,A
????? ? INC????? A
?????? ? MOVC A,@A+DPTR;取分支地址低位
?????? ? PUSH?? ACC ? ??????;入棧保存
?????? ? MOV??? A,R2
?????? ? MOVC? A,@A+DPTR;取分支地址高位
?????? ? PUSH?? ACC ? ??????;入棧保存
?????? ? RET?? ?????? ???? ??????;分支地址→PC,轉移
TAB:? DW? ????? ??ADDR0 ???? ??????;分支地址表
?????? ?? ? DW? ???? ??ADDR1?????
???????????????????? …?
ADDR0:????? …?????????? ????? ;程序段0? …
(2)轉移表法。用分支轉移指令 JMP @A+DPTR
【例】根據R0的值轉向7個分支程序。R0<10,轉向SUB0; R0<20,轉向SUB1;… …R0<60,轉向SUB5; R0>=60,轉向SUB6;
分析:這里應該利用JMP @A+DPTR
指令直接給PC賦值,使程序實現轉移
參考程序如下:
ORG??? 2000H
MOV DPTR,#TAB;取轉移指令表首地址
MOV? A,R0 ????????? ;取數?????
MOV????? B,#10
???? ……
DIV? AB????????????????? ;A/10,商在A中???????
CLR C
RLC??? A????? ????????? ;A←2A
JMP?? @A+DPTR???? ;PC ← A+DPTR
TAB: AJMP???? SUB0? ;轉移指令表
AJMP? SUB1
AJMP???? SUB2
????? ……
AJMP???? SUB6
3、循環結構
循環程序結構是匯編語言程序中常見的一種程序結構。所謂循環,就是讓計算機反復執行某一段程序。使用循環程序可以省略很多類似的代碼,提高程序的代碼密度。
循環程序主要包含以下三個方面:
(1)循環初始化
設置循環的初始狀態,如工作單元的清零,循環次數的設置等。在設置初始條件時要小心,否則很容易讓程序多執行(或少執行)一次。
(2)循環體
即循環程序的主體,是要求計算機重復執行的部分。這部分程序應該特別注意精簡,因為要重復多次,所以這部分的精簡程度決定了整個循環程序的執行效率。
(3)循環控制
包括對循環計數器的修改和循環結束條件的判斷等內容。
【例】把內部RAM中從ST1地址開始存放的數據傳送到以ST2開始的存儲區中,數據塊長度未知,但已知數據塊的最后一個字節內容為00H,而其它字節均不為0。并設源地址與目的地址空間不重疊。?
??? 分析:顯然,我們可以利用判斷每次傳送的內容是否為 0 這一條件來控制循環。利用判A轉移控制的循環流程圖如下圖所示。
參考程序如下:
START:MOV ???? R0,#ST1
?????? MOV ????? R1,#ST2
?LOOP: MOV ?? A, @R0??????
?????? ? JZ? ??? ENT
? ?? ??MOV? @R1,A
?????? ? INC ?? R0?????????
?????? ? INC ?? R1????????????????????????
?????? ? SJMP LOOP???????????? ??????????????????????
?????? ?ENT:? RET???????
例:求n個單字節數據的累加,設數據串已在43H起始單元,數據串長度在42H單元,累加和不超過2個字節。
?SUM:?? MOV????? R0,#42H;設指針
????????????? MOV????? A,@R0
????????????? MOV????? R2,A??? ? ;循環計數器←n
????????????? CLR A???? ? ;結果單元清0
????????????? MOV????? R3,A
ADD1:INC?? R0?? ? ;修改指針
????????????? ADD?????? A,@R0? ;累加
????????????? JNC?? NEXT? ? ;處理進位
????????????? INC R3?? ? ;有進位,高字節加1
NEXT:???? DJNZ ??? R2,ADD1 ;循環控制:數據是否加完?
????????????? MOV????? 40H,A? ;循環結束,保存結果
????????????? MOV????? 41H,R3
????????????? RET
多重循環循環體中套循環結構
例將內存一串單字節無符號數升序排序。
步驟:
每次取相鄰單元的兩個數比較,決定是否需要交換數據位置。
第一次循環,比較N-1次,取到數據表中最大值。
第二次循環,比較N-2次,取到次大值。
??? …
第N-1次循環:比較一次,排序結束。
?程序:
SORT:? MOV??? A,#N-1??? ;N個數據排序
????????????? ? MOV? R4,A???????? ;外循環次數
LOOP1: MOV?? A,R4
????????????? ? MOV? R3,A???????? ;內循環次數
????????????? ? MOV? R0,#TAB?? ;設數據指針
LOOP2: MOV?? A,@R0????? ;取二數
????????????? ? MOV? B,A
????????????? ? INC??? R0
????????????? ? MOV? A,@R0
????????????? ? CJNE A,B,L1 ;比較
L1:?????? ? JNC??? UNEX????????? ;A≥B,不交換
????????????? ? DEC??? R0??????? ;否則交換數據
????????????? ? XCH?? A ,@R0
????????????? ? INC??? R0
????????????? ? MOV? @R0,A
UNEX:? DJNZ R3,LOOP2??? ;內循環結束?
????????????? ? DJNZ R4,LOOP1?? ;外循環結束?
????????????? ? RET
4、子程序
能完成某項特定功能的獨立程序段,可被反復調用。
子程序設計
(1)子程序入口用標號作為子程序名。
(2)調用子程序之前設置好堆棧。
(3)用返回指令RET結束子程序,并保證堆棧棧頂為調用程序的返回地址。
(4)子程序嵌套須考慮堆棧容量。
(5)提供足夠的調用信息:
如:子程序名、子程序功能、入口參數和出口參數、子程序占用的硬件資源、子程序中調用的其他子程序名。
選用不同的參數傳遞方式。
1.寄存器傳送參數
2.存儲器傳送參數
3.堆棧傳送參數
【例】將R4R5R6中三個字節數據對半分解,變成6個字節, 存入顯示緩沖區(DISMEM0~DISMEM5)。
1)子程序UFOR1的功能:將A累加器中單字節數據,對半分解成兩個字節,存入R0所指向的相鄰兩個單元
UFOR1:MOV? @R0,#0
????????????? ?XCHD A,@R0?? ;保存低半字節
????????????? ?INC? R0????? ;修改指針
????????????? ?MOV? @R0,#0
????????????? ?SWAP A
????????????? ?XCHD A,@R0?? ;保存高半字節
????????????? ?RET
2)調用子程序UFOR1之前,將待分解的內容送A,存放地址送R0。
【例】利用MCS-51仿真實驗板,外部擴展四個雙色發光二極管HL1、HL2、HL3和HL4分別模擬北(HL1)、西(HL2)、東(HL3)、南(HL4)四個方向交通燈,連接電路如下圖所示:
?分析:雙色發光二極管有一個陰極,兩個陽極G和R,當G極為高電平時,發光二極管呈現綠色,當R極為高電平時,發光二極管呈現紅色,當G和R極都為高電平時,發光二極管呈現黃色,根據題意要求和圖3.19的電路連接情況可以知道P1口的控制狀態如下表所示:
參考程序如下:
???????????? ORG 1000H
START:MOV? R0,#0
???????????? MOV? R1,#0?? ;南北綠燈亮5秒鐘,東西紅燈亮
?? ? ????????MOV? P1,#10010110B ;南北綠燈亮紅燈滅,東西紅燈亮綠燈滅,為狀態1
SNDL5:? MOV R1, #10
??????????? ACALL?? DL500ms??? ;調用延時500ms程序10次,實現延時5秒
??????????? DJNZ? R1, SNDL5?? ;南北綠燈閃爍3次,每次1秒(亮0.5秒,滅0.5秒)
SS1:??? MOV? P1,#10011111B;南北綠燈和紅燈都滅,東西紅燈亮綠燈滅,為狀態2
??????????? ACALL? DL500ms??????? ;延時500ms
??????????? MOV? P1,# 10010110B? ;南北綠燈亮紅燈滅,東西紅燈亮綠燈滅,為狀態1
??????????? ACALL? DL500ms?????? ;延時500ms
??????????? INC ?????? ?R0
??????????? CJNE????? R0,#03H,SS1?? ;閃爍3次,南北黃燈亮2秒
??????????? MOV????? P1,#00000110B? ;南北黃燈亮,東西紅燈亮綠燈滅,為狀態3
SNDL2:? MOV R1, #4
?????? ????? ACALL?? DL500ms ;調用延時500ms程序4次,實現延時2秒
???????????? DJNZ? R1, SNDL2?????? ;東西綠燈亮5秒鐘,南北紅燈亮
???????????? MOV P1,#01101001B? ;東西綠燈亮紅燈滅,南北紅燈亮綠燈滅,為狀態4
EWDL5:? MOV R1, #10
???????????? ACALL?? DL500ms? ;調用延時500ms程序10次,實現延時5秒
???????????? DJNZ? R1, EWDL5 ;東西綠燈閃爍3次,每次1秒(亮0.5秒,滅0.5秒)
SS2:? MOV P1,#01101111B ;東西綠燈和紅燈都滅,南北紅燈亮綠燈滅,為狀態5
???????????? ACALL? DL500ms?????? ;延時500ms
?????????? MOV? P1,# 01101001B ;東西綠燈亮紅燈滅,南北紅燈亮綠燈滅,為狀態4
???????????? ACALL? DL500ms??????? ;延時500ms
?????? ?????? INC ?R0
???????????? CJNE??? R0,#03H,SS2?? ;閃爍3次,東西黃燈亮2秒
????????????? MOV? P1,#00001001B? ;東西黃燈亮,南北紅燈亮綠燈滅,為狀態6
SNDL2:? MOV R1, #4
??????????? ACALL?? DL500ms?????? ;調用延時500ms子程序4次,實現延時2秒
??????????? DJNZ? R1, SNDL2
??????????? SJMP? START? ?? ?????; 500ms 秒延時子程序
DL1500mS: MOV? R7,#5 ;500ms 秒延時子程序,假定為6MHz晶振
?? DL2: MOV? R6,#200
?? DL1: MOV? R5,#250
???????????? DJNZ??? R5,$
???????????? DJNZ??? R6,DL1
???????????? DJNZ??? R7,DL2
???????????? RET??????????
???????????? END
模塊化設計
模塊化設計是指把一個具體的功能分解成多個小的模塊,各個模塊之間相互獨立,而又可以相互傳遞參數。分解成的小模塊程序功能單一,易于調試和修改,而在模塊內部要注意多使用子程序調用,一個子程序可以被多次調用,節省空間而且便于閱讀。在程序中應該盡量使用循環結構,這樣可以節省內存,提高執行效率,不過要注意循環的初始值和循環的結束條件。
注意:由于中斷是隨機產生的,因此在處理中斷程序時,一定要注意保存程序現場(保護標志寄存器和中斷處理程序用到的寄存器),以便執行完畢后恢復。在進行子程序調用時,經常使用累加器A(參數多時還可以使用寄存器或存儲器)進行參數傳遞。
總結
以上是生活随笔為你收集整理的汇编语言程序设计技巧详解(附例题)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 最近写的一个qt应用软件
- 下一篇: Qt 设置窗体或控件渐变消失