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

如何修改ARM汇编代码实现依次请求数字、字符输入并分别打印

ARM汇编代码修改方案

原代码存在的核心问题

  • 启动后同时打印数字、字符两个输入提示,不符合「先处理数字输入全流程,再发起字符输入请求」的需求
  • 数字打印完成后直接跳转退出,字符读取、打印的逻辑完全无法执行
  • 字符读取格式串用%c会读取输入数字后残留在缓冲区的换行符,导致无需用户输入就直接拿到无效字符
  • 寄存器逻辑混乱,读取数字后未打印就提前执行字符读取逻辑,覆盖了r1中存储的数字值,导致数字打印结果错误

修改后的完整代码

@ 使用以下命令对该程序进行汇编、链接、运行和调试:
@    as -o student_inputC.o student_inputC.s
@    gcc -o student_inputC student_inputC.o
@    ./student_inputC 
@    gdb --args ./student_inputC 

.equ READERROR, 0 @ 用于检查scanf读取错误。
.global main @ 因使用C库,必须定义main入口。

main:
prompt:
@ 提示用户输入一个数字。
    ldr r0, =strInputPrompt 
    bl  printf              @ 调用C库printf展示输入提示。

get_num_input:
    ldr r0, =numInputPattern @ 配置为读取一个整数。
    ldr r1, =intInput        @ 向r1加载存储输入值的内存地址
    bl  scanf                @ 读取键盘输入。
    cmp r0, #READERROR       @ 检查是否发生读取错误。
    beq readerror            @ 若发生读取错误则跳转至对应处理逻辑。

@ 打印输入的数字
    ldr r1, =intInput
    ldr r1, [r1]
    ldr r0, =strOutputNum
    bl  printf

@ 提示用户输入字符
    ldr r0, =charInputPrompt
    bl printf

get_char_input:
    ldr r0, =charInputPattern @ 配置为读取一个字符,前置空格跳过残留空白符
    ldr r1, =charInput        @ 向r1加载存储输入值的内存地址
    bl  scanf                @ 读取键盘输入。
    cmp r0, #READERROR       @ 检查是否发生读取错误。
    beq readerror            @ 若发生读取错误则跳转至对应处理逻辑。

@ 打印输入的字符
    ldr r1, =charInput
    ldr r1, [r1]
    ldr r0, =strOutputChar
    bl  printf

b   myexit @ 退出程序。

readerror:
@ scanf返回读取错误,清空输入缓冲区后跳转回提示用户重新输入。
@ 由于输入无效,我们需要使用%[^\n]格式读取缓冲区内容直到用户按下回车键,完成输入缓冲区清空。
    ldr r0, =strInputPattern
    ldr r1, =strInputError   @ 向r1加载读取内容的存储地址。
    bl scanf                 @ 读取键盘输入。
@ 不对读取的内容做处理,该操作仅用于清空输入缓冲区。
@ 输入缓冲区现已清空,可以重新请求用户输入。
    b prompt

myexit:
@ 代码执行结束,强制退出并将控制权交还给操作系统
    mov r7, #0x01 @ 退出指令的SVC调用号
    svc 0         @ 发起系统调用。

.data
@ 声明所需的字符串和数据
.balign 4
strInputPrompt: .asciz "Input the number: \n"
.balign 4
strOutputNum: .asciz "The number value is: %d \n"
.balign 4
charInputPrompt: .asciz "Input the character: \n"
.balign 4
strOutputChar: .asciz "The character is: %c \n" 

@ scanf调用的格式串
.balign 4
numInputPattern: .asciz "%d"  @ 读取整数的格式串。
.balign 4
strInputPattern: .asciz "%[^\n]" @ 用于清空无效输入对应的输入缓冲区。
.balign 4
strInputError: .skip 100*4  @ 用于存储清空输入缓冲区时读取的无效内容。
.balign 4
intInput: .word 0   @ 存储用户输入数字的内存位置。
.balign 4
charInputPattern: .asciz " %c"  @ 读取字符的格式串,前置空格跳过空白符。
.balign 4
charInput: .word 0   @ 存储用户输入字符的内存位置

@ 告知汇编器以下为C库函数
.global printf
@  printf使用说明:
@     r0 - 待打印字符串的起始地址,字符串必须符合C编码标准。
@     r1 - 若字符串包含输出参数(如%d、%c等),r1必须存储待打印的数值。
@ 调用返回后r0、r1、r2、r3、r12寄存器的值会被修改。

.global scanf
@  scanf使用说明:
@      r0 - 读取用户输入值所用的输入格式串地址,本示例中为numInputPattern。
@      r1 - 必须存储输入值的存储地址,本示例使用.data段声明的intInput内存位置。
@ 调用返回后r0、r1、r2、r3、r12寄存器的值会被修改。
@ scanf重要说明:
@   若用户输入与输入格式不匹配,寄存器r0将返回0,格式合法则返回1。无效输入不会被自动从输入缓冲区清除,因此执行其他操作前需要手动清空缓冲区。
@
@ scanf与输入格式的附加说明:
@    1. 若使用%s或%c格式,用户输入不会产生错误码,用户在键盘输入的任何内容都会被这两种格式接受。
@    2. 若使用%d格式,用户输入12.123时,scanf会将12识别为有效输入,剩余的.123会留在输入缓冲区中。
@    3. 若使用"%c"格式,所有空白字符会保留在输入缓冲区中,多数情况下用户输入的回车键会留在缓冲区,若下次再用"%c"格式读取会直接返回该回车符。若要忽略这些空白字符,可以使用" %c"作为输入格式,会自动跳过用户输入的所有非打印字符。
@
@ 代码结束,文件末尾请保留一行空行。

关键修改说明

  • 调整了提示语打印时机:进入流程后仅打印数字输入提示,数字读取、打印全流程完成后,再打印字符输入提示
  • 拆分了数字、字符的输入读取逻辑,删除了数字打印后直接跳转退出的错误指令,保证字符处理逻辑可以正常执行
  • 修改字符读取格式串为 %c,前置空格自动跳过输入数字后残留在缓冲区的换行符等空白字符,避免直接读取到无效换行符
  • 调整寄存器使用逻辑,数字读取完成后先完成打印再处理字符相关逻辑,避免数字值被提前覆盖导致打印错误
  • 保留了原有的输入错误处理逻辑,数字、字符输入出错时都会清空缓冲区重新发起输入请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.29 10:57:02