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

如何用ARM汇编将用户输入的变量存储到指定地址?

ARM汇编:将scanf读取的数值存入指定地址

我通过scanf读取输入值并存入变量,希望把这个变量的值写入预先定义的指定地址,但尝试用address dcd 0x2000000的方式未成功,相关代码如下:

/* -- printf01.s */
.data
address dcd 0x2000000
/* First message */
.balign 4
ask_number: .asciz "Enter a number to store: "

.balign 4
ask_address: .asciz "Enter an address:"

/* Second message */
.balign 4
read_number: .asciz "Number from user input is %d\n"

.balign 4
read_address: .asciz "Number in address %d is %d\n"

/* Format pattern for scanf */
.balign 4
scan_pattern: .asciz "%d"

/* Where scanf will store the number read */
.balign 4
number: .word 0

.balign 4
return: .word 0

.text
.global main
main:
ldr r1, =return
str lr, [r1] @ save return address into return

ldr r0, =ask_number @ r0 <- &message1
bl printf @ call to printf

ldr r0, =scan_pattern @ r0 <- &scan_pattern
ldr r1, =number @ r1 <- &number_read
bl scanf @ call to scanf

ldr r0, =read_number
ldr r1, =number
ldr r1, [r1]
bl printf

ldr r0, =read_address @ r0 <- &message2
ldr r1, =number @ r1 <- &number_read
ldr r2, [r1] @ r1 <- *r1
bl printf @ call to printf

ldr lr, =return
ldr lr, [lr] @ load return address
bx lr

/* External */
.global printf
.global scanf

问题分析与解决方案

原代码核心问题是没有实现将number的值写入address指向内存的逻辑,仅定义了address变量但未用它完成存储操作。以下是两种修正方案:

方案1:使用预先定义的固定地址

在读取用户输入数值后,添加代码将数值写入address指定的内存地址:

/* -- 修改后的printf01.s */
.data
address dcd 0x2000000
/* First message */
.balign 4
ask_number: .asciz "Enter a number to store: "

.balign 4
read_number: .asciz "Number from user input is %d\n"

.balign 4
read_address: .asciz "Number in address 0x%x is %d\n"

/* Format pattern for scanf */
.balign 4
scan_pattern: .asciz "%d"

/* Where scanf will store the number read */
.balign 4
number: .word 0

.balign 4
return: .word 0

.text
.global main
main:
ldr r1, =return
str lr, [r1] @ save return address into return

@ 读取用户输入的数值
ldr r0, =ask_number
bl printf

ldr r0, =scan_pattern
ldr r1, =number
bl scanf

@ 打印读取到的数值
ldr r0, =read_number
ldr r1, =number
ldr r1, [r1]
bl printf

@ 将数值写入指定地址
ldr r0, =address    @ 加载address变量的地址
ldr r0, [r0]        @ 获取目标内存地址(0x2000000)
ldr r1, =number     @ 加载number变量的地址
ldr r1, [r1]        @ 获取用户输入的数值
str r1, [r0]        @ 将数值存储到目标地址

@ 打印目标地址中的数值
ldr r0, =read_address
ldr r1, =address
ldr r1, [r1]        @ 获取目标地址值
ldr r2, [r1]        @ 从目标地址读取数值
bl printf

@ 返回
ldr lr, =return
ldr lr, [lr]
bx lr

/* External */
.global printf
.global scanf

方案2:让用户输入目标地址(更灵活)

利用已定义的ask_address提示用户输入地址,再将数值写入该地址:

/* -- 支持用户输入地址的版本 */
.data
address dcd 0x0
/* First message */
.balign 4
ask_number: .asciz "Enter a number to store: "

.balign 4
ask_address: .asciz "Enter an address (decimal): "

.balign 4
read_number: .asciz "Number from user input is %d\n"

.balign 4
read_address: .asciz "Number in address 0x%x is %d\n"

/* Format pattern for scanf */
.balign 4
scan_pattern: .asciz "%d"

/* Where scanf will store the number read */
.balign 4
number: .word 0

.balign 4
return: .word 0

.text
.global main
main:
ldr r1, =return
str lr, [r1] @ save return address into return

@ 读取用户输入的数值
ldr r0, =ask_number
bl printf

ldr r0, =scan_pattern
ldr r1, =number
bl scanf

@ 读取用户输入的目标地址
ldr r0, =ask_address
bl printf

ldr r0, =scan_pattern
ldr r1, =address
bl scanf

@ 打印读取到的数值
ldr r0, =read_number
ldr r1, =number
ldr r1, [r1]
bl printf

@ 将数值写入用户指定的地址
ldr r0, =address
ldr r0, [r0]        @ 获取用户输入的目标地址
ldr r1, =number
ldr r1, [r1]        @ 获取用户输入的数值
str r1, [r0]        @ 存储数值到目标地址

@ 打印目标地址中的数值
ldr r0, =read_address
ldr r1, =address
ldr r1, [r1]
ldr r2, [r1]
bl printf

@ 返回
ldr lr, =return
ldr lr, [lr]
bx lr

/* External */
.global printf
.global scanf

关键说明

  • dcd是汇编器指令,仅用于在数据段定义32位常量,初始化address的值为0x2000000,但不会自动将其他变量的值写入该地址,必须通过str指令手动完成存储。
  • ldr r0, =address加载的是address变量本身的地址,需要再用ldr r0, [r0]才能获取它存储的目标内存地址值。
  • 注意内存地址合法性:写入只读区域或无效地址会导致程序崩溃,测试建议使用数据段内地址或系统允许的可写内存区域。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 05:01:36