printf in assembly NASM x86 print only once of the array in the loop

3 min read 21-09-2024
printf in assembly NASM x86 print only once of the array in the loop


Printing elements from an array in assembly language using NASM (Netwide Assembler) can be quite a challenging task, especially for beginners. However, once you grasp the basic concepts of assembly language and how to manage loops and conditional statements, it becomes more straightforward. In this article, we will clarify a common scenario: printing only one instance of an array element within a loop, using the printf function.

The Original Code Problem

Here’s a typical example of a problem statement where someone might want to print array elements but only print each unique element once within a loop:

section .data
    msg db "%d", 10, 0
    array db 1, 2, 3, 2, 1, 4 ; sample array
    arraySize db 6 ; size of the array

section .text
    global _start

_start:
    ; Your code for printing goes here

Problem Analysis

In this code snippet, the objective is to iterate through an array and print each element only once. The current logic of looping through the array as is would result in printing duplicates. Our task is to implement logic that checks for duplicates before printing.

Revised Code

Here’s a revised version of the original code that will ensure that each element is printed only once:

section .data
    msg db "%d", 10, 0        ; Format for printf
    array db 1, 2, 3, 2, 1, 4 ; Sample array
    arraySize db 6            ; Size of the array

section .bss
    printed resb 6            ; Array to track printed elements

section .text
    extern printf             ; Declaration of printf
    global _start

_start:
    mov ecx, 0                ; Initialize outer index
.outer_loop:
    cmp ecx, [arraySize]      ; Compare with array size
    jge .done                  ; If ecx >= arraySize, we're done

    movzx eax, byte [array + ecx] ; Load current element
    mov edi, 0                ; Initialize inner index to check duplicates
    mov ebx, 0                ; Reset duplicate flag

.inner_loop:
    cmp edi, ecx              ; Compare inner index with outer index
    jge .print                ; If inner index is greater than or equal, print

    movzx edx, byte [array + edi] ; Load current inner element
    cmp eax, edx              ; Compare elements
    je .duplicate_found        ; If they are equal, it's a duplicate

    inc edi                   ; Increment inner index
    jmp .inner_loop           ; Continue checking for duplicates

.duplicate_found:
    mov ebx, 1                ; Set duplicate flag

.print:
    cmp ebx, 0                ; Check if we found a duplicate
    je .print_element         ; If not a duplicate, print it

    jmp .skip_print           ; If it was a duplicate, skip printing

.print_element:
    push eax                  ; Save current element
    push msg                  ; Push format string
    call printf               ; Call printf to print
    add esp, 8                ; Clean up the stack

.skip_print:
    inc ecx                   ; Increment outer index
    jmp .outer_loop           ; Loop back

.done:
    ; Exit code
    mov eax, 1                ; sys_exit
    xor ebx, ebx              ; Exit code 0
    int 0x80

Explanation of the Code

  1. Data Sections: We declare the message format and the sample array containing numbers. The BSS section reserves space for tracking printed elements.

  2. Outer Loop: The code uses an outer loop (.outer_loop) to iterate over each element of the array.

  3. Inner Loop: An inner loop (.inner_loop) checks for previously printed elements by comparing the current element with all previous elements.

  4. Duplicate Check: If a duplicate is found, it sets a flag (ebx), which prevents the element from being printed again.

  5. Print Element: If the element is unique (not found in the duplicate check), it pushes the required arguments onto the stack and calls printf to print the value.

  6. End Execution: After iterating through the entire array, the program exits gracefully.

Practical Examples

This approach can be applied in various scenarios where you want to handle unique elements, such as filtering input from users or processing sensor data that might have repeating values.

Conclusion

Understanding how to print unique elements from an array in NASM assembly language is a valuable skill. It teaches you about loop constructs, conditional checks, and interfacing with external libraries such as the C standard library's printf.

For more detailed resources, consider the following:

  • "Programming from the Ground Up" by Jonathan Bartlett: An excellent introduction to assembly language programming.
  • The official NASM documentation: NASM Documentation for more examples and syntax.

By mastering these principles, you can write more efficient assembly code that optimally handles data structures like arrays. Happy coding!