Hey there! I am back again with an upadate in my journey of learning Software portability and Optimisation. So, today we are going to dive deep in writing assembly in 2 architechtures and their names are x86_64 and aarch64.
Before we get started you might wanna take a look at Assembler Basics
Lets get started directly into todays lab.So I was given the access for the 2 architectures by my professor for this lab and following are the tasks and how I did them.
Task 1: Build and run the C version(s)
• Navigate to the spo600/examples/hello/c directory.
• Use the make command to build the C programs.
• Run the generated binaries to observe their behavior.
• Compare the source code in hello.c, hello2.c, and hello3.c to understand the differences
Below is how the same program of hello world hello.c, hello2.c and hello3.c written in c looks like in x86(left) and aarch64(right).
Well not much of a difference just colour changes right?. NO, WRONG in the first snapshot you can see that we are doing a system call for displaying the text "Hello World!" and also including the header required for that method, whereas in the second and the third snapshot we are not includeing any special headers just using the builtin methods write and printf respectively.
Now how do you biuld and compile these files, using the command make filname
in this case it was make hello
make hello2
make hello3
. These commads will build and compile the program and generate binary file which then can be run to execute the program.
You might ask what is make or makefile?
A Makefile is a special file used by the make utility to automate the process of compiling and building programs. It contains rules and instructions on how to compile and link the program's source files. This helps streamline the build process, especially for projects with multiple files and dependencies.
We will go deep into this topic in our next post, for now lets concentrate on the lab because it is kind of urgent 😭.
Task 2: Disassemble the C binaries
• Use objdump -d
command on the generated binaries to disassemble them into assembly code.
• Look for the section in the disassembled code and analyze it.
• Note the differences in the amount of code compared to the C source code.
Here are the results.
I have highlighted the main tag and see how different are the 2 archietecturs and their addressing modes. The way they store a byte is also very different.
1. Register Naming and Usage
aarch64:
- aarch64 has 31 general-purpose registers named x0 to x30.
- Register x0 to x7 are used for passing arguments and return values.
- There is a special zero register xzr which always reads as 0.
- Stack pointer is sp, and the link register (for return addresses) is lr or x30.
x86 (x86-64):
- x86-64 has 16 general-purpose registers named rax, rbx, rcx, rdx, rsi, rdi, rsp, rbp, and r8 to r15.
- Register rax, rdi, rsi, rdx, rcx, r8, and r9 are used for passing arguments and return values.
- The stack pointer is rsp, and the base pointer (used for stack frames) is rbp.
2. Instruction Set
aarch64:
- Uses a Reduced Instruction Set Computing (RISC) architecture.
- Instructions are generally fixed at 32 bits in length.
- Emphasizes load/store architecture where memory operations are separate from arithmetic operations.
x86:
- Uses a Complex Instruction Set Computing (CISC) architecture.
- Instructions vary in length from 1 to 15 bytes.
- More complex instructions that can perform multiple operations.
And the list goes on and on. I think this is a lot of content already I dont want it to be overwhelming for my readers as it was for me 🥲. So, see you in the next post till then try to make sense of the above content.
Happy Coding!!
Top comments (0)