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.
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.