x86基础实验-字典排序

简介

输入n个字符串,对其进行字典排序并输出。(每个字符串长度最长为216-1,支持跨段。字符串个数n最多为约214个)

程序运行结果
image.png
代码
ASSUME  CS:CODE1,DS:DATA1,SS:STACK1

STACK1  SEGMENT PARA    STACK
STACK_AREA      DW      100H DUP(?)
STACK_BTM       EQU     $-STACK_AREA
STACK1          ENDS

CODE1   SEGMENT

MAIN    PROC    FAR  

        MOV     AX,STACK1
        MOV     SS,AX
        MOV     SP,STACK_BTM
        MOV     AX,DATA1
        MOV     DS,AX
        MOV     ES,AX


        CALL    INPUT

        MOV     AX,OFFSET POINTER
        PUSH    AX
        ADD     AX,4
        PUSH    AX
        CALL    CMP_STR
        PUSH    AX
        MOV     DX,AX

        MOV     AX,OFFSET POINTER
        PUSH    AX
        MOV     AX,POINTER_LEN
        PUSH    AX
        CALL    SORT


        MOV     CX,POINTER_LEN
        MOV     SI,OFFSET POINTER
OUTPUT_SORTED_STR_LOOP:
        PUSH    SI
        CALL    OUTPUT_STR_DD

        ADD     SI,4

        MOV     AX,OFFSET STR_ENTER
        PUSH    AX
        CALL    OUTPUT_STR

        LOOP OUTPUT_SORTED_STR_LOOP
    

        MOV     AX,4C00H
        INT     21H


MAIN    ENDP

GETCHAR PROC    NEAR    ;获得一个内存地址中存储的字节 ;[sp+2] pos [sp+4] pointer [sp+6] segment pointer,return in AX
        PUSH    BX
        PUSH    CX
        PUSH    DX
        PUSH    SI
        PUSH    ES

        MOV     SI,SP

        MOV     BX,SS:[SI+14] ;pointer
        MOV     ES,SS:[SI+16] ;segment
        MOV     CX,SS:[SI+12] ;pos

        MOV     AX,-1
        SUB     AX,BX
        CMP     AX,CX
        JB      GETCHAR_INC_REPOSITION
        ADD     BX,CX
        MOV     AL,ES:[BX]
        JMP     GETCHAR_EXIT

GETCHAR_INC_REPOSITION:
        MOV     DX,ES
        ADD     DX,1000H
        MOV     ES,DX

        SUB     CX,AX
        DEC     CX
        MOV     BX,CX
        MOV     AL,ES:[BX]

GETCHAR_EXIT:
        MOV     AH,0
        POP     ES
        POP     SI
        POP     DX
        POP     CX
        POP     BX
        RET     6

GETCHAR ENDP

SWAP_DD PROC    NEAR; 交换两个内存地址中的内容 [SP+2] addr dd1 [SP+4] addr dd2

        PUSH    SI
        PUSH    DI
        PUSH    AX
        PUSH    BX
        PUSH    CX
        PUSH    DX

        MOV     SI,SP
        MOV     DI,SS:[SI+16]
        MOV     SI,SS:[SI+14]

        MOV     AX,[SI]
        MOV     DX,[SI+2]
        MOV     BX,[DI]
        MOV     CX,[DI+2]

        MOV     [SI],BX
        MOV     [SI+2],CX

        MOV     [DI],AX
        MOV     [DI+2],DX

        POP     DX
        POP     CX
        POP     BX
        POP     AX
        POP     DI
        POP     SI
        RET     4

SWAP_DD ENDP

CMP_STR PROC    NEAR;   比较两字符串 [SP+2] addr dd of str2 [SP+4] addr dd of str1,ret in al

        PUSH    SI
        PUSH    DI
        PUSH    BX
        PUSH    CX
        PUSH    DX

        MOV     SI,SP
        MOV     DI,SS:[SI+12];str2
        MOV     SI,SS:[SI+14];str1
        
        MOV     CX,0 
        MOV     AX,0

