ASM 310: ARM64 Assembly (30 pts extra)

What You Need

Purpose

To practice writing simple 64-bit ARM assembly code.

Checking the Processor

On your Linux system, execute this command:
uname -a
You should see the aarch64 architecture, as shown below.

If you do not, stop this project and prepare an ARM64 system to use.

Prerequisites

To install the software we need, on your Linux system, execute these commands:
sudo apt update
sudo apt install binutils gdb -y

Hello World

On your Linux system, execute this command:
nano hello.s
Enter this code:
.global _start
.text
_start:
    mov     x0, 1            // File descriptor for stdout (1)
    ldr     x1, =message     // Address of the message string
    ldr     x2, =message_len // Length of the message string
    mov     x8, 64           // System call number for write
    svc     0                // Invoke system call

    mov     x0, 0            // Exit code (0 for success)
    mov     x8, 93           // System call number for exit
    svc     0                // Invoke system call

.data
message: .ascii "Hello, ARM64 World!\n"
message_len = . - message

Save the file with Ctrl+x, y, Enter.

Execute these commands to compile, link, and run the program:

as -g -o hello.o hello.s
ld -o hello hello.o
./hello    
The program runs, as shown below.

Caesar Cipher

This program reads input, shifts letters in the alphabet using a loop, and outputs the encrypted text.

On your Linux system, execute this command:

nano caesar.s
Enter this code:
.global _start
.text
_start:
    mov     x0, 0            // File descriptor for stdin (0)
    ldr     x1, =message     // Address of the message string
    ldr     x2, =message_len // Length of the message string
    mov     x8, 63           // System call number for read
    svc     0                // Invoke system call

    ldr     x10, =message        // Address of the message string
    mov     x11, 0               // index of current character
    ldr     x13, =message_len    // total length of string including \n
    sub     x13, x13, 1          // number of characters to encrypt
loop:                            // top of loop
    ldrb    w12, [x10, x11]      // load current byte
    add     x12, x12, #3         // move character forward in alphabet
    strb    w12, [x10, x11]      // store current byte
    add     x11, x11, 1          // increment character index
    cmp     x11, x13             // are we done?
    b.lt    loop

    mov     x0, 1            // File descriptor for stdout (1)
    ldr     x1, =message     // Address of the message string
    ldr     x2, =message_len // Length of the message string
    mov     x8, 64           // System call number for write
    svc     0                // Invoke system call

    mov     x0, 0            // Exit code (0 for success)
    mov     x8, 93           // System call number for exit
    svc     0                // Invoke system call

.data
message: .ascii "     \n"
message_len = . - message

Save the file with Ctrl+x, y, Enter.

Execute these commands to compile, link, and run the program:

as -g -o caesar.o caesar.s
ld -o caesar caesar.o
./caesar
HELLO
The program runs, as shown below.

ASM 320.1: Debugging the Caesar Program (5 pts)

The commands below peform these actions:
  • Load the "caesar" program into the debuggger
  • Display the first ten lines of source code
  • Place a breakpoint
  • Begin enecution
  • Read "HELLO" from stdin
  • Continue to the breakpoint
  • Display the value of register x0
Execute these commands:
gdb -q caesar
list
break 9
run
HELLO
print $x0
The flag is covered by a green rectangle in the image below.

ASM 320.2: Increasing Shift (10 pts)

Code an ARM64 assembly program that shifts characters this way:
  • Shift the first character forward by 1 character in the alphabet
  • Shift the second character forward by 2 characters in the alphabet
  • Shift the third character forward by 3 characters in the alphabet
  • And so on...
Use only capital letters from A to Z.

Wrap around, so shifting Z by one character produces A.

Test your program with the input word BOXES. The correct answer is shown below.

To get the flag, enter this plaintext input:

HLZNZULAEW
The resulting ciphertext is the flag.

ASM 320.3: One-Time Pad (15 pts)

Code an ARM64 assembly program that takes two input strings: a PLAINTEXT string and a KEY string.

To encrypt a string, process each character of the CIPHERTEXT based on the corresponding character of the KEY text this way:

  • If the KEY character is A, leave the PLAINTEXT character unchanged.
  • If the KEY character is B, shift the PLAINTEXT character forward by one letter in the alphabet
  • If the KEY character is C, shift the PLAINTEXT character forward by two letters
  • If the KEY character is D, shift the PLAINTEXT character forward by three letters
  • And so on...
Use only capital letters from A to Z.

Wrap around, so shifting Z by one character produces A.

Test your program as shown below.

Now make a program that reverses the process.

To get the flag, use these values and decrypt the message:

Ciphertext: VWVAMVGEVC
Key: ASECUREKEY
The resulting plaintext is the flag.

Sources

Introduction to ARM Assembly Basics
ARM Assembly By Example
A Gentle Introduction to Assembly Language Programming
ARMv8 AArch64/ARM64 Full Beginner's Assembly Tutorial
cc


Posted and video added 4-1-25