You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在汇编语言中按ASCII码升序排序4个可变长度单词?

问题描述

我有4个单词(每个单词长度为1-4个字符),需要按ASCII码对它们进行升序排序,例如输入{'1234','abcd','123','e'},排序后结果应为{'e','123','1234','abcd'}。我编写了一段汇编代码,但冒泡排序部分尚未完成,尝试多种方法后仍无法实现,恳请帮忙完善代码。以下是我的代码:

DOSSEG
    .MODEL SMALL
    .STACK 32
    .DATA
NUMERE  DB  0Dh,0Ah,'Nr.(1)=$'
KBD DB  5,0,0,0,0,0,0
STORE   DB 4 DUP (20h,20h,20h,20h)
    .CODE
START: MOV AX,@DATA
    MOV DS, AX
    MOV CX, 4
    MOV DI, (OFFSET STORE) + 4
AGAIN: PUSH CX ; afisare sir de interogare
    MOV DX, OFFSET NUMERE
    MOV AH, 9
    INT 21h
    INC [NUMERE+6]
    MOV [KBD+1], 0 ; se citeste un numar cu max. 4 cifre
    MOV AH, 0Ah
    MOV DX, OFFSET KBD
    INT 21h
    MOV CL, [KBD+1]
    MOV CH, 0
    MOV SI, (OFFSET KBD) + 2
    PUSH DI
    SUB DI, CX
NEXT: MOV AL, [SI]
    MOV [DI], AL
    INC SI
    INC DI
    LOOP NEXT
    POP DI
    ADD DI, 4
    POP CX
    LOOP AGAIN
;bubble sort starts
MOV CX, 3
SORT:           
    PUSH CX
    MOV CX,3
    MOV SI, OFFSET STORE
    MOV DI, OFFSET STORE+4
    INNER_LOOP:
        MOV AX, [DI]
        CMP [SI], AX
        JNG NO_SWAP
        SWAP: 
        NO_SWAP:
        INC SI
        INC DI
    LOOP INNER_LOOP
    INC SI
 POP CX
 LOOP SORT
;bubble sort ends

MOV SI, OFFSET STORE
MOV CX, 4
DISP: CALL CRLF 
    PUSH CX
    MOV CX,4
NUM:MOV AH, 2
    MOV DL, [SI]
    INT 21h
    INC SI
    LOOP NUM
    POP CX
    LOOP DISP
    MOV AH, 4CH
    INT 21H
CRLF:MOV AH,2
    MOV DL,0Ah
    INT 21h
    MOV AH,2
    MOV DL,0Dh
    INT 21h
    RET
END START
完善后的代码

下面是修复了冒泡排序逻辑的完整代码:

DOSSEG
    .MODEL SMALL
    .STACK 32
    .DATA
NUMERE  DB  0Dh,0Ah,'Nr.(1)=$'
KBD DB  5,0,0,0,0,0,0
STORE   DB 4 DUP (20h,20h,20h,20h)  ; 每个单词占4字节,不足补空格
    .CODE
START: MOV AX,@DATA
    MOV DS, AX
    MOV CX, 4
    MOV DI, (OFFSET STORE) + 4
AGAIN: PUSH CX ; 显示提示信息
    MOV DX, OFFSET NUMERE
    MOV AH, 9
    INT 21h
    INC [NUMERE+6]  ; 更新提示中的数字(1→2→3→4)
    MOV [KBD+1], 0 ; 重置输入长度
    MOV AH, 0Ah
    MOV DX, OFFSET KBD
    INT 21h         ; 调用DOS输入函数
    MOV CL, [KBD+1]
    MOV CH, 0
    MOV SI, (OFFSET KBD) + 2
    PUSH DI
    SUB DI, CX      ; 定位到当前单词的起始位置(从后往前填)
NEXT: MOV AL, [SI]
    MOV [DI], AL
    INC SI
    INC DI
    LOOP NEXT
    POP DI
    ADD DI, 4       ; 移动到下一个单词的起始位置
    POP CX
    LOOP AGAIN

; 冒泡排序开始
MOV CX, 3           ; 外层循环:4个元素需3轮排序
SORT:           
    PUSH CX
    MOV CX, 3       ; 内层循环:每轮比较次数递减,初始3次
    MOV SI, OFFSET STORE
    MOV DI, OFFSET STORE + 4
INNER_LOOP:
    ; 完整比较两个4字节的单词(按ASCII升序,空格ASCII值小于数字/字母)
    MOV AX, [SI]
    CMP AX, [DI]
    JLE SKIP_SWAP   ; 前两个字节小于等于,继续比较后两个
    JMP NEED_SWAP
    MOV AX, [SI+2]
    CMP AX, [DI+2]
    JLE SKIP_SWAP
NEED_SWAP:
    ; 交换两个4字节的单词
    MOV AX, [SI]
    XCHG AX, [DI]
    MOV [SI], AX
    MOV AX, [SI+2]
    XCHG AX, [DI+2]
    MOV [SI+2], AX
SKIP_SWAP:
    ADD SI, 4       ; 移动到下一个单词的起始
    ADD DI, 4
    LOOP INNER_LOOP
    POP CX
    LOOP SORT
; 冒泡排序结束

; 输出排序后的结果
MOV SI, OFFSET STORE
MOV CX, 4
DISP: CALL CRLF 
    PUSH CX
    MOV CX,4
NUM:MOV AH, 2
    MOV DL, [SI]
    INT 21h
    INC SI
    LOOP NUM
    POP CX
    LOOP DISP
    MOV AH, 4CH
    INT 21H
CRLF:MOV AH,2
    MOV DL,0Ah
    INT 21h
    MOV AH,2
    MOV DL,0Dh
    INT 21h
    RET
END START
关键修改说明
  • 完整单词比较:原代码仅比较了每个单词的前2字节,现在改为分两次比较4字节(AX寄存器是16位,每次处理2字节),确保整个单词的ASCII顺序正确。
  • 实现交换逻辑:添加了NEED_SWAP标签下的交换代码,通过XCHG指令交换两个单词的4字节内容。
  • 修正指针移动:内层循环中,每次比较后需要将SI和DI各加4(而非加1),因为每个单词占4字节,这样才能定位到下一个单词的起始位置。
  • 调整循环条件:移除了原代码中多余的INC SI,避免指针越界。

内容的提问来源于stack exchange,提问作者Samuel Edi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 23:33:22