Why can't I change the value of the segment register? (MASM)

I decided to teach myself assembler.

I realized that my program would not compile if I try to change the value of any segment register.

Every article I found says that I can really change the value of at least 4 segment registers, and what gives?

I really wonder only why at this moment I have no real goal in changing these addresses.

+6
assembly x86 masm
source share
2 answers

You said you are interested in why:

In real mode, the segment is a 64K “window” into physical memory, and these windows are spaced 16 bytes apart. In protected mode, a segment is a window into physical or virtual memory, the size and location of which is determined by the OS, and it has many other properties, including the privilege level that a process must have to access it.

From now on, everything that I say relates to the protected regime.

There is a table in memory called the global descriptor table (GDT), which stores information about these window sizes and locations and other properties. There may also be local descriptor tables for each process, and they work in a similar way, so I just focus on GDT.

The value that you load into the segment register is called the segment selector. This is an index in GDT or LDT with some additional security information. Naturally, if a program tries to load a handle that goes beyond the GDT, an exception is thrown. Also, if the process does not have sufficient authority to access the segment or something else is invalid, an exception is thrown.

When an exception occurs, the kernel processes it. Such an exception is likely to be classified as a segmentation error. Thus, the OS kills your program.

There is one final caveat: in the x86 instruction set, you cannot load instantaneous values ​​into segment registers. You must use an intermediate register or memory operand or POP in the segment register.

  MOV DS, 160; INVALID - won't assemble

 MOV AX, 160; VALID - assembles, but will probably result in an
 MOV DS, AX; exception, and thus the death of your program

I think it should be noted that architecture allows heaps of segments. But AFAIK, when it comes to major x86 operating systems, segment registers serve only a few purposes:

  • Security mechanisms, such as storing user space processes from harm to each other or the OS
  • Work with multiple / multi-core processors
  • Stream local storage: as an optimization, some operating systems (including Linux and Windows) use segment registers for local stream storage (TLS). Since streams use the same address space, it is difficult for a stream to know where its TLS area does not use a system call or lose case ... but since segment registers are practically useless, there is no harm in wasting them, for the sake of fast TLS. Please note that when setting up the OS, the OS can skip segment registers and write directly to descriptor cache registers, which are “hidden” registers used to cache GDT / LDT requests caused by references to segment registers, in which case, if you try to reading from segment registers you will not see it.

In addition to the segment per thread for TLS, in fact, only a few segments are used (times the number of processors) and only the OS. Applications can completely ignore segment registers.

This is due to the design of the OS, and not to technical limitations. There may be embedded operating systems that require user-space programs to work with segment registers, although I don't know anything.

+8
source share

Are you writing Windows executables?

In protected mode (Win32), segment registers are no longer used.

Link :

The memory model is also dramatic in contrast to the old 16-bit world. In Win32 we do not need to deal with a memory model or segment anymore! There is only one memory model: a flat memory model. No more 64K segments. the memory is a large contiguous 4GB space. It also means that you do not have segment registers to play. You can use any segment register to address any point in memory space. This is a BIG help to programmers. This is what makes assembling Win32 programming as easy as C.

+2
source share

All Articles