ARM汇编整数转字符串:如何去除输出的前导零?
如何去除ARM汇编整数转字符串时的前导零
你的问题出在整数转字符串的逻辑上:代码从1000这个最高位除数开始处理,999除以1000得到0,所以第一个字符被写成了'0',最终输出0999。要去掉前导零,得调整转字符串的逻辑,跳过开头的连续零,只从第一个非零数字开始写入,同时还要处理输入为0的特殊情况。
修改后的完整代码
.global _start //; r0: 要转换的整数 str: push {lr} push {r4-r11} mov r2, #0x0 // 字符串当前写入位置索引 mov r3, #1000 // 初始除数(对应4位数的最高位) mov r7, #10 // 除数的基数(10) mov r8, #0x0 // 有效数字标志:0=还没遇到非零,1=已开始写入有效数字 str_loop: mov r4, #0x0 udiv r4, r0, r3 // 计算当前位的数字 add r4, r4, #0x30 // 转成ASCII字符 // 判断是否是前导零,若是则跳过写入 cmp r8, #0 bne write_digit // 已经开始写入有效数字,直接写当前位 cmp r4, #0x30 // 当前位是'0'且还没开始写有效数字 beq skip_write write_digit: mov r8, #1 // 标记已开始写入有效数字 ldr r5, =to_string add r5, r5, r2 strb r4, [r5] add r2, r2, #1 // 移动到下一个写入位置 skip_write: // 计算剩余数值 sub r4, r4, #0x30 mul r6, r4, r3 sub r0, r0, r6 // 更新除数,处理下一位 udiv r6, r3, r7 mov r3, r6 cmp r3, #0 bne str_loop // 处理输入为0的特殊情况:如果没有写入任何字符,手动写一个'0' cmp r8, #0 beq write_zero return_str: // 写入换行符 mov r4, #0xa ldr r5, =to_string add r5, r5, r2 strb r4, [r5] add r2, r2, #1 // 把换行符算入长度,供display使用 pop {r4-r11} pop {pc} write_zero: mov r4, #0x30 ldr r5, =to_string strb r4, [r5] mov r2, #1 // 长度设为1(加上换行符后是2) b return_str display: push {lr} push {r4-r11} mov r7, #0x4 mov r0, #0x1 ldr r1, =to_string // r2是str函数计算出的实际字符长度(含换行符),不用固定为8 svc 0x0 pop {r4-r11} pop {pc} _start: mov r0, #999 bl str bl display // 退出程序 mov r7, #0x1 mov r0, #0 svc 0x0 .section .data to_string: .skip 10
关键修改点说明
- 新增有效数字标志r8:用来记录是否已经开始写入非零数字,初始为0,遇到第一个非零数字后设为1,后续所有数字都正常写入。
- 跳过前导零写入:在每次计算出当前位字符后,判断如果还没开始写入有效数字且当前位是'0',就跳过写入步骤,直接处理下一位。
- 处理输入为0的情况:如果循环结束后,有效数字标志还是0,说明输入的是0,手动写入一个'0',避免输出为空。
- 动态调整输出长度:
display函数不再固定输出8个字符,而是使用str函数中计算的实际字符长度(r2的值),确保只输出有效内容。
编译执行命令
arm-linux-gnueabi-as assignment.asm -o assignment.o arm-linux-gnueabi-gcc-11 assignment.o -o assignment -static -nostdlib
内容的提问来源于stack exchange,提问作者JPHamlett
相关产品推荐
相关产品推荐

