A compiler and an assembler are both programs that (roughly stated) translate human readable source code (C or assembly language) to machine code (or some code not designed for human consumption). There really is not much of a difference, except for the source language. You might as well call both "compiler".
Compilers for higher level languages (like C) have to figure out what the code is supposed to do, and translate it into a very different language (e.g. machine language for your machine), there is a lot of leeway to do so. For low level languages, like assembly language (which is close to the machine language) there is very little wiggle room, if any.
The resulting machine code is binary representation of the instructions to be executed. This has to be packaged up for other tools to process this in several ways (e.g. to link several separately compiled pieces to create an executable program), and for this apart from the instructions themselves other information is added (addresses inside the code where a function starts, places where an external function is called to patch it's address in, ...). The resulting program file contains the instructions to be executed, but also information needed to control it's placing in memory, where it should start execution, and others. A file containing this is handled by the operating system to load instructions into memory and start running. There are several different such formats. Each operating system uses it's own format. Many such formats are defined so they work for different instruction sets/formats (they aren't intrinsecally machine-dependent), some operating systems (like Linux) are even able to handle several formats (to be able to run e.g. executables for other systems).