views:

61

answers:

3

I have the next code:

mov  ax,@data
mov  ds,ax

Why I can not write just like this?

mov ds,@data

All source:

   .MODEL small
   .STACK 100h
   .DATA
   HelloMessage DB 'Hello, world',13,10,'$'
   .CODE 
   .startup
   mov  ax,@data
   mov  ds,ax
   mov  ah,9
   mov  dx,OFFSET HelloMessage
   int  21h
   mov  ah,4ch
   int  21h
   END

Thank you!

A: 

I'm no expert but this is how I understand this constraint to work.

The Segment registers are used to control which segment of memory is used by the register instructions, as such the last thing you want is to load a segment register (DS in this case which is the Data Segment register) from a memory location. The act of modifying DS could cause the memory location being read to change during the process of updating DS, i.e. the first bits/byte loaded into DS now cause it to be pointing to another segment before the remainder has been read. It's safer to read the value into the Accumulator (AX) or another general purpose register, so now the value is in the processor when it's loaded into the segment register, so no chance of the value getting corrupted during the load.

Lazarus
I don't think that's the reason, as DS could easily be updated after the complete value has been read.
starblue
If this was the explanation, there would be no instruction such as `mul ax`, because `ax` might be "corrupted" as it is being multiplied.
Pascal Cuoq
@starblue, it could easily be updated in that way if the processor has location into which to read the value before loading it into DS (say `mov ax,@Data` then `mov ds,ax`) however efficiencies in design might just have the value being loaded directing into the register. I'm not saying I'm definitely right, I am saying that it's not implausible.
Lazarus
@Pascal Cuoq : While I don't disagree that my explanation may be wrong, I do disagree with your validation. `mul ax` is executed entirely within the processor, no memory is being accessed through a segment register. After all AX is the accumulator and designed to do the dog work, it's more than likely that any special cases would be applied to this register over and above any other.
Lazarus
@Lazarus I was going to use the more technical explanation that the modern processors has tens of versions of the same register existing at the same instant and that "the version before the instruction" and "the version after the instruction" does not seem something that should scare the designers, but that would still be slightly wrong, because the instruction set was designed before out-of-order execution. In truth, your answer is so far from the actual way processor function it is hard to refute.
Pascal Cuoq
@Pascal Cuoq : I'm not actually trying to be difficult here, I'm trying to get to the actual answer, which your comments would indicate you have. You admit that the instruction set was designed before out-of-order execution but then state that my answer is completely wrong. I could accept that this was just an arbitrary decision based on available instruction size but as you point out elsewhere, the MOV DS is a different instruction to MOV AX so why not allow a memory location when the pairing is so very, very common?
Lazarus
I suspect we'll never get to the truth in this. I accept my answer is pure speculation even with a background in working with hardware ICEs, too far back in time and memory :)
Lazarus
8086 has been 16 bit from the start in the seventies, so it is designed to access memory in words of 16 bits http://en.wikipedia.org/wiki/8086#Details . The 8 bit 8088 came later, and it would have to respect the logical view of accessing 16 bit as a whole.
starblue
That's really good point @starblue. It does still seem odd that if it is just an arbitrary decision to drop an instruction, why that one when it would be so commonly used.
Lazarus
+4  A: 

You can't, because the instruction set doesn't contain an instruction to do that. It is just one of the many idiosyncrasies of the x86.

These kind of restrictions are fairly normal for assembly languages. Most architectures contain some registers that are treated specially (for example the processor status word), though usually fewer than the x86 architecture.

The reason to not provide an instruction for all possible moves is to reduce the size of the instruction set, so that an instruction takes less memory. Overall it is more efficient to do moves that are rarely needed in two steps.

starblue
+1 You could also say that the reason for not being able to modify `ds` with one of the standard `mov` instructions is that only 3 bits are reserved to encode the destination register in most instructions, and that ax,bx,cx,dx,si,di,sp,bp already use all the available possibilities. But that would be simplifying things a bit.
Pascal Cuoq
Yes, that's the concrete design decision to keep the instructions small.
starblue
In that case where does `mov ds,ax` come into it? I'm pretty sure that's a `mov` with `ds` as the destination register ;) You've a sound argument and I'm just playing!
Lazarus
@Lazarus `mov ds,...` is **not** a `mov` with a `ds` as destination register. It is a convenient notation for a different instruction. See http://pdos.csail.mit.edu/6.828/2004/readings/i386/MOV.htm
Pascal Cuoq
@Pascal Cuoq : And as I said, your argument was sound and I was playing... or did you reach your branch into rant before you got to that part of the sentence or did you just choose to ignore it.
Lazarus
+1  A: 

General purpose register as the 'ax' is designed to hold the 16 bit number pointing to the data (in your case the string inside the DATA)

So if you try to directly pass the data to the special register (ds or data segment here) it will not work correctly as it does not know to accept data that way. So we first get that 'number' or the point in memory location where data starts & pass that point to ds register.

loxxy