The "frame pointer" gives you access to parameters passed on the stack, and to local variables, usually using small (signed byte) offsets (smaller opcodes). Best place to learn more is probably
http://www.drpaulcarter.com/~pcasm"Pushl" looks like at&t (Gas) syntax, not Nasm. It just means a 32-bit push - "push dword ..." in Nasm syntax. FWIW, in Nasm 0.98, "push 1" was not valid. You *had* to specify either "push word 1" or "push dword 1". Shortly after the release of 0.98, the folks involved in Nasm development at that time - primarily H. Peter Anvin (still with us) and John Fine (gone on to other interests, and sorely missed) - decided that it would be sensible for Nasm to "assume" that the size of a "push" was word if Nasm was emitting in "bits 16" mode, and dword if in "bits 32". All later versions of Nasm work this way - you can override it if you need to, but this is extremely rare!
To further complicate the issue, there's "push byte 1". This does *not* push a byte on the stack - there's no such instruction. The operand is *stored* as a byte in the code stream, but expanded - sign-extended - to word or dword when it's pushed. Nasm does not make this optimization by default - you have to specify "push byte" (the apparently contradictory "push dword byte" works, too - Nasm knows what you mean). Using the "-O" switch (use a good big "maximum passes" parameter - I like "-O999" - add a "v" for "verbose" if you want a report on how many passes it actually used) will cause Nasm to use the "push byte" form if the supplied operand will fit in a signed byte - -128 thru +127.
Best,
Frank