Question: I have started to learn assembly. I came across these lines.

```
;*************************************************;
; Second Stage Loader Entry Point
;************************************************;

main:
   cli  ; clear interrupts
   push cs ; Insure DS=CS
   pop ds

```

Here on second line of code, the code segment is push to the stack(I think this). I have seen it in many codes. Why we should do this and how it ensures DS =CS? On third line DS is pop out of stack(I think this). Why it is done? It is pop out of stack means it was push to stack before. There is no code for that. Can anybody explain all this to me? Thanks in advance.

Answer: 
The 'push this register onto stack, pop stack to this register' can sometimes be done with MOV instructions, such as MOV ax,dx. But some register-to-register MOV instructions aren't available in the instruction set, and IIRC MOV ds,cs isn't available. That could be the reason for putting it in memory (well, cache, really) and reading it back.
By pushing the value of CS to the stack, and popping it into DS, you ensure that DS has the same value as CS.

I haven't programmed in assembler for a while, but I thought there was no direct way to move from one segment register into another.

You can see the stack as a pile of data. You push something on top and it stays there until you pop it of\ the pile. In that way you can use the stack to exchange data. But most of the time you use it to save data so you can use the registers for other purposes and restore the content later.

This happens when you execute the code.

1) initial situation

```
CS has value X
DS has value Y
Stack has ....

```

2) push CS

```
CS has value X
DS has value Y
Stack has ...., X

```

3) pop DS

```
CS has value X
DS has value X
Stack has ....

```

But what are segment registers.
In the old days, 8086 had 16 bit address registers but a 20 bit addressspace. So they used the segment registers to combine both to a 20 bit space by multiplying the segment register by 16, and add the memory location. To save space, we had near pointers (without segment to jump within the segment) and far pointers (with segment).

With the introduction to 80286 protected mode, the segment registers were reused as segment descriptors. They pointed to a memory location that gave enough information to get to the real space. But now we have linear address spaces (virtually mapped on the real memory).