Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Indexing array elements in Assembly

I'm having some trouble with arrays in NASM. I am trying to implement this pseudo code but am obtaining incorrect results.

For instance, when I send in 'abcdefgh' as byte_arr I should get 8 7 6 5 4 3 2 1. However, I actually receive: 5 4 3 2 1 1 1 1. Here's the code:

maxLyn(Z[0 . . n − 1], n, k) : returns integer 

if k = n − 1 

   return 1

p ← 1 

for i ← k+1 to n − 1 
{

    if Z[i−p] = Z[i] 

        if Z[i−p] > Z[i] 

            return p 
        else 

            p ← i+1−k 
}

return p.      

Rather than returning p, I wish to store it as a global variable which I can access in my other subroutines. Here is my attempt at coding it:

enter 0, 0           ; creates stack
pusha                ; pushes current register values onto stack

mov eax, [ebp+16]    ; kth index
mov ebx, [ebp+12]    ; length   
mov edi, [ebp+8]     ; byte_arr

mov [len], ebx      ; len = length    
sub [len], dword 1  ; len = len - 1   
mov ebx, [len]      ; ebx contains len - 1   

mov [k], eax        ; k = epb+16   
mov [p], dword 1    ; p = 1   
mov [i], eax        ; i = k   
inc dword [i]       ; i = k+1    
mov ecx, [i]        ; ecx = i  

cmp [k], ebx        ; checks if kth index is last element
  je ENDFOR

  FOR: cmp dword [i], ebx  ; goes from ith index to len     
    ja ENDFOR
    mov esi, [edi + ecx*1] ; esi = array[i]  
    mov [i_temp], esi      ; store array[i] in variable     
    sub ecx, [p]           ; ecx = i-p
    mov edx, [edi + ecx*1] ; edx = array [i-p]

    cmp edx, [i_temp]      
   je REPEAT               ; array[i-p] = array[i]
   ja ENDFOR               ; array[i-p] > array[i]     
   mov eax, dword [i]      
   mov [p], eax            ;p = i
   inc dword [p]           ;p = i + 1       
   mov eax, dword [p]     
   sub eax, [k]            ;eax = p - k     
   mov [p], eax            ;p = i+1-k  

   REPEAT:     
     inc dword [i]         ; i = i + 1
     mov ecx, [i]          ; ecx = i + 1
     jmp FOR   

   ENDFOR:  
     popa                  ; saves register values and pops them off
     leave                 ; cleans up
     ret                   ; returns to caller
like image 948
C. Bagnall Avatar asked Jun 24 '26 18:06

C. Bagnall


1 Answers

mov esi, [edi + ecx*1] ; esi = array[i]  
mov [i_temp], esi      ; store array[i] in variable     
sub ecx, [p]           ; ecx = i-p
mov edx, [edi + ecx*1] ; edx = array [i-p]

cmp edx, [i_temp]      
je REPEAT               ; array[i-p] = array[i]
ja ENDFOR               ; array[i-p] > array[i]     

In these lines you read your array elements as dwords but you actually are using an array of bytes!
That's why the comparing fails. Change this cmp into:

cmp dl, byte ptr [i_temp]

Alternatively rework your code to use byte sized variables/registers where appropriate.

like image 106
Fifoernik Avatar answered Jun 27 '26 20:06

Fifoernik



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!