LOOP_CMP_STR:
        MOV     AX,[SI]
        PUSH    AX
        MOV     AX,[SI+2]
        PUSH    AX
        PUSH    CX
        CALL    GETCHAR
        MOV     DL,AL

        MOV     AX,[DI]
        PUSH    AX
        MOV     AX,[DI+2]
        PUSH    AX
        PUSH    CX
        CALL    GETCHAR
        MOV     DH,AL

        SUB     AL,DL 

        JNZ     EXIT_CMP_STR

        CMP     DL,0
        JZ      EXIT_CMP_STR

        INC     CX

        JMP     LOOP_CMP_STR

EXIT_CMP_STR:

        POP     DX
        POP     CX
        POP     BX
        POP     DI
        POP     SI

        RET     4
CMP_STR ENDP

SORT    PROC    NEAR    ;字符串排序 [sp+2] len [sp+4] begin pointer

        PUSH    SI
        PUSH    DI
        PUSH    BP 
        PUSH    AX
        PUSH    BX
        PUSH    CX
        PUSH    DX

        MOV     SI,SP
        MOV     BP,SS:[SI+16];len
        MOV     SI,SS:[SI+18];begin pointer
        
        MOV     DX,BP 
        DEC     DX
SORT_LOOP_1:
        MOV     CX,BP
        DEC     CX
SORT_LOOP_2:
        MOV     BX,CX 
        SHL     BX,1 
        SHL     BX,1 

        MOV     AX,SI;[SI+BX-4] 
        ADD     AX,BX
        SUB     AX,4
        PUSH    AX
        ;MOV     AX,[SI+BX]
        ADD     AX,4
        PUSH    AX
        CALL    CMP_STR

        CMP     AL,0
        JG     SORT_SKIP_SWAP
        
        ;MOV     AX,[SI+BX-4]
        MOV     AX,SI
        ADD     AX,BX
        PUSH    AX
        SUB     AX,4
        ;MOV     AX,[SI+BX]
        PUSH    AX
        CALL    SWAP_DD

SORT_SKIP_SWAP:

        LOOP    SORT_LOOP_2

        DEC     DX
        CMP     DX,0
        JNZ     SORT_LOOP_1

END_SORT_LOOP_1:
        POP     DX
        POP     CX
        POP     BX
        POP     AX
        POP     BP
        POP     DI
        POP     SI
        RET     4
SORT    ENDP

INPUT16 PROC    NEAR ; read a number in 16hex,return in ax
        PUSH    BX
        PUSH    CX
        PUSH    DX

        MOV     DX,0
INPUT16_LOOP:
        MOV     AH,01H
        INT     21H
        CMP AL,30H
        JB  INPUT16_NOT_NUM
        CMP AL,39H
        JA  INPUT16_NOT_NUM
        MOV BH,0
        MOV BL,AL
        SUB BX,30H
        JMP INPUT16_RCL

INPUT16_NOT_NUM:
        CMP AL,41H
        JB  INPUT16_NOT_ALP
        CMP AL,46H
        JA  INPUT16_NOT_ALP
        MOV BH,0
        MOV BL,AL
        SUB BX,41H
        ADD BX,10
        JMP INPUT16_RCL

INPUT16_RCL:
        SHL DX,1
        SHL DX,1
        SHL DX,1
        SHL DX,1
        OR  DL,BL
        JMP INPUT16_LOOP

INPUT16_NOT_ALP:
        MOV AX,DX

        POP    DX
        POP    CX
        POP    BX
        RET 

INPUT16 ENDP

INPUT   PROC    NEAR
        
        MOV     AX,OFFSET STR_INPUT_POINTER_LEN_EXPLAIN
        PUSH    AX
        CALL    OUTPUT_STR

        CALL    INPUT16
        MOV     BX,OFFSET POINTER_LEN
        MOV     [BX],AX
        
        MOV     CX,AX

        MOV     DX,DS
        MOV     ES,DX
        MOV     BP,OFFSET CONTENT
        MOV     SI,OFFSET POINTER
