x86匯編語言實踐(2)


0 寫在前面

  為了更深入的了解程序的實現原理,近期我學習了IBM-PC相關原理,並手工編寫了一些x86匯編程序

  在2017年的計算機組成原理中,曾對MIPS體系結構及其匯編語言有過一定的了解,考慮到x86體系結構在目前的廣泛應用,我通過兩個月左右的時間對x86的相關內容進行了學習。

  在《x86匯編語言實踐》系列中(包括本篇、x86匯編語言實踐(1)x86匯編語言實踐(3)x86匯編語言實踐(4)以及x86匯編語言復習筆記),我通過幾個具體案例對x86匯編語言進行實踐操作,並記錄了自己再編寫匯編代碼中遇到的困難和心得體會,與各位學習x86匯編的朋友共同分享。

  我將我編寫的一些匯編代碼放到了github上,感興趣的朋友可以點擊屏幕左上角的小貓咪進入我的github,或請點擊這里下載源代碼。

1 十進制輸入輸出的乘法練習

1-1 練習要點

  • 輸入輸出中斷調用練習
  • 宏練習
  • 子程序編寫與調用

1-2 實現思路

  • 數據區使用byte類型存放兩個十進制乘數NUM1和NUM2
  • 輸入采用宏GETNUM實現,從百位讀到個位,調用乘法宏MULTI計算出NUM1和NUM2的值
  • 調用乘法宏MULTI計算出結果,並保存到RESULT,以便debug調試
  • 調用OUTPUT子程序進行輸出,輸出從RESULT中保存的結果
  • 其他對於輸入輸出的控制對輸出結果進行改進

1-3 代碼實現

  1 STACK     SEGMENT    PARA    STACK
  2         DW        100H DUP(?)
  3 STACK    ENDS
  4 
  5 DATA    SEGMENT    PARA
  6 NUM1     DB         ?
  7 NUM2    DB         ?
  8 RESULT  DW         ?
  9 DATA     ENDS
 10 
 11 CODE     SEGMENT PARA
 12         ASSUME    CS:CODE,DS:DATA,SS:STACK
 13 
 14 GETNUM     MACRO
 15         MOV     AH,1
 16         INT      21H
 17         SUB     AL,30H
 18         ENDM
 19 
 20 MULTI     MACRO    N1,N2
 21         MOV     AL,N1
 22         MOV     BL,N2
 23         MUL     BL
 24         ENDM
 25 
 26 DIVIDE     MACRO     N1,N2
 27         MOV     AX,N1
 28         MOV     BX,N2
 29         XOR     DX,DX
 30         DIV     BX
 31         ENDM
 32 
 33 DISPNUM MACRO     
 34         PUSH     DX
 35         MOV     AH,2
 36         MOV     DL,AL
 37         ADD     DL,30H
 38         INT     21H
 39         POP     DX
 40         ENDM
 41 
 42 INPUT     MACRO     NUM
 43         GETNUM
 44         MULTI     AL,100
 45         MOV     NUM,AL
 46         GETNUM
 47         MULTI     AL,10
 48         ADD     NUM,AL
 49         GETNUM
 50         ADD     NUM,AL
 51         ENDM
 52 
 53 NEWLINE MACRO
 54         MOV     AH,2
 55         MOV     DL,0DH
 56         INT     21H
 57         MOV     AH,2
 58         MOV     DL,0AH
 59         INT     21H
 60         ENDM
 61 
 62 OUTPUT     PROC
 63         DIVIDE     AX,10000
 64         DISPNUM
 65         DIVIDE     DX,1000
 66         DISPNUM
 67         DIVIDE     DX,100
 68         DISPNUM
 69         DIVIDE     DX,10
 70         DISPNUM
 71         MOV     AL,DL
 72         DISPNUM
 73         RET
 74 OUTPUT     ENDP
 75 
 76 MAIN    PROC     FAR
 77         MOV     AX,DATA
 78         MOV     DS,AX
 79         ;get num1
 80         INPUT     NUM1
 81         ;getchar
 82         GETNUM
 83         XOR     AX,AX
 84         ;get num2
 85         INPUT     NUM2
 86         ;num1 * num2
 87         MULTI     NUM1,NUM2
 88         MOV     RESULT,AX
 89         ;newline
 90         NEWLINE
 91         ;output result
 92         MOV     AX,RESULT
 93         CALL     OUTPUT
 94 
 95 
 96 EXIT:    MOV     AX,4C00H
 97         INT     21H
 98 MAIN     ENDP
 99 
