匯編語言的分支程序設計與循環程序設計


匯編語言的分支程序設計:

例題1:比較三個無符號數的大小,按照從大到小的順序排列

關鍵的語句是:無符號數,因此所用語句是JAE實現跳轉:

此外比較兩個操作數所用的是CMP,交換兩個操作數的是XCHG

書上的代碼:

代碼1:這樣寫法比較占用寄存器,但是寄存器之間交換數值比較快

;程序名稱:實現三個無符號數的由小到大的排序
DATAS  SEGMENT
BUFFER   DB   87,234,123
DATAS  ENDS

CODES   SEGMENT
                    ASSUME  CS:CODES,DS:DATAS
START:    MOV   AX,DATAS
                    MOV    DS,AX
                    
                    MOV    SI,OFFSET  BUFFER;把buffer的 偏移量交給變址寄存器SI
                    MOV    AL,[SI]
                    MOV    BL,[SI+1]
                    MOV    CL,[SI+2]
                    CMP        AL,BL  ;比較AL,和BL的大小
                    JAE            NEXT1  ;如果AL>BL轉移到next1
                    XCHG   AL,BL;交換AL,和BL
NEXT1:   CMP     AL,CL  ;比較AL和CL的大小
                    JAE            NEXT2
                    XCHG    AL,CL
NEXT2:   CMP     BL,CL
                    JAE       NEXT3
                    XCHG    BL,CL
NEXT3:   MOV      [SI],AL    
                    MOV      [SI+1],BL
                    MOV      [SI+2],CL
                    MOV           AH,4CH
                    INT                21H
CODES    ENDS
                    END    START
View Code

 代碼2:這樣的寫法只用了AL,但是寄存器與存儲器操作數指教的操作比較慢

 1 ;程序功能,實現三個數的大小排序
 2 DATAS     SEGMENT
 3 BUFFER   DB    87,234,123
 4 DATAS     ENDS
 5 
 6 
 7 CODES      SEGMENT
 8 ASSUME  CS:CODES,DS:DATAS
 9 START:    MOV   AX,DATAS
10                     MOV   DS,AX
11                     
12                     MOV     SI,OFFSET  BUFFER
13                     MOV     AL,[SI]
14                     CMP     AL,[SI+1]
15                     JAE       NEXT1
16                     XCHG   AL,[SI+1]
17                     MOV     [SI],AL
18 NEXT1:   CMP      AL,[SI+2]
19                     JAE        NEXT2
20                     XCHG    AL,[SI+2]
21                     MOV      [SI+1],AL
22 NEXT2:   MOV       AL,[SI+1]
23                CMP      AL,[SI+2]
24                JAE        NEXT3
25                XCHG     AL,[SI+2]
26                MOV       [SI+1],AL
27 NEXT3:   MOV        AH,4CH
28                     INT         21H
29 CODES    ENDS
30                    END        START
View Code

 

例題2:寫一個實現一位十六進制的數轉換為對應的ASCII碼的程序 

;程序功能,實現16進制數值轉換成對應的ASCII碼
;原理:但十六進制數值為0到9的時候,對應的ASCII=x+30H
; 當十六進制為10到15的時候,對應的ASCII = x+37H

這里關鍵的語句是 JA,大於9的話,轉移

之后便是程序跳轉指令:JMP,但標號很多的時候,可以用LAB1,LAB2,LAB3這種類型的標號

 1 ;程序功能,實現16進制數值轉換成對應的ASCII碼
 2 ;原理:但十六進制數值為0到9的時候,對應的ASCII=x+30H
 3 ;            當十六進制為10到15的時候,對應的ASCII = x+37H
 4 DATAS            SEGMENT
 5 XX         DB      4
 6 ASCII     DB      ?
 7 DATAS   ENDS
 8 ;
 9 
