Reputation: 15115
I'm trying to translate this x86_64
program:
# hello_world.s
# GNU Assembly, x86_64 Linux
.global _start
.data
.equ SYS_EXIT, 60
.equ SYS_WRITE, 1
.equ STDOUT, 1
.equ SUCCESS, 0
MSG:
.ascii "Hello world!\n"
.equ MSG_LEN, . - MSG
.text
_start:
# write(STDOUT, MSG, MSG_LEN)
mov $SYS_WRITE, %rax
mov $STDOUT, %rdi
mov $MSG, %rsi
mov $MSG_LEN, %rdx
syscall
# exit(SUCCESS)
mov $SYS_EXIT, %rax
mov $SUCCESS, %rdi
syscall
Into an aarch64
program:
// hello_world.s
// GNU Assembly, aarch64 Linux
.data
.equ SYS_EXIT, 93
.equ SYS_WRITE, 64
.equ STDOUT, 1
.equ SUCCESS, 0
MSG:
.ascii "Hello world!\n"
.equ MSG_LEN, . - MSG
.text
.global _start
_start:
// write(STDOUT, MSG, MSG_LEN)
mov x8, #SYS_WRITE
mov x0, #STDOUT
adr x1, MSG
mov x2, #MSG_LEN
svc #0
// exit(SUCCESS)
mov x8, #SYS_EXIT
mov x0, #SUCCESS
svc #0
However when I try to assemble the above program I get this error:
hello_world.s:27:13: error: expected compatible register or logical immediate
mov x2, #MSG_LEN
^
Which I think is somewhat of a red herring because if I change this line:
.equ MSG_LEN, . - MSG
Into this:
.equ MSG_LEN, 13
Then it works fine. However I'm not happy with this solution because I don't want to hardcode the MSG_LEN
, I want the assembler to be able to determine the length at assemble time like in the x86_64
version. Can you help me figure out how I can set MSG_LEN
in the aarch64
version of the program without having to explicitly hardcode a value?
Additional details: I'm compiling and running these programs inside of a docker container which is built from this Dockerfile:
FROM ubuntu:20.04
RUN apt-get update
RUN apt-get -y install clang qemu qemu-system gcc-aarch64-linux-gnu
I'm compiling and running the x86_64
program with:
clang -nostdlib -target x86_64-linux-gnu -s hello_world.s -o hello_world.out && ./hello_world.out
And I'm compiling and running the aarch64
program with:
clang -nostdlib -target aarch64-linux-gnu -s hello_world.s -o hello_world.out && ./hello_world.out
Upvotes: 3
Views: 1753
Reputation: 15115
Solution: I needed to use -fno-integrated-as
with clang
to tell it to use GNU Assembler directly instead of its own built-in integrated assembler (which is suppose to be a drop-in replacement for GAS but apparently it's not). I used the following updated command to compile and run my aarch64
program without issue:
clang -nostdlib -fno-integrated-as -target aarch64-linux-gnu -s hello_world.s -o hello_world.out && ./hello_world.out
Thanks to @Jester and @Nate Eldredge who helped me debug in the comments.
Upvotes: 3