Skip to content

Instantly share code, notes, and snippets.

@multitudes
Last active May 2, 2024 17:09
Show Gist options
  • Save multitudes/5b76d698cfd6894caffef5b55f2c6c15 to your computer and use it in GitHub Desktop.
Save multitudes/5b76d698cfd6894caffef5b55f2c6c15 to your computer and use it in GitHub Desktop.
helloworld.s
/*
minimul required to print hello world.
also can compile with
cc helloworld.s
and exec with ./a.out
or use the linking
as helloworld.s -o helloworld.o
ld helloworld.o -o helloworld -l System -syslibroot `xcrun -sdk macosx --show-sdk-path` -e _main -arch arm64
*/
.global _main
.align 2 // important for apple silicon it is always 2!!
_main:
mov x0, #1 // File descriptor (stdout)
adr x1, helloworld // Pointer to message
mov x2, #12 // Length of message
mov x16, #4 // write system call number
svc 0 // exec the system call
mov x0, #0 // Exit code
mov x16, #1 // System call number (sys_exit)
svc 0 // exec the system call and exit
helloworld: .ascii "hello world\n"
/*
this is the bare minimum code to print hello world in assembly language
even shorter using ret for return.
*/
.global _main
.align 2 // important for apple silicon it is always 2!!
_main:
// this is equivalent to write(1, "hello world\n", 12)
// write is a system call that writes to a file descriptor
// x0 x1 x2 are the parameters to the system call
mov x0, #1 // File descriptor (stdout)
adr x1, helloworld // Pointer to message
mov x2, #12 // Length of message
// also a supervisor call is needed to execute the system call
// need register x16 to hold the system call number
mov x16, #4 // write system call number
svc 0 // exec the system call
// the system jumps to the address stored in x30
// if my program doesnt have subroutine then I can
// use ret to return to the caller. otherwise I need to store
// the x30 I get when first entering the program and load it
// before caling ret
ret
helloworld: .ascii "hello world\n"
/*
adapted for mac M1
*/
.global _main // Expose 'main' to the linker.
.text // Specify what comes next is code.
.align 2 // Align the next instruction on a 4 byte boundary.
/* Perry Kivolowitz
Assembly Language Programming Made Not So Scary
if06.s - demonstrating an IF statement.
This program will compare 5 to 10. If 5 is larger
(it isn't), the program will print TRUE. If 10 is
larger than 5 (it is), the program will print
FALSE.
*/
_main:
str x30, [sp, -16]! // Preserve x30 due to function call.
mov x1, 10 // b gets 10
mov x0, 5 // a gets 5
cmp x0, x1 // a - b ... 5 - 10 makes negative 5.
ble 1f // If b >= a, thake the branch. ble -> branch less equal
adr x0, T // a is greather than b - load the
// address of TRUE string into x0
b 2f // Skip over prepping FALSE
1: adr x0, F // x0 contains a pointer to the
// correct string either way.
2: bl _puts // Print the string with a new line.
ldr x30, [sp], 16 // Restore x30 so we can return.
mov x0, xzr // Indicate success to the caller.
ret // Return back to the caller.
F: .asciz "FALSE" // Null terminated C string.
T: .asciz "TRUE" // Null terminated C string.
//.data // What comes next is data.
.end // Tells the assembler that it
// should emit an error if any
// more data or instructions
// come after.
/*
.asciz declares a string and automatically appends a null character (\0)
at the end of the string.
This is useful when working with C functions,
which expect strings to be null-terminated.
.ascii declares a string exactly as it is.
It does not append a null character at the end of the string.
*/
@multitudes
Copy link
Author

for Mac I need to add the
adr x0, F instead of ldr x0, =T as in Linux

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment