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: 
It's not the `push cs` that ensures this, it's the `push cs; pop ds;` combination that does.

The first instruction copies the current value of `cs` onto the stack, and the second pulls that value off the stack and puts it into the `ds` register.

---

In response to your request for more information, let's start with the following stack and registers:

```
stack=[1,2,3], cs=7, ds=6

```

After `push cs`, which pushes the value of the `cs` register onto the stack:

```
stack=[1,2,3,7], cs=7, ds=6

```

After `pop ds`, which pops a value off the stack and put it into the `ds` register:

```
stack=[1,2,3], cs=7, ds=7

```

And that's basically it.

---

I can't recall of the top of my head whether it was possible to transfer between segment registers with a `mov` instruction (I don't think it was, but I may be wrong, and this would necessitate the push/pop sequence). This [link](http://www.penguin.cz/~literakl/intel/m.html#MOV) would seem to confirm that: there is no `mov` option with a segment register as both source *and* destination.

But even if it were, assembler coders often chose more suitable instructions, either for speed or compact code (or both), things like using `xor ax, ax` instead of `mov ax, 0` for example.
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).