I'm currently trying to learn assembly, I'm on mac M2, so with ARM64, and I can't find a way to display an user input. Here is my code:
.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
The output is this:
❯ ./hello
Say something:
a
❯
Yes, an empty space, after that it close the program.
Does anyone know how to fix this.
And yes I already took a look at the syscalls.master docs.
I tried to send back the input of the user with ARM64 assembly.
The problem is (as Jester suggested) that the .text
section is read-only. You need to move the buffer to a .data
section, which is writable. I believe that means that you need to shift from ADR
to ADRP
/ADD
pattern, too (as discussed in Apple Clang12 LLVM - unknown AArch64 fixup kind).
Thus, perhaps:
.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