Smallest Value Array: 8086

Ahmet Göker
6 min readDec 15, 2023

--

Hey everyone, welcome back! Today, we’re cracking the code on a classic challenge: finding the smallest value in an array using Assembly 8086. Now, if you’re thinking, “Arrays and Assembly? Sounds like ancient riddles!”, don’t worry. We’ll break it down like a Lego set, step-by-step, so everyone can join the coding fun.

Arrays in 8086

We use arrays all the time in programming, but they’re usually just tools for building bigger things in high-level languages. In assembly, though, arrays are different. We have to work with them directly, which is like getting under the hood of the car and seeing how the engine and memory actually work together. So, let’s dive in and see how we can handle arrays in this low-level world!

1. Defining the Array:

  • Arrays are declared in the .data segment using the db or dw directives.
  • Each element occupies one byte (db) or two bytes (dw), depending on the data type.
  • An array name acts as a pointer to the first element’s memory address.

2. Accessing Array Elements:

  • To access a specific element, calculate its offset within the array.
  • The offset is the element index multiplied by the element size (1 for byte, 2 for word).
  • Use the add instruction to add the offset to the base address (array name) stored in a register.
  • The resulting address points to the desired element.
  • Use memory access instructions like mov or xchg to read or write data to/from the specified memory location.
numbers db 5, 10, 15, 20
mov ax, numbers ; Load base address of 'numbers' into AX
mov bx, 2 ; Element index (2 corresponds to third element)
add ax, bx ; Calculate offset (index * element size)
mov dl, [ax] ; Read data from third element (15) into DL

3. Looping through Arrays:

  • Use loop instructions like loop or jle to iterate through the array elements.
  • Within the loop, use the offset calculation as described above to access each element.
  • Update the loop counter and offset register at each iteration.

4. Manipulating Arrays:

  • Use memory access instructions like mov or xchg to write new values to array elements.
  • You can also perform calculations on array elements directly in registers after loading them from memory.

5. Important Pointers:

  • Be mindful of array bounds and avoid accessing elements outside the allocated memory space.
  • Use index variables and loop counters carefully to prevent errors.
  • Choose appropriate registers for calculations and data manipulation based on size and performance considerations.

The Data Stage:

  • list3: A modest treasure chest containing five precious numbers, 1 to 5, hidden within its bytes.

Setting the Scene:

Before embarking on our quest, we need to prepare the stage. The mov ax, @data and mov ds, ax commands are our incantations, summoning the .data segment to reside in the ds register, granting us access to our data treasures.

The Looping:

Now, we move on to list3 and its secret code. To start, we set up SI with the location of the first byte in list3, like using a key to open the box. Then, we create a counter called CX and set it to 6, so we can check all five hidden numbers in the list.

  • mov dl, [si]: Loads the byte at the address pointed to by SI (the array index) into DL.
  • add dl, 48: Converts the internal byte value to its ASCII representation by adding 48.
  • mov ah, 02h; int 21h: Invokes the "write character" function (interrupt 21h, function 2) with the ASCII character in DL, printing it to the screen.
  • mov dl, 32; int 21h: Prints a space character to separate the printed numbers.
  • inc si: Increments SI by 1 to move to the next element in the array.
  • loop loopx: Jumps back to the loop instruction (loopex) if the loop counter (CX) is not zero, continuing the iteration.

The reason we use add dl, 48 :

The output:

If you want the output to be A, B, C, D, and E, be aware that using add dl, 48 won't work. This is because the ASCII code for A is 65, so adding 48 would result in a different character.

Thus, we are going to delete add dl, 48 :

Smallest value: 8086

In this section, we’ll delve into the code for finding the smallest value in an array. We’ll begin by outlining the algorithm step-by-step, followed by its implementation in code. To fully grasp this section, understanding the previous material is crucial. So, without further ado, let’s dive in!

The Algorithm

Initialize:

  • Set BX to hold the current smallest value (initially set to the first element in the array using mov bl, [si]).
  • Set CX as the loop counter to track the remaining elements (initially set to the array size).

1. Loop through the array:

  • While CX is not zero:
  • Compare the current element at [si] with the current smallest value (bl):
  • If the current element is smaller or equal (cmp [si], bl; jle update):
  • Update the current smallest value to the current element (mov bl, [si]).
  • Otherwise, the current element is not smaller, so move on to the next element (jmp resume).
  • Increment the loop counter and array pointer:
  • inc si moves si to the next element in the array.
  • dec cx reduces the remaining elements to check.
  • loop loopx jumps back to the beginning of the loop.

2. End loop and output:

  • Once the loop exits (CX reaches zero), bl holds the smallest value in the array.
  • Convert the smallest value from its internal representation to ASCII (add bl, 48) and store it in dl.
  • Print the message “Smallest value from array: “ followed by the smallest value (mov ah, 02h; int 21h).

3. Exit:

  • hlt terminates the program.

As you can, it is quite simple.

Here is the code with the output:

Summary:

Today, I wrote this blog for those fascinated by writing such Assembly exercises. I hope this post has helped you understand how registers work. Please remember, you can always ask me if you have any questions. More blogs and exercises will be coming soon, as we share our passion for low-level programming, including reverse engineering and exploitation. If you enjoyed this content, please don’t forget to share and like my blog!

You can follow me on:

Twitter: https://twitter.com/lockpin010_

LinkedIn: https://www.linkedin.com/in/ahmetgoker/

GitHub: https://github.com/0xCD4

Ahmet | Security Researcher | Sociologist

--

--

Ahmet Göker
Ahmet Göker

Written by Ahmet Göker

Full stack Reverser | Linux-Kernel | Windows API

No responses yet