i have a function func which is supposed to print numbers from 0 to 10 but it only prints 0 then exits.something must be wrong with the loop but i can't seem to figure it out


section .data
fmt db "%d ",10,0


section .text
global _func
extern _printf

_func:
push ebp
mov ebp,esp
sub esp,12
xor ecx,ecx
mov edx,10

L1:
cmp ecx,edx
jge L2
push ecx
push fmt
call _printf
inc ecx
jmp L1

L2:
mov esp,ebp
pop ebp
ret
Posted on 2011-11-12 16:06:16 by ashken
Read about calling conventions.
http://www.agner.org/optimize/calling_conventions.pdf


sections 6 (Register usage) and 7 (Function calling conventions)

ecx and edx are volatile, use non-volatile registers or push/pop or local var.
printf is __cdecl which means caller cleans the stack.
Posted on 2011-11-12 16:39:38 by drizz
thanx @drizz.I had forgotten that regs eax,ecx and edx get trashed between function calls.Just some clarification..
the _cdecl convention doesn't pop off parameters from the stack right?
Also i modified the function to loop through an array of integers(whose name/pointer it receives as a parameter) and find the largest number which works ok but the problem comes when i want to print the array elements during the iterations.it does so but the largest number which i preserved the ebx register for somehow gets filled with garbage data from memory.

//this prints the largest number in the array of five elements

segment .data

fmt db "%d ",10,0

segment .text
global func
extern printf

func:
push ebp
mov ebp,esp
sub esp,16

mov ebx, ;the array/pointer to first element goes in here
mov esi,ebx
mov edi,ebx
add edi,20
mov ebx,dword
add esi,4
loop:
cmp esi,edi
jge l2
mov edx,
cmp ebx,edx
jge L3
mov ebx,edx
add esi,4
jmp loop
L3:
add esi,4
jmp loop

l2:
push ebx
push fmt
call printf
add esp,8
mov esp,ebp
pop ebp
ret

now i add some code to print the array elements which it does but the largest number is somehow trashed.


segment .data

fmt db "%d ",10,0

segment .text
global func
extern printf

func:
push ebp
mov ebp,esp
sub esp,16

mov ebx, ;the array/pointer to first element goes in here
mov esi,ebx
mov edi,ebx
add edi,20
mov ebx,dword
add esi,4
loop:
cmp esi,edi
jge l2
mov edx,
push edx
push fmt
call printf
add esp,8
cmp ebx,edx
jge L3
mov ebx,edx
add esi,4
jmp loop
L3:
add esi,4
jmp loop

l2:
push ebx
push fmt
call printf
add esp,8
mov esp,ebp
pop ebp
ret

Posted on 2011-11-14 14:52:38 by ashken
Just some clarification..
the _cdecl convention doesn't pop off parameters from the stack right?
Yes, that's right.

	call printf
add esp,8
cmp ebx,edx;  <---------- AGAIN, edx is volatile substitute edx with

I had forgotten that regs eax,ecx and edx get trashed between function calls.


Also don't forget to preserve non-volatile registers in func.

Posted on 2011-11-15 07:12:52 by drizz
Worked perfectly!!thanx once again
Posted on 2011-11-15 14:18:09 by ashken