Что означает двоеточие: в синтаксисе GAS для сборки x86, как в% ds: (% bx)?

Я новичок в сборке x86, и я пытаюсь понять код в этом документе: http://www.cs.cmu.edu/~410-s07/p4/p4-boot.pdf страница 3:

movw $0x1234, %ax
movw %ax, %ds
movw $0x5678, %bx
# The following instruction is the same as "movw $0x1337, (%bx)".
movw $0x1337, %ds:(%bx) # Places 0x1337 into memory word 0x179b8.
# Segment Base: %ds << 4: 12340
# Offset: %bx: + 5678
# -------
# Linear Address: 179b8

Но я не понимаю команду:

movw $0x1337, %ds:(%bx) # Places 0x1337 into memory word 0x179b8.

Почему конкатенация% ds с (% bx) совпадает с ((% ds < 4) |% bx)?

Поскольку я в реальном режиме (16 бит), конкатенация не должна быть% ds < < 8? вместо% ds < 4

И почему скобки всего около% bx? И не вокруг всей структуры вроде: movw $0x1337, (% ds:% bx)?

Ответ 1

В реальном режиме регистр сегмента используется для предоставления 20-битного адреса. В этом случае регистр сегмента данных ds предоставляет "высокие" 16 бит адреса: (0x1234 < 4 = 0x12340), а смещение в сегменте задано: 0x5678, чтобы получить: 0x179b8.

Регистр сегмента данных неявный, поэтому нет необходимости использовать: ds:(%bx). Если вы использовали другой регистр сегмента, например es, он должен быть явным.

Надеюсь, я понял ваш вопрос. Что касается того, почему это не написано как (%ds:%bx), это действительно просто синтаксическое решение, за которое вы застряли.