100 CODE     ENDS
101         END     MAIN

 

1-4 實現效果截圖

經驗證,發現輸出結果符合預期。

2 字符串操作與跳轉表練習

2-1 練習要點

  • 字符串的操作,包括:字符串的拼接、比較、查找
  • 子程序調用與宏
  • 跳轉表的使用

2-2 重點難點

  • 子程序調用需要對子程序中使用到的變量進行壓棧處理,以免變量污染
  • 字符串操作通常都需要對ES:DI和DS:SI進行初始化
  • 宏的內容不能有標簽

2-3 實現思路

  • 首先為輸入和輸出單獨編寫子程序,程序主體采用跳轉表實現
  • 為每一個條件單獨編寫一個子程序,有4個條件,因此共需編寫4個子程序

2-4 代碼實現

    

  1 STACK     SEGMENT    PARA    STACK
  2         DW        100H DUP(?)
  3 STACK    ENDS
  4 
  5 DATA    SEGMENT    PARA
  6     LEN        EQU     128
  7     MSG1    DB        'INPUT OPRAND:',13,10,'$'    ;THE MSG TO OUTPUT
  8     MSG2     DB         'INPUT STRING 1:',13,10,'$'
  9     MSG3     DB         'INPUT STRING 2:',13,10,'$'
 10     MSG4    DB        '<','$'
 11     MSG5    DB        '=','$'
 12     MSG6    DB        '>','$'
 13     MSG7    DB        'S3=','$'
 14     MSG8     DB         'INPUT A CHAR:',13,10,'$'
 15     MSG9    DB         'CHAR FOUND IN STR1!',13,10,'$'
 16     MSG10     DB         'CHAR NOT FOUND IN STR1!',13,10,'$'
 17     STR1    DB        LEN-1
 18             DB        ?
 19             DB        LEN DUP(?)
 20     STR2    DB        LEN-1
 21             DB        ?
 22             DB        LEN DUP(?)
 23     STR3    DB        LEN-1
 24             DB        ?
 25             DB        LEN DUP(?)
 26     CHAR     DB        ?
 27     OP         DB         ? ;THE OPRAND USER INPUT
 28 DATA     ENDS
 29 
 30 CODE     SEGMENT PARA
 31     ASSUME    CS:CODE,DS:DATA,SS:STACK
 32 
 33     HINT     MACRO     MSG
 34         LEA     DX,MSG ;OUTPUT MSG1
 35         MOV     AH,09H
 36         INT     21H
 37         ENDM
 38 
 39     GETOP     MACRO 
 40         MOV     AH,1
 41         INT     21H
 42         SUB     AL,30H
 43         MOV     OP,AL
 44         ENDM
 45 
 46     NEWLINE MACRO
 47         PUSH     AX
 48         PUSH     DX
 49         MOV     AH,2
 50         MOV        DL,0DH
 51         INT     21H
 52         MOV     AH,2
 53         MOV     DL,0AH
 54         INT     21H
 55         POP     DX
 56         POP     AX
 57         ENDM
 58 
 59     GETCHAR MACRO
 60         MOV        AH,1
 61         INT     21H
 62         MOV     CHAR,AL
 63         ENDM
 64 
 65     GETSTR1    PROC
 66         MOV        DX,OFFSET STR1        
 67         MOV     AH,0AH
 68         INT     21H    
 69         MOV        CL,STR1+1
 70         XOR     CH,CH
 71         MOV     SI,OFFSET STR1+2
 72         LP1:    INC     SI
 73         LOOP     LP1
 74         MOV     BYTE PTR [SI],'$'
 75         RET
 76     GETSTR1 ENDP
 77 
 78     GETSTR2 PROC
 79         MOV        DX,OFFSET STR2                
 80         MOV     AH,0AH
 81         INT     21H
 82         MOV        CL,STR2+1
 83         XOR     CH,CH    
 84         MOV     SI,OFFSET STR2+2
 85         LP2:INC     SI
 86         LOOP     LP2
 87         MOV     BYTE PTR [SI],'$'
 88         RET
 89     GETSTR2 ENDP
 90 
 91     STRCAT  PROC
 92         PUSH     AX
 93         CLD
 94         CAT_LP1:LODSB
 95         STOSB
 96         CMP     AL,0
 97         JNZ     CAT_LP1
 98         POP     AX
 99         RET
