HomeAboutArticles

ARM64 — Making a library

Start page1 page2 page3 page4 page5 page6 page7 page8 page9 page10

The idea on this page is to make a library of useful subroutines, and in that way make the main program more readable. So we need two assembler files now.

hello3.s

        .text
        .global _start
        .extern _phex
        .extern _exit
_start:

        mov x0,0x9876
        bl _phex

        bl _exit

lib3.s

        .text
        .global _phex
        .global _exit

_phex:  movz x3,16
        adr x2,message

again:  ror x0,x0,60
        and x1,x0,0xF
        cmp x1,10
        bge isAtoF
        add x1,x1,48
        b  done
isAtoF: add x1,x1,55
done:   strb w1,[x2]
        add x2,x2,1

        subs x3,x3,1
        bne again

        mov x0,1
        adr x1,message
        mov x2,17
        mov x8,0x40
        svc 0
        ret

_exit:  mov x0,0
        mov x8, 93
        svc 0


        .data
message: .ascii "****************\n"

Assemble, link and run

user@rpi4:~/work $ as hello3.s -o hello3.o
user@rpi4:~/work $ as lib3.s -o lib3.o
user@rpi4:~/work $ ld hello3.o lib3.o  -o hello3
user@rpi4:~/work $ ./hello3
0000000000009876

So what happens

In lib3.s we declare two labels to be global, so they can be seen by the linker, and used in other programs.

I like to name these global names starting with an underscore. It will be easier to see what's wrong when there are errors.

In hello3.s the global names used are listed as .extern, and we just branch to them as we did before. The hello3.s-program is quite readable now.

Actually in this assembler there is no need to declare the external names. Any unknown label is automatically external. Even if you do declare them .extern, they are still mentioned in the listing as UNDEFINED SYMBOLS. This can be different on another system.

And now we don't need to assemble all files — only those that have changed.

The stack pointer

Now try this:

        mov x0,sp
        bl _phex

It might print 0000007FD00802A0, which is where the system has allocated a stack. sp is just another name for register x29.

The value is not the same every time you run the program. The stack is actually supposed to be used in subroutines, for local variables and for the return address.

We are ready to see how subroutines really should be made.

Start page1 page2 page3 page4 page5 page6 page7 page8 page9 page10

2025-06-16