INPUT_LOOP:
        MOV     AX,OFFSET STR_INPUT_CONTENT_EXPLAIN
        PUSH    AX
        CALL    OUTPUT_STR

        MOV     [SI],ES
        MOV     [SI+2],BP
        ADD     SI,4
        CALL    INPUT_STR
        LOOP    INPUT_LOOP

        RET

INPUT   ENDP

INPUT_STR   PROC    NEAR    ;\n end  es:Bp
    
    PUSH SI
    PUSH AX
    PUSH BX
    PUSH CX
    PUSH DX

INPUT_STR_LOOP:
    MOV     AH,01H
    INT     21H
    CMP     AL,13   ;\n
    JZ      END_INPUT_STR_LOOP    
    MOV     ES:[BP],AL 
    INC     BP

    CMP     BP,0
    JNZ     INPUT_STR_LOOP

    MOV     DX,ES
    ADD     DX,1000H
    MOV     ES,DX

    JMP     INPUT_STR_LOOP

END_INPUT_STR_LOOP:

    MOV     BYTE PTR ES:[BP],0
    
    INC     BP
    CMP     BP,0
    JNZ     EXIT_INPUT_STR
    MOV     DX,ES
    ADD     DX,1000H
    MOV     ES,DX

EXIT_INPUT_STR:


    POP DX
    POP CX
    POP BX
    POP AX
    POP SI

    RET 

    
INPUT_STR   ENDP
OUTPUT_STR  PROC    NEAR ;OUTPUT a string end with '\0' [SP+2] str
    PUSH    SI
    PUSH    AX
    PUSH    DX

    MOV     SI,SP
    MOV     SI,SS:[SI+8]

    MOV     AH,2H
OUTPUT_STR_LOOP:
    MOV     DL,[SI]
    CMP     DL,0
    JZ      END_OUTPUT_STR_LOOP
    INT     21H
    INC     SI
    JMP     OUTPUT_STR_LOOP

END_OUTPUT_STR_LOOP:    

    POP     DX
    POP     AX
    POP     SI
    RET     2
OUTPUT_STR  ENDP

OUTPUT_STR_DD   PROC    NEAR ;out astring in [[SP+2]]:[[sp+2]+2]
    PUSH    SI
    PUSH    AX
    PUSH    DX
    PUSH    ES

    MOV     SI,SP
    MOV     SI,SS:[SI+10]
    MOV     DX,[SI]
    MOV     AX,[SI+2]
    MOV     SI,0

OUTPUT_STR_DD_LOOP:
    PUSH    DX
    PUSH    AX

    PUSH    DX
    PUSH    AX
    PUSH    SI
    CALL    GETCHAR

    MOV     DL,AL
    CMP     DL,0
    JZ      END_OUTPUT_STR_DD_LOOP
    MOV     AH,02H
    INT     21H
    INC     SI
    POP     AX
    POP     DX
    JMP     OUTPUT_STR_DD_LOOP

END_OUTPUT_STR_DD_LOOP:
    POP     AX
    POP     DX

    POP     ES
    POP     DX 
    POP     AX
    POP     SI
    RET     2

OUTPUT_STR_DD   ENDP

CODE1   ENDS

DATA1   SEGMENT

STR_INPUT_POINTER_LEN_EXPLAIN   DB  "please input number of words(HEX)",13,10,0
STR_INPUT_CONTENT_EXPLAIN       DB  "please input word",13,10,0
STR_ENTER                   DB  13,10,0

POINTER_LEN         DW  100H  ;support at most 100H words
POINTER             DD  100H  DUP(?)
CONTENT             DB  0

DATA1   ENDS

END MAIN

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,457评论 5 459
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,837评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,696评论 0 319
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,183评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,057评论 4 355
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,105评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,520评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,211评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,482评论 1 290
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,574评论 2 309
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,353评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,213评论 3 312
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,576评论 3 298
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,897评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,174评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,489评论 2 341
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,683评论 2 335

推荐阅读更多精彩内容