Getting Parameters in IA32 Assembly...

Started by
18 comments, last by LessBread 18 years, 6 months ago
Quote:Original post by doynax
Quote:Original post by Krisc
okay, so the second one is an array of pointers. so what i need to do is add 4 to the memory spot of the second parameter each time i want to increment to the next spot in the array. correct?
Correct.


I have this much... it is so confusing! arrg! ;)

main:     	pushl	%ebp	movl	%esp, %ebp	#... put argv[1] into ebx	#... put argv[2] into ecx	pushl (%ebx)	call atoi	pushl (%ecx)	call atoi
Advertisement
Try this:
     	movl 12(%ebp),%eax  # load argv into eax     	movl 4(%eax),%ebx  # put argv[1] into ebx     	movl 8(%eax),%ecx  # put argv[2] into ecx
Shouldn't it be 12(%ebp),

It is still throwing a seg fault, time to load up gdp.
Quote:Original post by Krisc
Shouldn't it be 12(%ebp),
Oops.. Guess I've gotten a little too used to direct esp addressing..
Quote:Original post by Krisc
It is still throwing a seg fault, time to load up gdp.
But you're still not removing your arguments after the atoi calls. You need to pop them (or add 4 to the stack pointer).
I don't understand what you mean by removing my arguments... Could you go a bit in depth about this?
Quote:Original post by Krisc
I don't understand what you mean by removing my arguments... Could you go a bit in depth about this?
Well, the strings you're pushing for the atoi calls needs to be removed from the stack (popped) by someone. In stdcall this is the callee's responsibility but in cdecl (the "standard" convention) it's actually up to the caller to do it.

So your function call might look like this:
pushl (%ecx)call atoipopl %eax
or this:
pushl (%ecx)call atoiaddl 4,%esp
okay, this is the entire program in IA32 asm... I got it working except y is set to whatever x is somehow...or somehow x is passed in twice to pow.

running:
./p1 2 4
results in
x^y = 4

running:
./p1 4 2
results in
x^y = 256

here is the code, thanks for the help guys i am beginning to understand it all
	.file	"p1.c"	.section	.rodata.LC0:	.string "x^y = %d\n"	.text.globl pow	.type	pow,  @functionpow:	pushl	%ebp	movl	%esp, %ebp	pushl	%ebx		# save ebx	pushl	%esi		# save esi	pushl	%edi		# save edi		movl	8(%ebp),%eax	# eax now holds x	movl	12(%ebp),%edx	# edx now holds y	xor	%ebx,%ebx	addl	%eax,%ebx	.L1:	decl	%edx	imull	%ebx,%eax	cmpl	$1,%edx	jg	.L1	popl	%edi		# restore edi	popl	%esi		# restore esi	popl	%ebx		# restore ebx	leave	ret.globl main	.type	main, @functionmain:	pushl	%ebp	movl	%esp, %ebp	pushl	%ebx		# save ebx	movl	12(%ebp),%eax	# load argv into eax (temp)	movl	4(%eax),%ebx	# x = argv[1]	movl	8(%eax),%ecx	# y = argv[2]	pushl	%ecx		# push y on the stack, as it gets				# clobbered by atoi	pushl	%ebx		# push x into atoi via stack	call	atoi		# call atoi	movl	%eax,%ebx	# move result into (x) ebx	call	atoi		# call atoi with y	movl	%eax,%ecx	# put result into (y) ecx	pushl	%ecx		# push y as second param	pushl	%ebx		# push x as first parameter	call	pow		# call power function	push	%eax		# push returned value	push	$.LC0		# push fmt string	call	printf		# call printf	popl	%ebx		# restore ebx	xor	%eax, %eax	leave	ret	.size	main, .-main	.section	.note.GNU-stack,"",@progbits	.ident	"GCC: (GNU) 3.3.5 20050117 (prerelease) (SUSE Linux)"
The next step with your pow function ...

	.text.globl pow	.type	pow,  @functionpow:	pushl	%ebp	movl	%esp, %ebp	pushl	%ebx		# save ebx	pushl	%esi		# save esi	pushl	%edi		# save edi		movl	8(%ebp),%eax	# eax now holds x	movl	12(%ebp),%edx	# edx now holds y	xor	%ebx,%ebx	addl	%eax,%ebx	.L1:	decl	%edx	imull	%ebx,%eax	cmpl	$1,%edx	jg	.L1	popl	%edi		# restore edi	popl	%esi		# restore esi	popl	%ebx		# restore ebx	leave	ret


... is to notice that since you don't use %edi or %esi you don't need to preserve them. And also that if you use %ecx instead of %ebx you won't have to preserve %ebx either. This reduces the number of instructions used by the function, thus making it faster which is good for a function like pow. The %ecx register is usually used as a counter, such as the loop countdown that you used %edx for. So you might consider using %ecx where you use %edx and %edx where you use %ebx.

Another thing to consider, but which I don't want to add to any confusion, is that the parameters can be accessed relative to %esp, further reducing the number of instructions used by the function. YMMV.

	.text.globl pow	.type	pow,  @functionpow:	movl	4(%esp),%eax	# eax now holds x	movl	8(%esp),%ecx	# ecx now holds y	xorl	%edx,%edx	addl	%eax,%edx	.L1:	decl	%ecx	imull	%edx,%eax	cmpl	$1,%ecx	jg	.L1	ret
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man
I forgot to pop eax off the stack after atoi... Thanks guys. ++ for all!
It looks like more than just once. In my earlier post I didn't examine main at all, but you've left the arguments to the functions on the stack.

 pushl	%ecx		# push y as second param pushl	%ebx		# push x as first parameter call	pow		# call power function addl   $8,%esp         # clean pow arguments from stack


Some functions clean the arguments from the stack as part of the return statement. For example, by including the number of bytes of arguments following the ret instruction, "ret $4" for one argument, "ret $8" for two arguments and so on.

Since I wrote about the pow function last time, I'll keep to it. The pow function doesn't clean the arguments from the stack, the function that calls it needs to do it - as the above code shows. A stack is like an array of unsigned longs, but stacks grow from higher addresses to lower addresses which is kind of strange thing to get your head around at first. What this means is that you subtract from a stack to expand it and add to it to retract it. Thus to remove the arguments add the number of bytes to esp. This goes for atoi and printf as well. Since atoi takes two arguments "addl $8,%esp" is needed following the call. The call for printf also takes two arguments so "addl $8,%esp" will work there as well, but other calls to printf will be different because printf can accept a variable number of arguments.
"I thought what I'd do was, I'd pretend I was one of those deaf-mutes." - the Laughing Man

This topic is closed to new replies.

Advertisement