Fencing is an early form of memory management designed to ensure applications and user data do not corrupt the operating system. The earliest, and most basic form of fencing simply separated the operating system and user data into two sections, creating boundaries on either side. While effective for separating the OS from data, the bounds were fixed so neither side could expand beyond a certain point making a fence very restrictive. Additionally, locations for memory were often physically written to the code in the past, making adjustment or movement of that data within the fence extremely difficult.
These issues were addressed with the creation of a fence register, a type of hardware register. A fence register is more flexible and allows for a dynamic fence that can resize and move as needed. In this implementation, the operating system and user data are assigned to different sections of memory, the locations marked with integers. When an action or modification is made above a certain integer bound this is recognized as user input and the modification is accepted. When the action falls below a certain bound it is viewed as an action to affect the operating system; unless proper permissions are provided this action will fail and output an error message. Even the fence register has limitations, specifically protection is unidirectional; the operating system can be protected from a user, but users and applications are not necessarily protected from one another.
Relocation is important so the operating system knows where data is stored and can access it. Ideally programs/data would start at address 0 and go up, and if an operating system is a fixed size the programmer can know at which address to begin. However, the operating system can change in size from version to version, and it would be extremely difficult and time consuming to manually update the address location. By adding a relocation factor to each address for the program, the system can automatically update the addresses as needed. Combined with a fence register, a program can be moved to a new memory location while maintaining a fence ensuring access to any location lower than the fence is restricted (except in special circumstances).
Fence registers only provide a starting point, or lower bound, which is useful when multiple users are trying to execute programs, but the lack of an upper bound has inherent risks from overflow, and as was previously mentioned corruption from other users. A second register is typically added to provide an upper bound limit; this is known as a bounds register. Creating an upper bound on actions forms something of a sandbox to ensure that one user cannot negatively impact another.