[Example] Compiling, Hello World and printf() in Assembly
Compiling and Running
Compiling your .s assembly code/files is the exact same as what you did with .c C code/files, using gcc:
gcc helloworld.s -o helloworld
./helloworld
If you used m4 macros, like the optimized loop example in my other post, you have one extra step:
m4 optimizedwhileloop.m4 > optimizedwhileloop.s
gcc optimizedwhileloop.s -o optimizedwhileloop
./optimizedwhileloop
Hello World in Assembly
// Hello World in Assembly
// Define string for call to printf()
hello: .string "Hello, world!\n"
// Define the main function of our program
.balign 4 // Instructions must be word aligned
.global main // Make "main" visible to the OS
main: stp x29, x30, [sp, -16]! // Save FP and LR to stack, allocating 16 bytes, pre-increment SP
mov x29, sp // Update FP to current SP
adrp x0, hello // set 1st argument to pass to printf(format, var1, var2...) (high-order bits)
add x0, x0, :lo12:hello // set 1st argument to pass to printf(format, var1, var2...) (lower 12 bits)
bl printf // Call the printf() function
// Set up return value of zero from from main()
mov w0, 0
ldp x29, x30, [sp], 16 // Restore FP and LR from stack, post-increment SP
ret // Return to caller
The highligted part is the template you will follow for writing your own programs, including the assignments. This template is used in all the examples I've provided.
Another printf() example
// Simple program to show how to use printf from Assembly.
// Define format string for call to printf()
fmt: .string "char: %c \nint: %d\n"
// Define the main function for our program
.balign 4 // Instructions must be word aligned
.global main // Make "main" visible to the OS
main: stp x29, x30, [sp, -16]! // Save frame pointer (FP, x29) and link register (LR, x30) to stack, allocating 16 bytes, pre-increment SP
mov x29, sp // Update frame pointer (FP) to current stack pointer (SP) (after we've incremented SP in the last step)
mov w19, 65 // Move 65 to 32-bit general purpose register
// Note: 65 is just a number, until the %c in the printf() format converts it to a character
mov w20, 42 // Move 42 to 32-bit general purpose register
// Print the letter A and the number 42
adrp x0, fmt // set 1st argument to be passed to printf(format, var1, var2...) (higher-order bits)
add x0, x0, :lo12:fmt // set 1st argument to be passed to printf(format, var1, var2...) (lower 12 bits)
mov w1, w19 // pass in the 2nd argument from 32-bit register w19
mov w2, w20 // pass in the 3rd argument from 32-bit register w29
bl printf // use bl (branch to label) to call function printf()
// Return 0 in main, like we did in C
mov w0, 0
// Restore registers and return to calling code (OS)
ldp x29, x30, [sp], 16 // Restore FP and LR from stack, post-increment SP
ret // Return to caller