10 CODE     SEGMENT 
11 ASSUME       CS:CODE,DS:DATAS
12                      MOV   AX,DATAS
13                      MOV   DS,AX
14                      
15 START:         MOV   AL,XX
16                           AND    AL,0FH
17                     CMP   AL,9
18                     JA     LAB1
19                     ADD    AL,30H
20                     JMP    LAB2
21 LAB1:          ADD     AL,37H
22 LAB2:          MOV    ASCII,AL
23                           MOV    AH,4CH
24                           INT      21H
25 CODE           ENDS
26                     END     START
View Code

 

 例題3:寫一個程序實現ASCII轉換成對應的十六進制

 1 ;ASCII 轉換為16進制數
 2 DATA     SEGMENT
 3 XX          DB       ?
 4 ASCII      DB      'a'
 5 DATA      ENDS
 6 ;
 7 
 8 CODE      SEGMENT
 9          ASSUME    CS:CODE,DS :DATA
10 START:            MOV   AX,DATA
11                         MOV   DS,AX
12                          MOV    AL,ASCII
13                          CMP   AL,0
14 LAB:           JB      LAB5
15                         MOV   AH,AL
16                         SUB    AH,'0'
17                         CMP   AL,'9'
18                         JBE     LAB6
19                         CMP   AL,'A'
20                         JB       LAB5
21                         MOV   AH,AL
22                         SUB    AH,'A' -10
23                         CMP    AL,'F'
24                         JBE      LAB6
25                         CMP     AL,'a'
26                         JB        LAB5
27                         MOV    AH,AL
28                         SUB      AH,'a' -10
29                         CMP      AL,'f'
30                         JBE        LAB6
31                         ;
32 LAB5 :         MOV      AH,-1
33 LAB6:                          MOV       XX,AH
34                           MOV       AH,4CH
35                           INT         21H
36                           CODE      ENDS
37                                          END         START
View Code

 

利用地址表實現多向分支

當要根據某個變量的值,進行多種不同的處理時,就會產生了多向分支,多向分支在高級語言中常常用switch實現,在匯編語言中是使用地址表實現的

DSEG    SEGMENT

……………………

COMTAB  DW  COMA,COMB,COMC,COMD

              DW  COME,COMF,COMG,COMH

DSEG      ENDS

……………………

計算如果地址表內的地址,之后調用路口地址表即可

之后跳轉指令用這個 JMP   COMTAB[BX]

 

循環程序設計:

例題1:用計數法控制循環

 1 ;程序功能,說明根據計數法控制循環體
 2 DSEG        SEGMENT
 3 SUM         DW            ?
 4 DSEG        ENDS
 5 
 6 CSEG            SEGMENT
 7 ASSUME         CS:CSEG
 8 
 9 START:     MOV    AX,40H
10                     MOV DS,AX
11                     MOV    SI,0
12                     MOV CX,1024
13                     XOR    AX,AX
14 AGAIN:        ADD  AX,[SI]
15                     INC        SI
16                     INC     SI
17                     LOOP        AGAIN
18                     ;
19                     ASSUME  DS:DSEG
20                     MOV    BX,DSEG
21                     MOV    DS,BX
22                     MOV    SUM,AX
23                     MOV    AH,4CH
24                     INT       21H
25                     CSEG    ENDS
26                                     END    START
View Code

本例程中所用的關鍵指令為LOOP,LOOP指令使用的方法是在初始化CX的初值,每次執行一次LOOP,CX寄存器會減一

此外,還用了SI這個源地址指針,因為定義的變量時字,所以SI在循環的時候,調用了兩次INC,在得到校驗和的時候,重新設置了

數據段寄存器,以便於保存校驗和

例題2:不用乘法指令實行乘法運算

假設乘法時234*125,不用乘法指令,可以有移位和累加兩種方法

方法一:累加,可以看成是125個234相加,因此循環的時候,循環次數是CX=125

 1 ;程序功能,說明根據計數法控制循環體
 2 DSEG        SEGMENT
 3 SUM         DW            ?
 4 DSEG        ENDS
 5 
 6 CSEG            SEGMENT
 7 ASSUME         CS:CSEG
 8 
 9 START:     MOV    AX,40H
