непосредственные (квадратные скобки) и индексные регистры + файлы с 2x dw в сегменте стека

Я очень новичок в ассемблере и пытаюсь изучить его, разбираясь в дизассемблировании старой 16-битной игры для DOS (дизассемблирование, сгенерированное IDA Free).

В этом коде я прочитал две вещи и, думаю, догадался, что он делает. Тем не менее, я не совсем уверен, прав ли я, поэтому я хотел проверить (просто сократил код примера здесь, кстати):

1)

lds di, some_adress ; (eg: ds = 0012h, di=BAF6h afterwards)
xor cx, cx
mov [di], cx ; <- what segment is used here

Я предполагаю, что он использует ds как какой-то волшебный сегмент по умолчанию, чтобы применить смещение и вычислить физический адрес.

2)

assume ds:dseg (e.g. 0012h)
mov ax, 0BAF6h ; <- why is the leading 0 here btw
push ds
push ax

поэтому мой стек выглядит так:

...  ...
02   ds (0012)
00   ax (BAF6)  <- sp

тогда:

mox bx, sp
les di, ss:[bx]

Я предполагаю, что регистры теперь es=0012h и di=BAF6h, что имело бы смысл при рассмотрении остального кода игры, но поскольку мой стек выглядит как BAF6 0012 ..., это будет означать, что первое слово помещается в di, а второе слово помещается в es. Это меня немного смущает, так как это своего рода обратный порядок двух слов (с моей точки зрения).


person cdx    schedule 14.03.2013    source источник
comment
Вы можете загрузить руководства Intel, чтобы вам не пришлось гадать. Что касается порядка байтов, x86 имеет прямой порядок следования байтов, поэтому более низкие адреса имеют менее значимые части. Вот почему первое слово загружается в di, а второе — в es (обратите внимание, что байты слов также хранятся в порядке с прямым порядком байтов).   -  person Jester    schedule 14.03.2013
comment
иногда самые простые вещи просто не приходят в голову, спасибо за подсказку   -  person cdx    schedule 15.03.2013


Ответы (1)


  1. ds — это сегмент по умолчанию для всех остальных 16-битных режимов адресации памяти, кроме [bp+immediate], [bp+si+immediate] и [bp+di+immediate]. Таким образом, в основном, если вы не используете bp в косвенной адресации, сегмент по умолчанию — ds. Если вы используете bp в косвенной адресации, то сегмент по умолчанию — ss.

  2. Начальный ноль в шестнадцатеричных числах — это соглашение, используемое многими синтаксисами дизассемблеров и ассемблеров для отделения шестнадцатеричных чисел от символов (некоторые другие дизассемблеры и ассемблеры используют 0x вместо 0). Ведущие нули не влияют на числовое значение любого числа и одинаково во всех системах счисления (двоичной, десятичной, шестнадцатеричной и т. д.).

Как вы и предполагали, lesdi, ss:[bx] загружает первое слово в di и второе слово в es, так что это эквивалентно:

mov di,ss:[bx]
mov es,ss:[bx+2]
person nrz    schedule 14.03.2013
comment
Ведущий ноль служит для того, чтобы отличать числа от символов. BAF6h будет именем символа. - person Jester; 14.03.2013
comment
@Jester Ты прав, конечно. Я настолько привык к 0x соглашению, используемому YASM, NASM, NDISASM и udis86, что забыл значение ведущих нулей. - person nrz; 14.03.2013
comment
Большое спасибо за быстрый ответ и ресурсы. меня просто смутил ноль, так как он не всегда присутствует в дизассемблированном коде. иногда это просто mov ax, 3D00h без нуля - person cdx; 15.03.2013
comment
@cdx В случае, если шестнадцатеричное число начинается со значения в диапазоне 0 ... 9, нет необходимости ставить перед ним префикс 0, чтобы отличить его от символов, потому что имена символов не могут начинаться с 0 ... 9, но они могут начинаться с a ... f и A ... F. - person nrz; 15.03.2013