Following the HelloSilicon tutorial on ARM assembly for Apple Silicon I decided to play around with the general purpose registers and with the program counter.
When feeding the source to the linker with any of the registrers ("R1", "R2"... ) or "PC" ("R15") I got the following linker error:
% ld -o cicle cicle.o -lSystem -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _start -arch arm64
Undefined symbols for architecture arm64:
"PC", referenced from:
_start in cicle.o
ld: symbol(s) not found for architecture arm64
The source is:
.global _start // Provide program starting address to linker
.align 2 // Make sure everything is aligned properly
// Setup the parameters to print hello world
// and then call the Kernel to do it.
_start:
label:
mov X0, #1 // 1 = StdOut
adr X1, helloworld // string to print
mov X2, #13 // length of our string
mov X16, #4 // Unix write system call
svc #0x80 // Call kernel to output the string
b PC //Expecting endless loop
//b PC-6 //Expecting endless "Hello World" loop
// Setup the parameters to exit the program
// and then call the kernel to do it.
mov X0, #0 // Use 0 return code
mov X16, #1 // System call number 1 terminates this program
svc #0x80 // Call kernel to terminate the program
helloworld: .ascii "Hello World!\n"
I understand that this problem can be solved when coding on XCode 12+ changing the Bundle to Mach-O on the build settings, however, appending the bundle argument -b
sends a ld: warning: option -b is obsolete and being ignored
warning.
When feeding the source to the linker with any of the registrers ("R1", "R2"... ) or "PC" ("R15") I got the following linker error:
These registers don't exist, you're reading the manual for the wrong architecture. You need ARMv8, not ARMv7.
As for this:
b PC //Expecting endless loop
//b PC-6 //Expecting endless "Hello World" loop
PC
is not a thing. It's just an identifier like any other, such as _start
. If you want to refer to the current instruction, use a dot (.
):
b . // infinite loop
b .+8 // skip the next instruction
Note that any arithmetic is unscaled. If you want to jump 6 instructions back, you'll have to do b .-(4*6)
. If you attempted to compile b .-6
, you'd get an error because b
is only able to encode offsets aligned to 4 bytes.