尝试从用户输入中捕获两个字符和新行。
这个程序把3个helloworld打印到屏幕上,然后用户可以输入一些字符。一切看起来都正常,但是它不打印输入
我怀疑这是由于我在_read函数中操作X1寄存器的方式,或者是分配缓冲区的方式
运行代码时不报告任何错误。
代码是使用以下命令编译的。它应该在MacM1上运行
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"
2条答案
按热度按时间4xy9mtcn1#
首先,您需要将
msg
移动到一个可写段:然后,由于段可以在链接时任意移动,苹果的工具链将不再允许您使用
adr
来获取该缓冲区的地址-您将不得不使用adrp
和add
:如果需要,可以告诉链接器尽可能将其优化回
adr
:那么你需要删除这一行:
这将加载缓冲区的内容,这些内容将只是空字节。
最后,您应该将
x0
值更改为exit
,并将其更改为常量:此时
x2
中的值将被删除,您也不需要它。2ic8powd2#
作为一个参考,任何人在未来寻找一个例子,从标准在苹果硅(M1)阅读,这段代码(基于上述信息)的工作。它接受一个字符串多达20个字符,并打印出来的标准输出。
您的makefile应该如下所示: