Recursion in assembly?

I'm trying to better understand the assembly, and I'm a bit confused about how to call functions recursively when I have to deal with registers, popping / pushing, etc.

I embed the x86 assembly in C ++. Here I am trying to make a method that defines an array of integers that will build a linked list containing these integers in the order they appear in the array.

I do this by calling a recursive function:

insertElem (struct elem *head, struct elem *newElem, int data) 

-head: list header

-data: the number to be inserted at the end of the list

-newElem: indicates the place in memory where I will store the new element (data field)

My problem is that I rewrite registers instead of a typical linked list. For example, if I pass the array {2,3,1,8,3,9} to it, my linked list will return the first element (head) and only the last element, since the elements will overwrite each other after the head is no more than null.

So my linked list looks something like this: 2 → 9 instead of 2 → 3 → 1 → 8 → 3 → 9

It seems to me that I do not understand how to organize and process registers. newElem is in EBX and just keeps on texting. Thanks in advance!

+3
source share
3 answers

It's hard to give an answer without seeing your asm code. My first thought is that there is no need for recursive functions when working with linked lists.

, - :

;
; ebx = current element
;
TraverseList:

   ; If this is the end of the list we can skip the recursive invocation
   cmp [ebx+next], 0
   je NoNextElement

   push ebx               ; Save current element (ebx) on stack
     mov ebx, [ebx+next]  ; Put next element in ebx
     call TraverseList    ; Recursive invocation
   pop ebx                ; Restore current element (ebx) from stack

NoNextElement:

   ; Do stuff with the current element (ebx)
   ...
   ret
+7

, "": gcc -S. -, , C .

. , .

+2

Try something like this as asm code

__asm{
        mov ebx, dword ptr[esp+4] //head
        mov ecx, dword ptr[esp+8] //newElem
        mov edx, dword ptr[esp+12] // data

    cmp [ebx+4], 0
    je NO_NEXT_ELEMENT

    mov ebx, [ebx+4]
    mov ecx, [ecx+4]

    push edx
    push ecx
    push ebx
    call insertElem
    pop ebx
    pop ecx
    pop edx


NO_NEXT_ELEMENT:


    mov dword ptr[ebx+4], ecx 
    mov dword ptr[ecx], edx
    mov [ecx+4], 0

    ret
}

EDIT: Just ran this and realized that this is not working. It gives read / write errors of the access violation site. But I hope this gives you a start, maybe someone can clean it up a bit.

0
source

Source: https://habr.com/ru/post/1748649/


All Articles