2

I've been following a few examples on writing assembly and they use a temporary register to pass an immediate value to a segment register. Why is there a need to place the immediate in some register before putting it in the segment register?
Example:

movw $0x7c00, %ax
movw %ax, %ds
...
...
movw $0x6000, %ax
movw %ax, %ss

Why not instead directly put the immediate in the segment register?

movw $0x7c00, %ds
...
movw $0x6000, %ss
jrhetf4xb
  • 161
  • 3
  • 3
  • 10
  • 2
    Move immediate to a segment register isn't allowed. See http://stackoverflow.com/questions/19074666/8086-why-cant-we-move-an-immediate-data-into-segment-register. – lurker Sep 06 '14 at 16:28
  • The real answer is that instruction-set space is expensive, because there are only so many bits, and every instruction requires transistors to support it. Thus, a CPU designer can't afford to offer every possible useful instruction. So they optimize for activities which are common (by providing "convenient" instructions), and leave out instructions that support activities that occur rarely in terms of code volume or frequency. "Mov immediate to segment" register can obviously be done by using just a few instructions, and is rarely necessary, so this is good enough. You should expect this. – Ira Baxter Sep 06 '14 at 18:01

2 Answers2

5

Because Intel didn't provide the instructions for that (mov seg, [ptr], mov seg, imm16 etc). So you have to. It turned out fine since we don't use segments/selectors much anymore.

But it's not hopeless. There is lea variant instructions with segment which loads segment and offset at once:

les di, [someptr]

(which effectively means: di = [someptr]; es = [someptr+2])

You can also push/pop to avoid register swapping, at the expense of memory access delay of course:

push immediate
pop  es

Many registers are only focused to a purpose and are not interchangable for some operations (bx for offsets, cx for count, dx for higher order of result, ax for results). So it's not that weird in machine code culture to use temporary registers and swap them around.

Sedat Kapanoglu
  • 46,641
  • 25
  • 114
  • 148
1

It's that way because the only instructions that Intel has for getting or setting the segments register are:

  • Get Register -> opcode: 8C /r intruction: MOV r/m16,Sreg Description: Move segment register to r/m16.
  • Set Register -> opcode: 8E /r instruction: MOV Sreg,r/m16 Description: Move r/m16 to segment register.

The only posibility is copying from register or memory access, eg:

MOV DS, AX
# or
MOV DS, WORD PTR [EAX]                   # or any memory addressing like bellow
MOV DS, WORD PTR [EAX + EBX *2 + 0x456]

Intel Instruction Manuals.
Condensed info about assembly instructions x86asm ref.

NetVipeC
  • 4,402
  • 1
  • 17
  • 19