如何在Apple Silicon (aarch64 macos)汇编中使用_scanf来读取用户输入?

huangapple go评论85阅读模式
英文:

How to use _scanf in Apple Silicon (aarch64 macos) assembly to read in user input?

问题

I'm new to assembly programming, but I've been figuring a lot out by googling and trial and error. I'm trying to write a simple program that prompts the user to enter a number (with _printf), then reads in and saves that number (_scanf), then prints out a message using the stored number (_printf).

I was able to get the _printf code to work under aarch64 (Apple Silicon) assembly, but no matter what I do, I cannot seem to get _scanf to work. I have looked through the ARM Developer docs, looked at the HelloSilicon github page, and googled for hours, and I cannot come up with anything that works.

In my code (included below), if I comment out the "read_from_keyboard" branch in the following code, the printf functions work just fine. But when I include the "read_from_keyboard" code, I get a "Segmentation fault: 11" error.

Where is my mistake?

  1. .global main
  2. .align 4
  3. main:
  4. // PRINT MESSAGE
  5. ADRP X0, message@PAGE
  6. ADD X0, X0, message@PAGEOFF
  7. BL _printf
  8. // BL read_from_keyboad
  9. // READ NUMBER FROM DATA AND MOVE TO STACK FOR PRINTING
  10. ADRP X10, num@PAGE
  11. ADD X10, X10, num@PAGEOFF
  12. LDR X1, [X10]
  13. STR X1, [SP, #-16]!
  14. // LOAD THE PRINTF FORMATTED MESSAGE
  15. ADRP X0, output_format@PAGE
  16. ADD X0, X0, output_format@PAGEOFF
  17. end:
  18. BL _printf
  19. mov X16, #1
  20. svc 0
  21. read_from_keyboard:
  22. ADRP X0, input_format@PAGE
  23. ADD X0, X0, input_format@PAGEOFF
  24. ADRP X11, num@PAGE
  25. ADD X11, X11, num@PAGEOFF
  26. BL _scanf
  27. ret
  28. .data
  29. .balign 4
  30. message: .asciz "What is your favorite number?\n"
  31. .balign 4
  32. num: .word 32
  33. .balign 4
  34. input_format: .asciz "%d"
  35. .balign 4
  36. output_format: .asciz "Your favorite number is %d \n"

(Note: Code sections are provided as requested. Please note that this code may not run properly due to potential issues with the assembly code itself or system-specific configurations.)

英文:

I'm new to assembly programming, but I've been figuring a lot out by googling and trial and error. I'm trying to write a simple program that prompts the user to enter a number (with _printf), then reads in and saves that number (_scanf), then prints out a message using the stored number (_printf).

I was able to get the _printf code to work under aarch64 (Apple Silicon) assembly, but no matter what I do, I cannot seem to get _scanf to work. I have looked through the ARM Developer docs, looked at the HelloSilicon github page, and googled for hours, and I cannot come up with anything that works.

In my code (included below), if I comment out the "read_from_keyboard" branch in the following code, the printf functions work just fine. But when I include the "read_from_keyboard" code, I get a "Segmentation fault: 11" error.

Where is my mistake?

  1. .global main
  2. .align 4
  3. main:
  4. // PRINT MESSAGE
  5. ADRP X0, message@PAGE
  6. ADD X0, X0, message@PAGEOFF
  7. BL _printf
  8. // BL read_from_keyboad
  9. // READ NUMBER FROM DATA AND MOVE TO STACK FOR PRINTING
  10. ADRP X10, num@PAGE
  11. ADD X10, X10, num@PAGEOFF
  12. LDR X1, [X10]
  13. STR X1, [SP, #-16]!
  14. // LOAD THE PRINTF FORMATTED MESSAGE
  15. ADRP X0, output_format@PAGE
  16. ADD X0, X0, output_format@PAGEOFF
  17. end:
  18. BL _printf
  19. mov X16, #1
  20. svc 0
  21. read_from_keyboard:
  22. ADRP X0, input_format@PAGE
  23. ADD X0, X0, input_format@PAGEOFF
  24. ADRP X11, num@PAGE
  25. ADD X11, X11, num@PAGEOFF
  26. BL _scanf
  27. ret
  28. .data
  29. .balign 4
  30. message: .asciz "What is your favorite number?\n"
  31. .balign 4
  32. num: .word 32
  33. .balign 4
  34. input_format: .asciz "%d"
  35. .balign 4
  36. output_format: .asciz "Your favorite number is %d \n"

答案1

得分: 0

在对 _printf 的调用中,你的可变参数位于 [sp]。在对 _scanf 的调用中,你将它放在了 x11 中。为什么这样做?只需执行与 _printf 中相同的操作 str xN, [sp, #-16]!,这将修复你的段错误。

另外,你还需要为 read_from_keyboard 创建一个堆栈帧。bl _scanf 会破坏 x30,因此接下来的 ret 会陷入无限循环。

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

  1. .global _main
  2. .align 4
  3. _main:
  4. // 打印消息
  5. ADRP X0, message@PAGE
  6. ADD X0, X0, message@PAGEOFF
  7. BL _printf
  8. BL read_from_keyboard
  9. // 从数据中读取数字并移到堆栈以进行打印
  10. ADRP X10, num@PAGE
  11. ADD X10, X10, num@PAGEOFF
  12. LDR X1, [X10]
  13. STR X1, [SP, #-16]!
  14. // 载入 printf 格式化消息
  15. ADRP X0, output_format@PAGE
  16. ADD X0, X0, output_format@PAGEOFF
  17. end:
  18. BL _printf
  19. mov X16, #1
  20. svc 0
  21. read_from_keyboard:
  22. STP X29, X30, [SP, #-16]!
  23. ADRP X0, input_format@PAGE
  24. ADD X0, X0, input_format@PAGEOFF
  25. ADRP X11, num@PAGE
  26. ADD X11, X11, num@PAGEOFF
  27. STR X11, [SP, #-16]!
  28. BL _scanf
  29. ADD SP, SP, #16
  30. LDP X29, X30, [SP], #16
  31. ret
  32. .data
  33. .balign 4
  34. message: .asciz "What is your favorite number?\n"
  35. .balign 4
  36. num: .word 32
  37. .balign 4
  38. input_format: .asciz "%d"
  39. .balign 4
  40. output_format: .asciz "Your favorite number is %d \n"

请注意,我只翻译了代码中的注释和字符串部分,而没有进行其他更改。

英文:

On the call to _printf, your variadic arg is in [sp]. On the call to _scanf, you put it in x11. Why? Just do the same str xN, [sp, #-16]! that you do on _printf, that'll fix your segfault.

In addition though, you also need a stack frame for read_from_keyboard. The bl _scanf clobbers x30, so the following ret would just get stuck in an infinite loop.

Fix these two issues and your code works:

  1. .global _main
  2. .align 4
  3. _main:
  4. // PRINT MESSAGE
  5. ADRP X0, message@PAGE
  6. ADD X0, X0, message@PAGEOFF
  7. BL _printf
  8. BL read_from_keyboard
  9. // READ NUMBER FROM DATA AND MOVE TO STACK FOR PRINTING
  10. ADRP X10, num@PAGE
  11. ADD X10, X10, num@PAGEOFF
  12. LDR X1, [X10]
  13. STR X1, [SP, #-16]!
  14. // LOAD THE PRINTF FORMATTED MESSAGE
  15. ADRP X0, output_format@PAGE
  16. ADD X0, X0, output_format@PAGEOFF
  17. end:
  18. BL _printf
  19. mov X16, #1
  20. svc 0
  21. read_from_keyboard:
  22. STP X29, X30, [SP, #-16]!
  23. ADRP X0, input_format@PAGE
  24. ADD X0, X0, input_format@PAGEOFF
  25. ADRP X11, num@PAGE
  26. ADD X11, X11, num@PAGEOFF
  27. STR X11, [SP, #-16]!
  28. BL _scanf
  29. ADD SP, SP, #16
  30. LDP X29, X30, [SP], #16
  31. ret
  32. .data
  33. .balign 4
  34. message: .asciz "What is your favorite number?\n"
  35. .balign 4
  36. num: .word 32
  37. .balign 4
  38. input_format: .asciz "%d"
  39. .balign 4
  40. output_format: .asciz "Your favorite number is %d \n"

huangapple
  • 本文由 发表于 2023年1月9日 16:42:18
  • 转载请务必保留本文链接:https://go.coder-hub.com/75054828.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定