Arrays 在NASM汇编中递归添加数组中的所有元素
在我学习NASM汇编(32位Ubuntu)中递归的过程中,我现在正在尝试递归地添加数组中的所有元素。数组的每个元素都是4字节 我想出了一个似乎有效的解决办法 基本上,要在数组中添加元素,我需要对它们进行计数,对吗?因此,我有Arrays 在NASM汇编中递归添加数组中的所有元素,arrays,algorithm,assembly,recursion,nasm,Arrays,Algorithm,Assembly,Recursion,Nasm,在我学习NASM汇编(32位Ubuntu)中递归的过程中,我现在正在尝试递归地添加数组中的所有元素。数组的每个元素都是4字节 我想出了一个似乎有效的解决办法 基本上,要在数组中添加元素,我需要对它们进行计数,对吗?因此,我有ESI作为我的计数器。但是,这个寄存器需要在函数开始时设置为0,但是我认为没有任何方法可以判断当前函数调用是第一个,还是第二个或第三个。。。为了解决这个问题,我有两个函数:初始调用,和递归调用。第一个函数将ESI设置为0,然后调用递归调用。这些元素都被添加到EAX,在初始调用
ESI
作为我的计数器。但是,这个寄存器需要在函数开始时设置为0
,但是我认为没有任何方法可以判断当前函数调用是第一个,还是第二个或第三个。。。为了解决这个问题,我有两个函数:初始调用,和递归调用。第一个函数将ESI
设置为0
,然后调用递归调用。这些元素都被添加到EAX
,在初始调用中,EAX也被设置为0
但我关心它,因为它与我以前做过的两个递归函数有些不同:
; --------------------------------------------------------------------------
; 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
首先,您对
大小的定义是错误的,您的方式将给出数组的总字节数;这不是你想要的。您的数组是由DWORD组成的,您想知道元素总数,所以我们除以4(DWORD的大小):
有两种方法可以执行此操作,从阵列的末尾或开头开始:
自始至终:
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
从一开始:
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
所以基本上总是有一个初始呼叫,并且总是有一个计数器?顺便问一下,fmtint
是什么?初始呼叫?好吧,当然!如果不借助巫毒,你如何“进入”这个功能fmtint
用于打印返回值fmtint db“%d”,0
的格式说明符是否为计数器?是的,您需要知道何时停止递归调用-计数器、布尔值等等。很好,谢谢。虽然我认为size
常数很好,因为我每次都增加4
。虽然捕捉得很好,但它使事情变得更简单。
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