여전히 NASM 어셈블리 인 32 비트 우분투에서 재귀를 배우려고합니다. 이제 배열의 모든 요소를 재귀 적으로 추가하려고합니다. 배열 요소는 모두 각각 4 바이트입니다.NASM 어셈블리의 배열에있는 모든 요소를 반복적으로 추가합니다.
나는 작동하는 해결책을 생각해 냈습니다.
기본적으로 배열에 요소를 추가하려면 어떻게 든 을으로 계산해야합니다. 맞습니까? 그래서 내 카운터로 ESI
있습니다. 그러나이 레지스터는 함수 시작 부분에 0
으로 설정해야합니다. 그러나 현재 함수 호출이 첫 번째 호출인지 또는 두 번째 또는 세 번째 호출인지 여부를 알 수있는 방법이 없다고 생각합니다. 이 문제를 해결하려면 초기 호출과 재귀 호출의 두 가지 기능이 있습니다. 첫 번째는 ESI
에서 0
으로 설정 한 다음 재귀 호출을 호출합니다. 요소는 모든
.. 또한 초기 호출에 0
로 설정 EAX
에 추가됩니다하지만 약간이 재귀 함수에서 다른 내가 한 일이기 때문에 나는 그것으로 걱정하기 전에 :
, 때문에 무엇보다도 먼저, 나는 두 가지 기능, 시작 하나, 실제 재귀 부분에 대한 또 다른를 사용하고 있습니다. 또한, 반복적 인 솔루션과 매우 흡사 한 카운터를 사용하고 있습니다.
제 질문은 : 제가 위에 게시 한 두 가지 재귀 함수와 유사한 솔루션이 있습니까? 현재 솔루션을 재귀 적으로 간주 할 수 있습니까?
; --------------------------------------------------------------------------
; 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
이 것 항상 카운터일까요? 그런데'fmtint'는 무엇입니까? – Voldemort
초기 통화? 음, 물론! 부두에 의지하지 않고 함수에 ""들어가려면 어떻게해야합니까? 'fmtint'는'printf'에 반환 된 값을 출력하기 위해 사용한 형식 지정자입니다. fmtint \t db \t "% d", 0' 카운터? 예, 재귀 호출을 중지 할시기를 알아야합니다. 카운터, 부울 값 등입니다. – Gunner
니스, 고마워. 크기 상수는 괜찮 았지 만, 어쨌든 매번 '4'씩 증가시키기 때문에 생각합니다. 멋지게 잡아라, 그것은 물건을 더 단순하게한다. – Voldemort