Without giving away your homework...
... let me plant a few useful ideas...
The Intel x86 architectures generally implement the notion that, when a program requests "an instruction at" location
0x'123456', and then "a piece of data at"
0x'123456', it might well have a legitimate reason for these two requests to refer to an entirely-separate piece of physical memory, even though the
address is exactly the same in both cases.
The distinction is
contextual: one reference is for "executable code," and the other is for "data."
The designers at Intel expressed this as "the 'code segment' (CS)" versus "the 'data segment' (DS)."
In other words,
every reference to memory would consist not-only of "an address," but also an (implied...) "segment."
The operating system, whatever it was (Linux... Unix... Win-doze...) would therefore need to have a way to map "a segment" to "a particular range of physical-memory addresses."
The
segment descriptor tables, GDT and LDT, accomplish this.
The
GDT is designed to be, as the name implies, "global." In other words, every process on a system would share these entries. The
LDT, then, would be "local." Every process on a system would have its own set of local entries.
The architecture
conceals the difference between "GDT" and "LDT" from the running processes, since only the operating-system would know or care....