assembly 如何用汇编arm64 macos存储和显示数据

ecfdbz9o  于 2023-05-18  发布在  Mac
关注(0)|答案(1)|浏览(135)

我目前正在学习汇编,我在Mac M2上,所以用ARM64,我找不到显示用户输入的方法。下面是我的代码:

.global _main
.align 2

_main:
    b _printf
    b _read
    b _prinfbuffer
    b _terminate

_printf:
    mov X0, #1                      // stdout
    adr X1, prompt                  // address of string
    mov X2, #17                     // nbyte
    mov X16, #4                     // write
    svc 0                           // call syscall

_read:
    mov X0, #0                      // stdin
    adr X1, buffer                  // address of buffer
    mov X2, #1024                   // maximum number of bytes to read
    mov X16, #3                     // read
    svc 0                           // call syscall

_prinfbuffer:
    mov X0, 1                       // stdout
    adr X1, buffer                  // address of buffer
    mov X2, #1024                   // nbyte
    mov X16, #4                     // write
    svc 0                           // call syscall

_terminate:
    mov X0, #0                      // return 0
    mov X16, #1                     // terminate
    svc 0                           // call syscall

// hello world string
prompt: .ascii "Say something: \n"
.align 2
buffer: .space 1024

输出如下:

❯ ./hello
Say something: 
a
❯

是的,一个空的空间,之后它关闭程序。
有谁知道怎么解决这个问题。
是的,我已经看了系统调用。主文档。
我试图用ARM64组件发回用户的输入。

6g8kf2rb

6g8kf2rb1#

问题是(正如Jester所建议的那样).text部分是只读的。您需要将缓冲区移动到可写的.data部分。我相信这意味着您也需要从ADR转换到ADRP/ADD模式(如Apple Clang12 LLVM - unknown AArch64 fixup kind中所讨论的)。
因此,也许:

.text
    .global _main
    .align 2

_main:
    bl _printprompt
    bl _read
    bl _printbuffer
    bl _terminate

_printprompt:
    mov x0, #1                      // stdout
    adrp x1, prompt@PAGE            // address of string
    add x1, x1, prompt@PAGEOFF
    mov x2, #17                     // nbyte
    mov x16, #4                     // write
    svc 0                           // call syscall
    ret

_read:
    mov x0, #0                      // stdin
    adrp x1, buffer@PAGE            // address of buffer
    add x1, x1, buffer@PAGEOFF
    mov x2, #1024                   // maximum number of bytes to read
    mov x16, #3                     // read
    svc 0                           // call syscall
    ret

_printbuffer:
    mov x2, x0                      // move byte count to x2 (the nbyte for write syscall)
    mov x0, #1                      // stdout
    adrp x1, buffer@PAGE            // address of buffer
    add x1, x1, buffer@PAGEOFF
    // mov x2, #1024                // nbyte
    mov x16, #4                     // write
    svc 0                           // call syscall
    ret

_terminate:
    mov x0, #0                      // return 0
    mov x16, #1                     // terminate
    svc 0                           // call syscall
    ret

.data
    prompt: .ascii "Say something: \n"
    .align 2
    buffer: .space 1024

相关问题