Still on my way to learn recursion in NASM Assembly, 32-bit Ubuntu, I am now trying to add all the elements in an array recursively. The array's elements are all 4-bytes each.
I came up with a solution that seems to work.
Basically, to add the elements in an array, I somehow need to count them, right? So I have ESI
as my counter. However, this register needs to be set to 0
at the beginning of the function - but I don't think there is any way I can tell whether the current function call is the first one, or the second or third... So to fix this, I have two functions: the initial call , and the recursive call . The first one sets ESI
to 0
and then calls the recursive call. The elements are all added to EAX
, which is also set to 0
in the initial call..
But I'm concerned with it because it is somewhat different from two recursive functions I've done before:
Because, first of all, I'm using two functions, one for the start, and another for the actual recursive part. Also, I am using a counter, which feels awfully a lot like an iterative solution.
So my questions are: is there a solution that resembles better the two recursive functions I posted above? Can my current solution be considered recursive?
; --------------------------------------------------------------------------
; Recursive function that adds all the elements in an array into EAX.
; The array's elements are 4-bytes each.
; --------------------------------------------------------------------------
SECTION .data
array: dd 1,5,3,7,4,8,5,2
size: equ $-array
SECTION .text
global main
main:
; ------------------------------------------------------------------
; * Main
; ------------------------------------------------------------------
call addVector
breakpoint: ; Used for GDB to inspect the result later
; ------------------------------------------------------------------
; * Exit
; ------------------------------------------------------------------
mov EAX,0
int 0x80
; ------------------------------------------------------------------
; * Initial function call, before doing the recursive calls
; Sets ESI to 0, which will be used to count the array's elements
; Also sets EAX to 0, for storing the result
; ------------------------------------------------------------------
addVector:
push ESI
mov ESI,0
mov EAX,0
call recursiveCall
pop ESI
ret
; ------------------------------------------------------------------
; * Recursive part of the function
; Adds to EAX to current element, and increases the ESI counter by
; 4 (because the array's elements are 4-bytes each).
; If the counter happens to be >= the array's size, stop.
; ------------------------------------------------------------------
recursiveCall:
cmp ESI,size
jge endRecursiveCall
add EAX,[array + ESI]
add ESI,4
call recursiveCall
endRecursiveCall:
ret
First, your definition of size
is wrong, your way will give you the total bytes of the array; this is not what you want. Your array is made of DWORDS, you want to know the total elements, so we divide by 4 (The size of a DWORD):
size: equ ($-array) / 4
Two ways of doing this, start from the end of the array or the beginning:
From end:
array: dd 1,5,3,7,4,8,5,2
size: equ ($-array) / 4
SECTION .text
global main
main:
xor eax, eax ; clear out eax
mov esi, size - 1 ; set our index to array end
call recursiveCall
push eax
push fmtint
call printf
add esp, 4 * 2
.exit:
call exit
recursiveCall:
add EAX, dword[array + 4 * ESI]
dec ESI
js .endRecursiveCall
call recursiveCall
.endRecursiveCall:
ret
From start:
SECTION .text
global main
main:
xor eax, eax ; clear out eax
xor esi, esi ; set out index to start of array
call recursiveCall
push eax
push fmtint
call printf
add esp, 4 * 2
.exit:
call exit
recursiveCall:
add EAX, dword[array + 4 * ESI]
inc esi
cmp esi, size - 1
jg .endRecursiveCall
call recursiveCall
.endRecursiveCall:
ret
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.