10                     MOV DS,AX
11                     MOV    SI,0
12                     MOV CX,1024
13                     XOR    AX,AX
14 AGAIN:        ADD  AX,[SI]
15                     INC        SI
16                     INC     SI
17                     LOOP        AGAIN
18                     ;
19                     ASSUME  DS:DSEG
20                     MOV    BX,DSEG
21                     MOV    DS,BX
22                     MOV    SUM,AX
23                     MOV    AH,4CH
24                     INT       21H
25                     CSEG    ENDS
26                                     END    START
View Code

這里用的指令時XOR,自己和自己異或等於0,還有JCXZ這條指令,JCXZ表示但cx寄存器為0的時候跳轉

例題3:把16位的二進制數轉換為5位十進制數值,為了簡單,設二進制數時無符號的,采用8421BCD碼表示十進制數

 1 ;程序功能,實現十六位二進制數轉換為十進制數
 2 DSEG        SEGMENT
 3 DATA         DW        23456
 4 BUFFER    DB         5    DUP(0)
 5 JM                DW        10000,1000,100,10,1
 6 DSEG        ENDS
 7 
 8 CSEG            SEGMENT
 9                     ASSUME    CS:CSEG,DS:DSEG
10         START:MOV AX,SEG    DATA
11                         MOV DS,AX
12                         MOV DI,OFFSET  JM
13                         MOV SI,OFFSET BUFFER
14                         MOV CX,5
15                         MOV AX,DATA
16                         XOR DX,DX
17         NEXT: MOV BX,[DI]
18                      ADD DI,2
19                      DIV BX
20                      MOV [SI],AL
21                      INC SI
22                      MOV AX,DX
23                      XOR DX,DX
24                      LOOP NEXT
25                      MOV AX,4C00H
26                      INT 21H
27                      CSEG ENDS
28                                      END START
View Code

這里用了兩個比較重要的概念,因為是16位的數值,因此必須明白,在進行16位的除法運算時,商保存在AX中,余數保存在DX中

在進行8位的除法運算時,AL保存商,AH保存余數

SEG可以返回變量所在的段值,OFFSET返回變量的偏移值,因此經常可以看到 MOV DI,OFFSET JM等等

在進行除法運算時,DIV BX隱含的是AX/BX

 

例題4

把一個字符串中的大寫字母改成小寫字母的程序

 1 ;程序功能,把字符串中的大寫字母改成小寫字母
 2 DSEG        SEGMENT
 3 STRING   DB  'HOW  arR  YOu I',0
 4 DSEG          ENDS
 5 CSEG         SEGMENT
 6                 ASSUME  CS:CSEG,DS:DSEG
 7         START: MOV AX,DSEG
 8                         MOV DS,AX
 9                         MOV SI,OFFSET STRING
10         AGAIN: MOV AL,[SI]
11                         OR   AL,AL
12                         JZ     OK
13                         CMP AL,'A'
14                         JB     NEXT
15                         CMP AL,'Z'
16                         JA        NEXT
17                         OR    AL,20H
18                         MOV [SI],AL
19         NEXT:   INC   SI
20                         JMP  AGAIN
21             OK:   MOV AX,4C00H
22                         INT   21H
23            CSEG  ENDS
24                            END   START
View Code

這里需要注意的是,在字符串后面添加了一個0,這里是用來判斷字符串是否為結束完,用OR AL,AL來判斷,因為自己和自己相或,得到的是本身,只有和0相或,才能得到0

因此用JZ來轉移到OK,

此外

比較CMP AL,'A',如果小的話用的是JB轉移,

判斷CMP AL 'Z',如果大於的話JA轉移,

 經過上面的判斷可以得出AL中是大寫字母,因此用OR AL,20H,把大寫字母轉換為小寫字母

如果上述條件不滿足,則INC SI

 

例題5

