theUserMan 0 Newbie Poster

working on a 32bit architecture and i'm adding two arrays together slot by slot into a third array so if I have 3,4,4 and 4,4,4 in the arrays the third array should contain 7,8,8 at the end of the function

I was able to pass in the arrays correctly and the amount of items into the function arleady, i know this because I ran test code

now i'm working on the addition part of it, here is what I have, the logic makes sense to me but it's still seg faulting...ideas?

;*************************************ADD ARRAY**********************************************
segment .bss
;
segment .data
summessage	db	"The Sum is: ", 0
segment .text
extern readdouble,print_string, read_int, writedouble, print_nl, print_int
	global addarray
addarray:
	pusha
	mov	edi, 0		;initialize counter to 0
	mov	ecx, 0		;zero out ecx and edx
	mov	edx, 0
	
	mov	ebx, [esp+48]	;moves starting location of array1 into ebx
	mov	edi, [ebp+40]	;move quantity into edi	
	mov	ebp, [esp+60]	;move the starting location of array2 into ebp
	
	mov	esi, [esi]	;move starting locatino of array3 into esi
	
	;mov	ecx, [ebp]
	;mov	edx, [ebp+4]
	;call	writedouble
	;call	print_nl

add_loop:

        fld     qword [ebx]      ;The second input is now in a floating point register, specifically st0.
	fld	qword [ebp]

	fadd    	         ;The first input is added to the second input and the sum
		                 ;replaces the second input in st0
	
	fstp	qword [ecx]	;copy top of stack onto ecx
	mov	ecx,[ecx]
	mov	edx,[edx+4]	
	
	mov	[esi], ecx
	mov	[esi+4], ecx
	add	esi, 8		;increment to the next loaction of esi
	
	add	ebx,8		;increment location of ebx to the next floating point value of array1
	;add	ebp,8		;increment location of ebp to the next floating point value of array2
	
	dec	edi		;increment counter

	cmp	edi, 0		;compare to see if all values have been added
	jz	add_done
	jmp	add_loop
add_done:
	popa
	ret

Dani AI

Generated

For : the segfault is almost certainly caused by mixing stack/frame offsets and by dereferencing registers that were never initialized. The function reads arguments with different schemes (esp offsets and ebp offsets) without establishing a proper frame, and there are instructions that dereference a register used as a pointer (for example mov esi, [esi] style logic). Also, storing the 64-bit FPU result via 32-bit moves is fragile: if the registers holding the halves are wrong you will write to invalid memory. In short, check your prologue/argument offsets, make sure every pointer register is loaded before you dereference it, and let the FPU write the full qword result instead of trying to split it manually.

A safe, minimal pattern to follow (use standard cdecl stack frame, copy argument pointers into regs, do FPU add and store the qword directly) is shown below. This avoids pushing registers before reading arguments (so offsets are simple) and uses fstp qword [dest] to write the double in one step.

push ebp
mov  ebp, esp
mov  ebx, [ebp+8]    ; arg1 (pointer to doubles)
mov  ecx, [ebp+12]   ; arg2
mov  edx, [ebp+16]   ; dest
mov  esi, [ebp+20]   ; count

add_loop:
  fld   qword [ebx]
  fadd  qword [ecx]
  fstp  qword [edx]
  add   ebx, 8
  add   ecx, 8
  add   edx, 8
  dec   esi
  jnz   add_loop

pop  ebp
ret

Debugging tips: run under a debugger and break at the start of your function, then inspect the register values used as pointers before the first fld and before any memory writes. Print the addresses and the count from the caller to confirm you received the expected arguments. If you must manipulate pointer bytes with integer registers, ensure you split the 64-bit store correctly (low dword and high dword) and advance by 8 each loop. If your platform supports SSE2, using MOVSD/ADDSD can simplify both correctness and performance.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.