Welcome back everybody!! In the last post we saw some basic hello world programs in x86_64 and aarch64 archietectures, what is the difference between the 2 and how they work. The programs we analysed were written in c. But in todays post we are going to analyse them in assembly language in both the archietectures. And may be re-evaluate our descision of assembly being difficult and boring, may be ⚠️.
So lets get started with the tasks.
Step 3: Review, build, and run the x86_64 assembly language programs
• Navigate to the spo600/examples/hello/assembler/x86_64 directory.
• Use make to build the assembly language programs.
• Use objdump -d on the generated object files to inspect the assembly code.
• Compare the assembly code with the C source code and note the differences.
So first we need to navigate to the address where all the programs are present we can do this with simple cd commad cd spo600/examples/hello/assembler/x86_64
as we have already extracted the tar archieve using tar xvf /public/spo600-assembler-lab-examples.tgz
If you do a ls
you will see the follwoing files
- hello-gas.s
- hello-nasm.s
- Makefile
Now lets check the contents of our hello-gas.s file, which looks like this
This program is written in the gnu assembler syntax so the name hello-gas
Next is the hello-nasm.s
You can see the difference in the syntax of the two files as this one uses the Netwide Assembler, which is a popular assembler for the x86 architecture. We will be working with hello-gas for today. So, lets compile it with the commad make hello-gas
.
It won't compile in aarch64 archietecture because duh!! this for x86 only.
This will generate a binary file called hello-gas and when we execute the binary with the commad ./hello-gas
we will see the following results.
Now lets take a look at the object dump of this program. You can use te command objdump -d hello-gas
which will look something like this.
This displays the disassembly of the .text section. The .text section contains the actual executable instructions of the program. When the program is run, the CPU reads and executes the instructions from this section.
Step 4: Build and run the aarch64 assembly language program
• Navigate to the spo600/examples/hello/assembler/aarch64 directory.
• Use make to build the assembly language program.
• Use objdump -d on the generated object file to inspect the assembly code.
• Compare the assembly code with the C source code and note the differences.
Lets perfom the same actions for aarch64 program.
When you do a ls
after navigating to the directory address you will see the following files.
- hello.s
- Makefile
Hello.s contains our program and Makefile is the file that compiles and builds our project as we discussed in my last post
Lets see what is there in hello.s
Notice the aarch64 program fails to compile in the x86 system. Quite colorful is aarch64 right! I like it.
Now lets build it with make hello
which gives us the following outcome.
The object dump and execution looks something like this.
Note that in both the systems apart from the binary file there is one more file being generated called hello.o in aarch64 and hello-gas.o in x86. What are these files now?
Object files, commonly with the .o extension, are intermediate files produced by the assembler or compiler from source code. They contain machine code that is not yet linked into a complete executable program. The .o
files represent the machine code translation of individual source files. They are not directly executable but contain the compiled code that will later be linked together to form an executable.
Do not get angry when I tell you that these were just the basics for getting us familiar with running and compiling the programs. The real task is to write a program that prints the word "Loop" or any other word with the index count of the loop. The loop should run 30 times.
Calm down and don't worry we have a hint!!😅
Here is a basic loop in AArch64 assembler - this loops from 0 to 9, using r19 as the index (loop control) counter:
.text
.globl _start
min = 0 /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
max = 10 /* loop exits when the index hits this number (loop condition is i<max) */
_start:
mov x19, min
loop:
/* ... body of the loop ... do something useful here ... */
add x19, x19, 1
cmp x19, max
b.ne loop
mov x0, 0 /* status -> 0 */
mov x8, 93 /* exit is syscall #93 */
svc 0 /* invoke syscall */
This code doesn't actually do anything while looping, because the body of the loop is empty. But we can use this code and combine it the hello world program so that it prints a word each time it loops.
I already did the hardwork for you and it did take sometime.
Code Reveal 🤫
.text
.globl _start
min = 0 /* starting value for the loop index; **note that this is a symbol (constant)**, not a variable */
max = 30 /* loop exits when the index hits this number (loop condition is i<max) */
_start:
mov x19, min
loop:
add x15, x19, 0x30
adr x14, msg+6
mov x12, 10
udiv x13, x19, x12
add x16, x13, 0x30
cmp x16, 0x30
b.eq ones
strb w16, [x14]
ones:
adr x14, msg+7
msub x13, x13, x12, x19
add x13, x13, 0x30
strb w13, [x14]
mov X0, 1
adr x1, msg
mov x2, len
mov x8, 64
svc 0
add x19, x19, 1
cmp x19, max
b.ne loop
mov x0, 0
mov x8, 93
svc 0
.data
msg: .ascii "Loop: #\n"
len= . - msg
I know , I know that you guys need a walkthrough and I won't keep you guys waiting.
So, see you guys in the next post.
Untill then Happy Coding!!!!😉
Top comments (0)