;寫一個程序判定從地址0040:0000H開始的2048個內存字節黨員中是否有字節A
;如果有字符A,則把第一個(按地址由小到大為序)含此指定字符的存儲單元的地址偏移
;送到000:03FEH黨員中,如果沒有,則把特征值送到0FFFFH送到上述指定單元

 1 ;寫一個程序判定從地址0040:0000H開始的2048個內存字節黨員中是否有字節A
 2 ;如果有字符A,則把第一個(按地址由小到大為序)含此指定字符的存儲單元的地址偏移
 3 ;送到000:03FEH黨員中,如果沒有,則把特征值送到0FFFFH送到上述指定單元
 4 ;
 5 SEGADDR  = 40H
 6 OFFADDR = 0
 7 COUNT = 2048
 8 KEYCHAR = 'A'
 9 SEGRESU = 0
10 OFFRESU = 3FEH
11 ;
12 CSEG            SEGMENT
13                     ASSUME  CS:CSEG
14                     START:MOV AX,SEGADDR
15                                   MOV DS,AX
16                                   MOV SI,OFFADDR
17                                   MOV CX,COUNT
18                                   MOV AL,KEYCHAR
19                     NEXT: CMP AL,[SI]
20                                   JZ OK
21                                   INC SI
22                                   LOOP NEXT
23                                   MOV SI,0FFFFH
24                     OK:     MOV AX,SEGRESU
25                                   MOV DS,AX
26                                   MOV BX,OFFRESU
27                                   MOV [BX],SI
28                                   MOV AH,4CH
29                                   INT 21H
30                     CSEG   ENDS
31                                     END  START
View Code

代碼分析:首先是等號的運用  =  ,常量的定義,類似於define

在查找的時候,調用CMP AL,[SI],這個查找到的話,調用JZ類似於若相等,則跳轉

例題6

;設緩沖區中有一組單字節有符號數,以0為結束標志,寫一個程序實現如下功能
;把前面5個正數一次送到緩沖區PDATA中,把前面5個負數送到緩沖區MDATA中,
;如果正數或者負數不足,則用0補足

 1 ;設緩沖區中有一組單字節有符號數,以0為結束標志,寫一個程序實現如下功能
 2 ;把前面5個正數一次送到緩沖區PDATA中,把前面5個負數送到緩沖區MDATA中,
 3 ;如果正數或者負數不足,則用0補足
 4 
 5 MAX_COUNT  = 5
 6 DSEG         SEGMENT
 7 DATA         DB  3,-4,5,6,-7,8,-9,-10,-1,-32,-132,27,58,44,-12,0
 8 PDATA         DB  MAX_COUNT DUP (?)
 9 MDATA    DB  MAX_COUNT DUP (?)
10 DSEG   ENDS
11 ;
12 CSEG            SEGMENT
13                     ASSUME CS:CSEG,DS:DSEG
14             START: MOV AX,DSEG
15                             MOV DS,AX
16                             MOV CX,MAX_COUNT
17                             MOV SI,OFFSET PDATA
18                             MOV DI,OFFSET MDATA
19                             MOV AL,0
20             NEXT1: MOV [SI],AL
21                             MOV [DI],AL
22                             INC SI
23                             INC DI
24                             LOOP NEXT1
25                             MOV BX,OFFSET DATA
26                             XOR SI,SI
27                             XOR DI,DI
28             NEXT2: MOV AL,[BX]
29                             INC BX
30                             CMP AL,0
31                             JZ OVER
32                             JG PLUS
33                             CMP DI,MAX_COUNT
34                             JAE CONT
35                             MOV MDATA[DI],AL
36                             INC DI
37                             JMP SHORT CONT
38             PLUS:  CMP SI,MAX_COUNT 
39                             JAE  CONT
40                             MOV PDATA[SI],AL
41                             INC SI
42             CONT: MOV AX,SI
43                           ADD AX,DI
44                           CMP AX,MAX_COUNT +MAX_COUNT
45                           JB NEXT2
46             OVER:  MOV AH,4CH
47                             INT 21H
48                 CSEG ENDS
49                             END START
View Code

這個題目考了很多地方,當程序需要三個指針的時候,這個時候BX,SI,DI都可以作為指針

這個題目相當的給力,可以好好看看

 

版權所有:轉載注明鏈接地址:http://www.cnblogs.com/fengdashen/p/3704148.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM