A compiler is a computer program that transforms source code written in one programming language (the source language), into another programming language (the target language, often having a binary form known as object code).
The first compiler was written by Grace Hopper, in 1952, for the A-0 System language. The A-0 System was a set of instructions that could translate symbolic mathematical code into machine language. The term compiler was coined by Hopper.
In 1960, the COBOL compiler for the UNIVAC II was the first to be written in a high level language, namely FLOW-MATIC. This again came from a team led by Grace Hopper.
Assembly instructions are a direct mapping to opcodes, which are byte values of machine code that can be directly interpreted by the processor. A very primitive program can be written in opcodes directly by looking them up from a table(which are different for different microprocessors) that lists them with the matching assembly instructions, and hand-determining memory addresses/offsets for things like jumps.
The first assemblers were written in this fashion - hand-written opcodes. Now these assemblers automated opcode lookups, as well as computing addresses/offsets for named jump labels.
These primitive assemblers could then be used to assemble more sophisticated assemblers which in turn could be used to assemble complex compilers written for higher-level languages(that would contain all the complex logic for lexical analysis, parsing, optimization basically written in assembly-language to be directly interpreted).
This process of iteratively writing the tools to simplify the creation of the next set of tools is called bootstrapping. And this bootstrapping process of writing a compiler (or assembler) in the programming language which it is intended to compile, creates a self-hosting compiler. Most of the modern-day programming languages have self-hosting compilers.