Hi again,
Apparently I wasn't very clear in our private messages!
xor esp,esp ;index for the stack level
In particular, I certainly didn't intend to tell you to do that! Get rid of that line, to start with. There's plenty more wrong with it, but that should get you past "push 1" at least.
I understand you're using "ddd" to step through your code. I've never used "ddd" but I think I know what it is. If that's working for you, it should help a lot. I understand your instructor suggested you keep an eye on EIP and watch how it changes as your subroutine is called, and returns. I'll suggest you also keep an eye on esp. In particular, watch how it changes when you do "push 1". You are not pushing a single byte onto the stack. The 1 is stored in memory as a single byte, but it's sign-extended to a dword (4 bytes, 32 bits) and that's pushed onto the stack. So to "clean up" after your subroutine returns, you need to "add esp, 8" not 2. This means that your offsets from ebp in your subroutine are wrong, too. After the usual prolog, the "first" (last pushed) parameter is at [ebp + 8]. Stack should look like...
parameter N
parameter N -1
...
...
parameter 0
return address
caller's ebp
At this point, ebp is "locked" to the present value of esp - and we do NOT want to alter ebp! Passed parameters are ar [ebp + 8], [ebp + 12], [ebp + 16], etc. and local variables (when we get to them) are at [ebp - 4], etc. That's how ebp is usually used (although it can be used as a general purpose register). In this case, your caller wasn't using ebp, but often the caller will be using it, so we don't want to trash it.
You've also got a problem with using the "loop" instruction (I think I showed you that). "loop" uses ecx as its loop counter. You modify ecx (cl) both in your loop and in your subroutine. This means it's going to loop forever! I probably shouldn't have showed you using "loop". Although the subroutine I showed you did not alter ecx, it is "allowed" for a subroutine to trash ecx according to most calling conventions. Using "loop" (and thus ecx) and calling printf in the middle of it is a common newbie problem. The solution is to preserve ecx around subroutine calls (ugly) or don't use the "loop" instruction. You can do the same thing using any other register (not esp, please!)...
mov edi, 4
top:
; do something
dec edi
jnz top
; at this point, your loop is finished
; do something else!
mov eax, 1 ; sys_sxit
xor ebx, ebx ; claim "no error"
int 80h
; at this point, you don't have to do anything else.
; good place for your subroutines
Well, I see that Gunner has made some suggestions. Thanks, Gunner! Take another shot at this and get back to us...
Best,
Frank