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
Read about calling conventions.
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.
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.
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.
now i add some code to print the array elements which it does but the largest number is somehow trashed.
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
Just some clarification..
the _cdecl convention doesn't pop off parameters from the stack right?
Yes, that's right.the _cdecl convention doesn't pop off parameters from the stack 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.
Worked perfectly!!thanx once again