32 ビット Ubuntu の NASM アセンブリで再帰を学ぶ途中ですが、配列内のすべての要素を再帰的に追加しようとしています。配列の要素はすべて 4 バイトです。
うまくいきそうな解決策を思いついた。
基本的に、配列に要素を追加するには、何らかの方法でそれらをカウントする必要がありますよね? だから私はESI
私のカウンターとして持っています。ただし、このレジスタは関数の先頭に設定する必要が0
あります-しかし、現在の関数呼び出しが最初のものなのか、2番目または3番目のものなのかを知る方法はないと思います...修正するにはこれには、初期呼び出しと再帰呼び出しの 2 つの関数があります。最初のものは再帰呼び出しを設定ESI
してから呼び出します。0
要素はすべて に追加され、最初の呼び出しでEAX
も に設定されます。0
しかし、私が以前に行った2つの再帰関数とは多少異なるため、私はそれを心配しています:
まず第一に、2 つの関数を使用しています。1 つは開始用で、もう 1 つは実際の再帰部分用です。また、私はカウンターを使用していますが、これは非常に反復的なソリューションのように感じます。
私の質問は次のとおりです。上に投稿した2つの再帰関数に似た解決策はありますか? 現在のソリューションは再帰的と見なすことができますか?
; --------------------------------------------------------------------------
; 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