x86汇编语言实践(2)

空扰寡人 提交于 2020-10-28 14:02:08

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段预置字典如下图所示

 

编译、链接并执行程序,得到结果如下,第一行为元单词表,第二行为排序后的单词表(按字典序升序)

显然,运行结果符合预期。

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!