如何使用_scanf在苹果硅(aarch64 macos)汇编读取用户输入?



我是汇编编程的新手,但我已经通过谷歌搜索和试验和错误弄清楚了很多。我试着写一个简单的程序,提示用户输入一个数字(使用_printf),然后读入并保存该数字(_scanf),然后使用存储的数字(_printf)打印出一条消息。

我能够让_printf代码在aarch64 (Apple Silicon)汇编下工作,但无论我做什么,我似乎都无法让_scanf工作。我已经浏览了ARM开发人员文档,查看了HelloSilicon github页面,并在谷歌上搜索了几个小时,我无法想出任何有效的方法。

在我的代码中(包括下面),如果我注释掉"read_from_keyboard"在下面的代码分支中,printf函数工作得很好。但是当我加上read_from_keyboard时代码,我得到一个"分割错误:11";错误。

我错在哪里?

.global main
.align 4
main:
// PRINT MESSAGE
ADRP    X0, message@PAGE
ADD X0, X0, message@PAGEOFF
BL  _printf
//  BL read_from_keyboad
// READ NUMBER FROM DATA AND MOVE TO STACK FOR PRINTING
ADRP    X10, num@PAGE
ADD X10, X10, num@PAGEOFF
LDR X1, [X10]
STR X1, [SP, #-16]!
// LOAD THE PRINTF FORMATTED MESSAGE
ADRP    X0, output_format@PAGE
ADD X0, X0, output_format@PAGEOFF
end:
BL  _printf
mov X16, #1
svc 0
read_from_keyboard:
ADRP    X0, input_format@PAGE
ADD X0, X0, input_format@PAGEOFF
ADRP    X11, num@PAGE
ADD X11, X11, num@PAGEOFF
BL _scanf
ret

.data
.balign 4
message:    .asciz "What is your favorite number?n"
.balign 4
num:    .word 32
.balign 4
input_format:   .asciz "%d"
.balign 4
output_format:  .asciz "Your favorite number is %d n"

在调用_printf时,您的可变参数在[sp]中。呼叫_scanf时,将其放在x11中。为什么?只要在_printf上做同样的str xN, [sp, #-16]!,就会修复你的段错误。

此外,您还需要read_from_keyboard的堆栈帧。bl _scanf打败了x30,所以接下来的ret会陷入无限循环。

修复这两个问题,你的代码就可以工作了:

.global _main
.align 4
_main:
// PRINT MESSAGE
ADRP    X0, message@PAGE
ADD X0, X0, message@PAGEOFF
BL  _printf
BL read_from_keyboard
// READ NUMBER FROM DATA AND MOVE TO STACK FOR PRINTING
ADRP    X10, num@PAGE
ADD X10, X10, num@PAGEOFF
LDR X1, [X10]
STR X1, [SP, #-16]!
// LOAD THE PRINTF FORMATTED MESSAGE
ADRP    X0, output_format@PAGE
ADD X0, X0, output_format@PAGEOFF
end:
BL  _printf
mov X16, #1
svc 0
read_from_keyboard:
STP X29, X30, [SP, #-16]!
ADRP    X0, input_format@PAGE
ADD X0, X0, input_format@PAGEOFF
ADRP    X11, num@PAGE
ADD X11, X11, num@PAGEOFF
STR X11, [SP, #-16]!
BL _scanf
ADD SP, SP, #16
LDP X29, X30, [SP], #16
ret

.data
.balign 4
message:    .asciz "What is your favorite number?n"
.balign 4
num:    .word 32
.balign 4
input_format:   .asciz "%d"
.balign 4
output_format:  .asciz "Your favorite number is %d n"

最新更新