Lab-3

 

Exploring Assembly Language on x86_64 and AArch64

Introduction

In this lab, we dive into the intricacies of assembler on both x86_64 and AArch64 architectures. We'll explore code examples, disassemble object files, and write simple assembly programs to understand the core differences and functionalities between these architectures.

Setting Up

First, we unpacked the provided code examples:



cd ~ tar xvf /public/spo600-assembler-lab-examples.tgz

This created a directory structure under ~/spo600/examples/, containing various examples in C and assembly for both architectures.

Building and Running C Programs

We started with the C programs to establish a baseline:

  1. Building the C programs:

    cd ~/spo600/examples/c make
  2. Running the C programs:

    ./hello ./hello2 ./hello3
  3. Observing the differences:
    • hello.c uses printf().
    • hello2.c uses write().
    • hello3.c uses syscall() directly.

Disassembling C Binaries

Using objdump, we disassembled the binaries to view their assembly code:


objdump -d hello > hello_disassembly.txt objdump -d hello2 > hello2_disassembly.txt objdump -d hello3 > hello3_disassembly.txt

Examining the <main> sections revealed differences in how each function call is translated into machine code. The C binaries included additional setup and teardown code, which was absent in pure assembly programs.

x86_64 Assembly Programs

Next, we turned to the x86_64 assembly programs:

  1. Building the assembly programs:

    cd ~/spo600/examples/hello/assembler/x86_64 make
  2. Disassembling and comparing:

    objdump -d hello-gas > hello_gas_disassembly.txt objdump -d hello-nasm > hello_nasm_disassembly.txt

The assembly code generated was leaner compared to the C binaries, as it didn't include the extra overhead required for C runtime support.

AArch64 Assembly Programs

We followed similar steps for the AArch64 assembly programs:

  1. Building the assembly programs:

    cd ~/spo600/examples/hello/assembler/aarch64 make
  2. Disassembling and verifying:

    objdump -d hello > hello_aarch64_disassembly.txt

Writing Assembly Programs

AArch64 Loop Example

We modified the provided loop example to print a message along with the loop index:


.text .globl _start min = 0 max = 10 _start: mov x19, min loop: // Print "Loop: " mov x0, 1 ldr x1, =msg mov x2, 6 mov x8, 64 svc 0 // Convert index to character and print add x21, x19, 0x30 mov x0, 1 mov x1, x21 mov x2, 1 mov x8, 64 svc 0 // Print newline ldr x1, =newline mov x2, 1 mov x8, 64 svc 0 // Increment and loop add x19, x19, 1 cmp x19, max b.ne loop // Exit mov x0, 0 mov x8, 93 svc 0 .data msg: .ascii "Loop: " newline: .ascii "\n"

Loop from 00 to 30

We extended the loop to print two-digit numbers:


.text .globl _start min = 0 max = 31 _start: mov x19, min loop: // Print "Loop: " mov x0, 1 ldr x1, =msg mov x2, 6 mov x8, 64 svc 0 // Convert tens place udiv x20, x19, 10 add x20, x20, 0x30 mov x0, 1 mov x1, x20 mov x2, 1 mov x8, 64 svc 0 // Convert units place msub x21, x19, x20, 10 add x21, x21, 0x30 mov x0, 1 mov x1, x21 mov x2, 1 mov x8, 64 svc 0 // Print newline ldr x1, =newline mov x2, 1 mov x8, 64 svc 0 // Increment and loop add x19, x19, 1 cmp x19, max b.ne loop // Exit mov x0, 0 mov x8, 93 svc 0 .data msg: .ascii "Loop: " newline: .ascii "\n"

Experience and Reflection

Writing and debugging in assembly language is an enlightening experience. It offers a granular level of control over the hardware, allowing us to see how high-level constructs translate into machine operations. However, it also demands meticulous attention to detail and a deep understanding of the hardware architecture.

Comparison: 6502, x86_64, and AArch64

  • 6502 Assembly:
    • Simpler and more constrained environment.
    • Ideal for understanding the fundamentals of assembly language.
  • x86_64 Assembly:
    • More complex and powerful.
    • Provides extensive instruction sets, but can be overwhelming due to its CISC nature.
  • AArch64 Assembly:
    • Balances between simplicity and power.
    • RISC architecture makes it more intuitive after grasping the basics.

Overall, this lab provided invaluable insights into different assembly languages and architectures. The experience underscored the importance of understanding lower-level programming to appreciate the efficiency and performance of high-level applications.

Comments

Popular posts from this blog

Exploring Retro Arcade Days - Simple Yet Challenging Breakout

Exploring Assembly Language (Lab-1)