First, I feel compelled to point out that you appear to be talking here about 8086 "real mode" addressing, which is a very old way of doing things which almost nothing uses anymore. Pretty much all modern operating systems operate in "protected mode", which supports many enhancements (such as flat 32- and 64-bit memory space addressing, virtual memory, etc.) which changes how all of this works substantially.
As far as I know, most operating systems nowadays don't even have any way to run code such as this (in real mode) anymore, so if you're interested in learning assembly for the purposes of programming modern PCs, you might want to find some more recent sources to learn from.
That having been said, assuming you do have some reason to want to do this (such as working with certain embedded processors), or are just curious for historical purposes:
Yes, the 8086 real-mode segment registers can be modified. The instructions and options for doing this are a bit more limited than modifying the more general-purpose registers (for example, there's no instruction to just load a value directly into a segment register, which is why in the code you quoted, the value is first loaded into AX, and then AX is loaded into DS), and can also vary depending on which segment register you're working with.
In general, you would never want to modify CS (the "code segment") register directly, as that would result in immediately changing what code the processor is running (probably in a way you really don't want). The usual way to modify CS is with a "long jump" or "long call" instruction, which will update both CS and IP (the instruction pointer) at the same time. Likewise, SS (the "stack segment") is usually set at the beginning of program execution and never changed (but it technically could be if you had some really compelling reason to do so).
DS and ES are general-purpose data segment registers and it was fairly common for programs to change these however they wanted to best access the memory they wanted to work with (as your example code above demonstrates).
As for the initial values for these registers, those were typically determined by the operating system prior to calling the program's code. Traditionally, in MS-DOS, there were two ways to write programs, as .COM files or as .EXE files. (The ORG 100h line in the code above suggests that it was intended to be run as a COM program.) In the COM case, MS-DOS would initially set all of the segment registers to be the same as CS (that is, they'd all point to wherever DOS had decided to load the program in memory) before invoking the program. The EXE file format was somewhat more sophisticated, and allowed specifying a separate "data segment", in which case the OS would set DS and ES to point to that segment before starting the program instead. In EXE programs, DOS would also typically set up a separate stack segment (SS) for them as well.
The ORG 100h line tells the assembler "assume that the following code will be loaded at address 100h". In real-mode code, addresses such as this are always relative to CS (so the program could actually be loaded many places in memory, as long as CS is set to the correct value to make the code be at 100h relative to CS).
Most addresses for data operations (such as MOV) will be calculated relative to DS by default (for some instructions, you can change that by explicitly specifying a different segment to use, but whether and how you can do that depends on the opcode and the way you're using it). There are, however, a few instructions which are designed to use other segments by default. In summary, it's really best to read the docs for each opcode you want to know about to determine how it uses which segment registers.