zoukankan      html  css  js  c++  java
  • 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段预置字典如下图所示

     

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

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

  • 相关阅读:
    gdb 查看变量~p长串末尾省略号, 一个页面显示不完
    Git 在团队中的最佳实践--如何正确使用Git Flow[转]
    apktool+dex2jar+xjad反编译android程序
    浏览器缓存详解:expires,cache-control,last-modified,etag详细说明
    64位windows 7下成功配置TortoiseGit使用Github服务器
    github简单使用教程
    浅淡HTML5移动Web开发
    Surface、SurfaceView、SurfaceHolder及SurfaceHolder.Callback之间的关系
    深入浅出Symfony2
    利用PHP取二进制文件头判断文件类型
  • 原文地址:https://www.cnblogs.com/chrischen98/p/10749148.html
Copyright © 2011-2022 走看看