100     STRCAT     ENDP
101 
102     P2_PUTEND    PROC
103         MOV     CL,STR1+1            ;SET CX TO LEN FOR LOOP
104         ADD     CL,STR2+1
105         XOR     CH,CH
106         MOV     SI,OFFSET STR3+2  ;GET ACTUAL STRING
107         PLP2:     INC     SI
108         LOOP    PLP2
109         MOV     BYTE PTR [SI],'$'      ;PUT END TO STRING 
110         RET
111     P2_PUTEND    ENDP
112     ;STRCMP
113     P1    PROC
114         PUSH     CX
115         CLD
116         PUSH     SI
117         MOV     CX,1
118         SLP1:    LODSB
119         CMP     AL,00H
120         JZ         SLP1_1
121         INC     CX
122         JMP     SHORT SLP1
123         SLP1_1:    POP     SI
124         REPE     CMPSB
125         HINT     STR1+2
126         JA         SL1
127         JB         SL2
128         HINT    MSG5
129         MOV     AL,0
130         JMP     SHORT RETURN
131         SL1:    HINT    MSG6
132         MOV     AL,1
133         JMP      SHORT RETURN
134         SL2:    HINT    MSG4
135         MOV     AL,2
136         RETURN:    HINT     STR2+2
137         POP     CX
138         RET
139     P1    ENDP
140     ;STRCAT(S1,S2)+STRCPY(S3,S1)
141     P2     PROC
142         ;STRCAT(S1,S2)
143         PUSH     AX
144         MOV     SI,OFFSET STR2+2
145         MOV     CL,STR1+1        
146         XOR     CH,CH
147         MOV     DI,OFFSET STR1+2  
148         CATLP1: INC     DI
149         LOOP    CATLP1
150         CALL     STRCAT
151         ;STRCPY(S3,S1)
152         MOV     SI,OFFSET STR1+2
153         MOV     DI,OFFSET STR3+2
154         CALL     STRCAT
155         CALL     P2_PUTEND
156         HINT     MSG7
157         HINT     STR3+2
158         POP     AX
159         RET
160     P2    ENDP
161     ;STRCAT(S2,S1)+STRCPY(S3,S2)
162     P2_2 PROC
163         ;STRCAT(S2,S1)
164         PUSH     AX
165         MOV     SI,OFFSET STR1+2
166         MOV     CL,STR2+1        
167         XOR     CH,CH
168         MOV     DI,OFFSET STR2+2  
169         CATLP2: INC     DI
170         LOOP    CATLP2
171         CALL     STRCAT
172         ;STRCPY(S3,S1)
173         MOV     SI,OFFSET STR2+2
174         MOV     DI,OFFSET STR3+2
175         CALL     STRCAT
176         CALL     P2_PUTEND
177         HINT     MSG7
178         HINT     STR3+2
179         POP     AX
180         RET
181     P2_2 ENDP
182     ;STRFIND
183     P3     PROC
184         HINT     MSG8
185         GETCHAR
186         NEWLINE
187         MOV        DI,OFFSET STR1+2
188         MOV     CL,STR1+1
189         XOR     CH,CH
190         MOV     AL,CHAR
191         CLD
192         REPNZ     SCASB
193         JZ         FOUND
194         HINT     MSG10
195         JMP        P3_RETURN
196         FOUND:    HINT MSG9
197         P3_RETURN:RET
198     P3    ENDP
199     ;SRTCMP+STRCAT+STRCPY
200     P4     PROC
201         MOV     SI,OFFSET STR1+2
202         MOV     DI,OFFSET STR2+2
203         CALL     P1
204         NEWLINE
205         CMP     AL,0
206         JNE     LA41
207         CALL    P2 
208         JMP     CONTINUE4
209         LA41:    CMP     AL,1
210         JNE     LA42
211         CALL     P2    
212         JMP     CONTINUE4
213         LA42:    CMP     AL,2
214         JNE     CONTINUE4
215         CALL     P2_2    
216         CONTINUE4:
217         RET
218     P4    ENDP
219 
220     SWITCH    PROC
221         CMP     OP,1
222         JNE     LA1
223         MOV     SI,OFFSET STR1+2
224         MOV     DI,OFFSET STR2+2
225         CALL     P1
226         JMP        CONTINUE
227         LA1:    CMP     OP,2
228         JNE     LA2
229         CALL     P2
230         JMP        CONTINUE
231         LA2:    CMP     OP,3
232         JNE     LA3
233         CALL     P3
234         JMP        CONTINUE
235         LA3:    CMP     OP,4
236         JNE     LAN
237         CALL     P4
238         JMP     CONTINUE
239         LAN:    HINT     MSG3
240         CONTINUE:RET
241     SWITCH     ENDP
242 
243     MAIN    PROC     FAR
244         MOV     AX,DATA
245         MOV     DS,AX
246         MOV         ES,AX
247         
248         ;input str1
249         HINT     MSG2
250         CALL     GETSTR1
251         NEWLINE
252         ;input str2
253         HINT     MSG3
254         CALL     GETSTR2
255         NEWLINE
256         ;input op
257         HINT     MSG1
258         GETOP
259         NEWLINE
260         ;SWITCH OP
261         CALL     SWITCH
262             
263         EXIT:    MOV     AX,4C00H
264         INT     21H
265     MAIN     ENDP
266 
267 CODE     ENDS
268         END     MAIN

 

