在 64 位汇编臂中捕获输入 mac os
Capture input in assembly arm 64 bit mac os
正在尝试从用户输入中捕获两个字符和换行符。
程序将 3 个地狱世界打印到屏幕上,然后用户可以输入一些字符。
一切似乎都有效,但它不打印输入
我怀疑是我在_read函数中对X1寄存器的操作方式,或者buffer的分配方式造成的
运行编译代码时没有报错。
代码是使用以下命令编译的。它应该 运行 在 Mac M1
as HelloWorld.s -o HelloWorld.o && ld -macosx_version_min 12.0.0 -o HelloWorld HelloWorld.o -lSystem -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start -arch arm64 && ./HelloWorld
//HelloWorld.s
.equ SYS_WRITE, 4
.equ SYS_READ, 3
.equ NEWLN, 10
.global _start // Provide program starting address to linker
.align 2
// Setup the parameters to print hello world
// and then call Linux to do it.
_start:
adr X4, helloworld1
mov X1, X4
bl _sizeof
bl _print
adr X4, helloworld2
mov X1, X4
bl _sizeof
bl _print
adr X4, helloworld3
mov X1, X4
bl _sizeof
bl _print
bl _read
//mov X2, 4
// bl _sizeof
bl _print
_exit:
mov X0, X2 // Use 0 return code
mov X16, #1 // Service command code 1 terminates this program
svc 0 // Call MacOS to terminate the program
_sizeof: //X1 = address, X2 = out length, string must terminate with \n
str LR, [SP, #-16]! //Store registers
//str W0, [SP, #-16]!
mov X2, #0
__loop:
ldrb W0, [X1, X2] //load a byte into W0 (32 bit)
add X2, X2, #1 //Add 1 offset
cmp W0, NEWLN //Compare byte with \n return
bne __loop
//ldr W0, [SP], #16
ldr LR, [SP], #16 //Load registers
ret
_print: //X2 = length, X1 = address
str LR, [SP, #-16]! //Store registers
mov X0, #1 // 1 = StdOut
// mov X1, X1 // string to print
// mov X2, X2 // length of string
mov X16, SYS_WRITE // MacOS write system call
svc 0 // Call kernel to output the string
ldr LR, [SP], #16 //Load registers
ret
_read:
//3 AUE_NULL ALL { user_ssize_t read(int fd, user_addr_t cbuf, user_size_t nbyte); }
str LR, [SP, #-16]! //Store registers
adr X1, msg
mov X0, #0 // 0 = StdIn
ldr X1, [x1] // address to store string
mov X2, #4 // length
mov X16, SYS_READ // MacOS read system call
svc 0 // Call system
ldr LR, [SP], #16 //Load registers
ret
msg: .ds 4 //memory buffer for keyboard input
helloworld1: .ascii "Hello World\n"
helloworld2: .ascii "Happy new year for 2022\n"
helloworld3: .ascii "Welcome to AARCH64 assembly on Mac Silicon\n"
首先你需要移动msg
到一个可写段:
.data
msg: .ds 4 //memory buffer for keyboard input
.text // keep everything else in __TEXT
然后,因为段可能会在 link 时间任意移动,Apple 的工具链将不再允许您使用 adr
来获取该缓冲区的地址 - 您将不得不使用adrp
和 add
:
adrp x1, msg@page
add x1, x1, msg@pageoff
如果需要,您可以告诉 link 人员请尽可能将其优化回 adr
:
Lloh0:
adrp x1, msg@page
Lloh1:
add x1, x1, msg@pageoff
.loh AdrpAdd Lloh0, Lloh1
然后你需要删除这一行:
ldr X1, [x1]
这将加载缓冲区的内容,它只是空字节。
最后,您应该将 x0
值更改为 exit
为常量:
mov x0, 0
此时 x2
中的值将被破坏,您也不需要它。
正在尝试从用户输入中捕获两个字符和换行符。
程序将 3 个地狱世界打印到屏幕上,然后用户可以输入一些字符。 一切似乎都有效,但它不打印输入
我怀疑是我在_read函数中对X1寄存器的操作方式,或者buffer的分配方式造成的
运行编译代码时没有报错。
代码是使用以下命令编译的。它应该 运行 在 Mac M1
as HelloWorld.s -o HelloWorld.o && ld -macosx_version_min 12.0.0 -o HelloWorld HelloWorld.o -lSystem -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start -arch arm64 && ./HelloWorld
//HelloWorld.s
.equ SYS_WRITE, 4
.equ SYS_READ, 3
.equ NEWLN, 10
.global _start // Provide program starting address to linker
.align 2
// Setup the parameters to print hello world
// and then call Linux to do it.
_start:
adr X4, helloworld1
mov X1, X4
bl _sizeof
bl _print
adr X4, helloworld2
mov X1, X4
bl _sizeof
bl _print
adr X4, helloworld3
mov X1, X4
bl _sizeof
bl _print
bl _read
//mov X2, 4
// bl _sizeof
bl _print
_exit:
mov X0, X2 // Use 0 return code
mov X16, #1 // Service command code 1 terminates this program
svc 0 // Call MacOS to terminate the program
_sizeof: //X1 = address, X2 = out length, string must terminate with \n
str LR, [SP, #-16]! //Store registers
//str W0, [SP, #-16]!
mov X2, #0
__loop:
ldrb W0, [X1, X2] //load a byte into W0 (32 bit)
add X2, X2, #1 //Add 1 offset
cmp W0, NEWLN //Compare byte with \n return
bne __loop
//ldr W0, [SP], #16
ldr LR, [SP], #16 //Load registers
ret
_print: //X2 = length, X1 = address
str LR, [SP, #-16]! //Store registers
mov X0, #1 // 1 = StdOut
// mov X1, X1 // string to print
// mov X2, X2 // length of string
mov X16, SYS_WRITE // MacOS write system call
svc 0 // Call kernel to output the string
ldr LR, [SP], #16 //Load registers
ret
_read:
//3 AUE_NULL ALL { user_ssize_t read(int fd, user_addr_t cbuf, user_size_t nbyte); }
str LR, [SP, #-16]! //Store registers
adr X1, msg
mov X0, #0 // 0 = StdIn
ldr X1, [x1] // address to store string
mov X2, #4 // length
mov X16, SYS_READ // MacOS read system call
svc 0 // Call system
ldr LR, [SP], #16 //Load registers
ret
msg: .ds 4 //memory buffer for keyboard input
helloworld1: .ascii "Hello World\n"
helloworld2: .ascii "Happy new year for 2022\n"
helloworld3: .ascii "Welcome to AARCH64 assembly on Mac Silicon\n"
首先你需要移动msg
到一个可写段:
.data
msg: .ds 4 //memory buffer for keyboard input
.text // keep everything else in __TEXT
然后,因为段可能会在 link 时间任意移动,Apple 的工具链将不再允许您使用 adr
来获取该缓冲区的地址 - 您将不得不使用adrp
和 add
:
adrp x1, msg@page
add x1, x1, msg@pageoff
如果需要,您可以告诉 link 人员请尽可能将其优化回 adr
:
Lloh0:
adrp x1, msg@page
Lloh1:
add x1, x1, msg@pageoff
.loh AdrpAdd Lloh0, Lloh1
然后你需要删除这一行:
ldr X1, [x1]
这将加载缓冲区的内容,它只是空字节。
最后,您应该将 x0
值更改为 exit
为常量:
mov x0, 0
此时 x2
中的值将被破坏,您也不需要它。