WithnoMute 0 Newbie Poster

Trying to progress in learning Assembly, but can't seem to figure out something.
In an example source code, it stores local data and -4(ebp) then does a pushl on it. I don't know what its doing there? How can you push something on the stack? Here is the source code, its from "programming from the ground up"; its suppose to work with two other programs and is teaching about records. I just don't get whats going on when you do a pushl on a stack position.

What im talking about is on line 39, this assembles ok but i just don't understand it.

.include "linux.s"
.include "record-def.s"
.section .data
file_name:
	.ascii "test.dat\0"
	.section .bss
	.lcomm record_buffer, RECORD_SIZE

.section .text
#Main program
.globl _start
_start:
	#These are the locations on the stack where
	#we will store the input and output descriptors
	#(FYI - we could have used memory addresses in
	#a .data section instead)
	.equ ST_INPUT_DESCRIPTOR, -4
	.equ ST_OUTPUT_DESCRIPTOR, -8
	#Copy the stack pointer to %ebp
	movl %esp, %ebp
	#Allocate space to hold the file descriptors
	subl $8, %esp
	#Open the file
	movl  $SYS_OPEN, %eax
	movl  $file_name, %ebx
	movl  $0, %ecx    #This says to open read-only
	movl  $0666, %edx
	int   $LINUX_SYSCALL
	#Save file descriptor
	movl  %eax, ST_INPUT_DESCRIPTOR(%ebp)
	#Even though it’s a constant, we are
	#saving the output file descriptor in
	#a local variable so that if we later
	#decide that it isn’t always going to
	#be STDOUT, we can change it easily.
	movl $STDOUT, ST_OUTPUT_DESCRIPTOR(%ebp)

record_read_loop:
	pushl ST_INPUT_DESCRIPTOR(%ebp)
	pushl $record_buffer
	call read_record
	addl $8, %esp
	#Returns the number of bytes read.
	#If it isn’t the same number we
	#requested, then it’s either an
	#end-of-file, or an error, so we’re
	#quitting
	cmpl $RECORD_SIZE, %eax
	jne   finished_reading
	#Otherwise, print out the first name
	#but first, we must know it’s size
	pushl $RECORD_FIRSTNAME + record_buffer
	call   count_chars
	addl   $4, %esp
	movl   %eax, %edx
	movl   ST_OUTPUT_DESCRIPTOR(%ebp), %ebx
	movl   $SYS_WRITE, %eax
	movl   $RECORD_FIRSTNAME + record_buffer, %ecx
	int    $LINUX_SYSCALL
	pushl  ST_OUTPUT_DESCRIPTOR(%ebp)
	call   write_newline
	addl   $4, %esp
	jmp    record_read_loop

finished_reading:
	movl $SYS_EXIT, %eax
	movl $0, %ebx
	int  $LINUX_SYSCALL
#linux.s
#Common Linux Definitions
#System Call Numbers
.equ SYS_EXIT, 1
.equ SYS_READ, 3
.equ SYS_WRITE, 4
.equ SYS_OPEN, 5
.equ SYS_CLOSE, 6
.equ SYS_BRK, 45
#System Call Interrupt Number
.equ LINUX_SYSCALL, 0x80
#Standard File Descriptors
.equ STDIN, 0
.equ STDOUT, 1
.equ STDERR, 2
#Common Status Codes
.equ END_OF_FILE, 0

just for completion

#record-def.s
.equ RECORD_FIRSTNAME, 0
.equ RECORD_LASTNAME, 40
.equ RECORD_ADDRESS, 80
.equ RECORD_AGE, 320
.equ RECORD_SIZE, 324