2-5 運行結果

2-5-1 操作類型為1,即比較str1和str2的字典序

2-5-2 操作類型為2,即將str2拼接到str1后,並將整個串拷貝至str3

 

2-5-3 操作類型為3,即再輸入一個字符char,判斷char是否屬於str1

 

2-5-4 操作類型為4,即比較str1和str2的字典序按降序進行拼接,並拷貝到str3

 

顯然,運行結果符合預期。

3 字符串按字典序排序

3-1 練習要點

  • 字符串的操作,LODSB,STOSB,CMPSB,REPE等等
  • 各個字符串操作指令對PSW和SI,DI的影響
  • 子程序調用與宏
  • 冒泡排序算法
  • 復雜程序的調試

3-2 重點難點

  • 冒泡排序
  • 宏和子程序的編寫時必須注意堆棧的維護,用到的變量必須壓棧處理
  • 字符串交換的邏輯
  • 操作字符串的子程序必須對SI,DI壓棧保存,因為會隱式修改SI,DI

3-3 實現思路

  • 調用輸出子程序輸出原單詞表
  • 調用排序子程序
  • 調用輸出子程序輸出排序后的單詞表

3-4 代碼實現

  • 輸出子程序中每輸出一個單詞,就將SI增加STR_LEN,循環輸出TABLE_LEN次
  • 排序子程序采用冒泡,在相鄰兩單詞比較時,將當前單詞置於DS:SI,相鄰下一單詞置於ES:DI,並比較其字典序,若當前單詞字典序較大,則調用交換子程序,並將標志位BX置0,表示這一趟外層循環排序有調整。當一趟外層循環排序無調整,則表示當前單詞表有序,即可退出排序子程序。
  • 比較子程序要注意對SI的維護,以及REPE CMPSB的含義:當CX≠0且ZF=1時執行CMPSB,CMPSB返回SI和DI的比較結果,並將二者分別+1,CX為提前計算好的兩字符串的長度。含義是,當兩字符串的前若干位字符相同時,就繼續向后比較,直到比較到長度的結尾,或出現不同時結束。后接JA,JB指令,根據比較結果進行跳轉與執行相關邏輯。
  • 交換S1,S2的邏輯:S1->TMP , S2->S1 , TMP->S2。
  1 STACK     SEGMENT    PARA    STACK
  2         DW        100H DUP(?)
  3 STACK    ENDS
  4 
  5 DATA    SEGMENT    PARA
  6     TABLE_LEN    EQU    9
  7     STR_LEN        EQU 7
  8     TABLE     DB    'QIQI',20H,0,'$'
  9             DB     'CHEN',20H,0,'$'
 10             DB    'XIAN',20H,0,'$'
 11             DB    'QIQJ',20H,0,'$'
 12             DB    'XHAN',20H,0,'$'
 13             DB    'XIBN',20H,0,'$'
 14             DB    'XHQI',20H,0,'$'
 15             DB    'LOVE',20H,0,'$'
 16             DB    'SURE',20H,0,'$'
 17     TEMP    DB    STR_LEN DUP(?)
 18     NEW_LINE    DB    0DH,0AH,'$'
 19 DATA     ENDS
 20 
 21 CODE     SEGMENT PARA
 22         ASSUME    CS:CODE,DS:DATA,SS:STACK
 23 
 24 NEWLINE MACRO
 25     PUSH     DX
 26     PUSH    AX
 27     MOV     DX,OFFSET NEW_LINE
 28     MOV     AH,9
 29     INT     21H
 30     POP     AX
 31     POP     DX
 32     ENDM
 33 
 34 OUTPUT     PROC
 35     PART1:
 36         MOV     CX,TABLE_LEN
 37         MOV     SI,OFFSET TABLE
 38     LP1:    
 39         MOV     DX,SI
 40         MOV     AH,9
 41         INT     21H                 
 42         ADD        SI,STR_LEN
 43         LOOP    LP1
 44         NEWLINE
 45         RET
 46 OUTPUT    ENDP
 47 
 48 COMP    PROC
 49     COMPARE:
 50         PUSH    SI
 51         PUSH     CX
 52         CLD
 53         PUSH     SI
 54         MOV     CX,1
 55     SLP1:    
 56         LODSB
 57         CMP     AL,00H
 58         JZ         SLP1_1
 59         INC     CX
 60         JMP     SHORT SLP1
 61     SLP1_1:    
 62         POP     SI
 63         REPE     CMPSB
 64         JA         SL1
 65         JB         SL2
 66         MOV     AL,1    ;SI=DI
 67         JMP     SHORT RETURN
 68     SL1:    
 69         MOV     AL,2     ;SI>DI
 70         JMP      SHORT RETURN
 71     SL2:        
 72         MOV     AL,0    ;SI<DI
 73     RETURN:    
 74         POP     CX
 75         POP     SI
 76         RET
 77 COMP    ENDP
 78 
 79 STRCPY     PROC
 80     STRING_COPY:
 81         PUSH    SI
 82         PUSH     DI
 83         PUSH     AX
 84         CLD
 85     CPY_LP1:
 86         LODSB
 87         STOSB
 88         CMP     AL,0
 89         JNZ        CPY_LP1
 90         POP     AX
 91         POP     DI
 92         POP        SI
 93         RET
 94 STRCPY     ENDP
 95 
 96 EXCHG    PROC
 97     EXCHANGE:
 98         PUSH     SI
 99         PUSH     DI
