如何用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
相关产品推荐
相关产品推荐

