汇编语言:移除整数字符串前导零且保留中间零(替换为空格)
解决汇编中仅替换整数字符串前导零为空格的问题
你的代码当前的问题是没有区分前导零和中间零,只要某一位数字计算结果为0就直接替换成空格,导致中间的零也被替换了。要实现只替换前导零,我们需要添加一个「已遇到非零数字」的标志,当标志未激活时,零替换为空格;一旦遇到第一个非零数字,标志激活,之后所有的零都正常输出为'0'。
修改后的完整代码
ASSUME CS:CODE, DS:DATA CODE SEGMENT BUFFER DB 7 DUP (?) DATA SEGMENT MYNAME DB 'Name$' DATA ENDS START PROC MOV AX, SEG DATA MOV DS, AX MOV DX,OFFSET MYNAME MOV AH,9 INT 21H MOV DL, 10 MOV AH, 02h INT 21h MOV DL, 13 MOV AH, 02h INT 21h MOV AX, 65505 CALL PRN_DEC MOV AX, 539 CALL PRN_DEC MOV AX, 5567 CALL PRN_DEC MOV AX, 0 ; 测试全零的情况,应该输出一个0而不是全空格 CALL PRN_DEC MOV AH,4CH INT 21H START ENDP PRN_DEC PROC MOV BX,SEG CODE MOV ES,BX MOV DS,BX MOV DI, OFFSET BUFFER MOV BX,10000 MOV DX,AX MOV CX,4 XOR SI, SI ; 初始化标志:SI=0表示未遇到非零数字 R1: MOV AX,DX MOV DX,0 DIV BX CMP AX,0 JNZ R4 ; 当前位是0,判断是否已经遇到过非零数字 CMP SI, 1 JNZ R2 ; 没遇到过,替换为空格 MOV AX,30H ; 已经遇到过,输出'0' JMP R5 R2: MOV AX,20H ; 前导零,替换为空格 JMP R5 R4: ADD AX,30H MOV SI, 1 ; 遇到非零数字,激活标志 R5: STOSB PUSH DX MOV AX,BX MOV DX,0 MOV BX,10 DIV BX MOV BX,AX POP DX LOOP R1 ; 处理最后一位数字 MOV AX,DX CMP SI, 0 ; 如果所有位都是0(标志未激活),输出'0' JNZ R6 MOV AX,30H R6: ADD AX,30H STOSB MOV AL,'$' STOSB MOV DX,OFFSET BUFFER MOV AH,9 INT 21H MOV DL, 10 MOV AH, 02h INT 21h MOV DL, 13 MOV AH, 02h INT 21h RET PRN_DEC ENDP CODE ENDS END START
关键修改点说明
- 添加了
XOR SI, SI初始化标志位,SI=0代表还没遇到非零数字,SI=1代表已经遇到过。 - 当计算出当前位为0时,先检查
SI的值:- 如果
SI=0(前导零),替换为空格(20H); - 如果
SI=1(中间零),输出'0'(30H)。
- 如果
- 当遇到非零数字时,设置
SI=1,后续所有零都正常输出。 - 增加了对全零情况的处理:如果循环结束后
SI仍为0,说明输入的数字是0,最后一位输出'0'而不是空格。
这样修改后,就能实现仅替换前导零为空格,保留中间和末尾零的效果,比如输入539会输出 539,输入65505会输出65505,输入0会输出 0。
内容的提问来源于stack exchange,提问作者dsadada
相关产品推荐
相关产品推荐