100 
101         MOV     DI,OFFSET TEMP
102         CALL     STRCPY
103 
104         MOV        DI,SI
105         ADD     SI,STR_LEN
106         CALL     STRCPY
107 
108         MOV     DI,SI
109         MOV     SI,OFFSET TEMP
110         CALL     STRCPY
111         POP     DI
112         POP     SI
113         RET
114 EXCHG    ENDP
115 
116 SORT    PROC
117     PART2:
118         MOV        CX,TABLE_LEN
119         DEC        CX
120     LP2:
121         MOV     BX,1
122         MOV     SI,OFFSET TABLE
123         PUSH    CX
124 
125     LP2_1:
126         MOV     AX,SI
127         ADD     AX,STR_LEN
128         MOV        DI,AX
129         CALL     COMP
130         CMP     AL,1
131         JBE        CONTINUE
132         CALL     EXCHG
133         MOV        BX,0
134     CONTINUE:
135         ADD     SI,STR_LEN
136         LOOP     LP2_1
137 
138         POP     CX
139         DEC     CX
140         CMP        BX,1
141         JZ         SORT_RETURN
142         JMP        SHORT LP2
143     SORT_RETURN:
144         RET    
145 SORT     ENDP
146 
147 MAIN    PROC     FAR
148     MAIN_PART:
149         MOV     AX,DATA
150         MOV     DS,AX
151         MOV     ES,AX
152         ;DISPLAY ORIGIN TABLE
153         CALL    OUTPUT
154         ;SORT
155         CALL     SORT
156         ;DISPLAY ORDERED TABLE
157         CALL     OUTPUT
158 
159     EXIT:    
160         MOV     AX,4C00H
161         INT     21H
162 MAIN     ENDP
163 
164 CODE     ENDS
165         END     MAIN

 

3-5 運行結果

在DATA段預置字典如下圖所示

 

編譯、鏈接並執行程序,得到結果如下,第一行為元單詞表,第二行為排序后的單詞表(按字典序升序)

顯然,運行結果符合預期。


免責聲明!

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



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