"It should subtract %esp by 4 and then save %esp at the location esp is pointing to"
That would have happened on 8086 CPU.From 80286, it stores ESP internally, then subtracts, then writes value stored internally. You have to allocate variable first (one push or one esp-4) then store address of this variable (second push). For first question you have to make 3 pushes or one sub and 2 pushes. In your case, esp points to stack location where old EBP was stored. You can use
push eax
push esp
push fmt
this would work as well.
Also, about the second problem, you referred to the lines which didn't even matter,
Oh yeah, I copied over wrong code lines, sorry. I was reffering to this piece:
pushl %esp #location of x
pushl %esp #location of y
pushl $fmt
call scanf
I pointed out, why your code is incorrect. You have to push 2 addresses of variables. Instead you push address of old EBP, then address of cell in stack with prev parameter (that points to old EBP); As result, on read one parameter get messed up, receiving value you entered on scanf. When it wants to write another value, instead of address of a cell, it has previous int.
Lastly, could you explain your suggested code? Why would I move edx and eax into esp, I don't even know what's in them
Sorry, this is an Intel syntax, hence mov eax, esp means "write esp to eax". It is not a very good code, indeed. Just for an example.
I allocate one variable on stack, get address of it in eax. Then allocate another var, store its address in edx. Then push both addresses, then push offset of fmt.
You have to allocate space first. And you do not need frame unless you are going to address local vars using EBP relative addresses. You can push ebp - 4 etc. Just compile your code and look how it works in any debugger (I used ollydbg to check your code); Finally, you can ask C compiler to generate asm listing and look, how compiler does this.