Куда указывает указатель SI, когда он указан для указания смещения? - PullRequest
0 голосов
/ 18 марта 2019

Заранее извиняюсь, если это дублирующий вопрос.Я немного запутался в следующем коде:

list db 80h, 70h, 60h, 50h, 40h, 30h, 20h

       mov si, offset list
       move al,[si] 
repit: inc si
       add al,[si]
       jnc repit
fin:

Я знаю, что jnc означает, что мы выйдем из этого цикла, когда не будет переполнения переноса, то есть CF = 0.Поскольку si должен указывать на индекс первого элемента списка, не будет ли это 80h?И затем, если si увеличивается, оно должно указывать на 70h.После их сложения ответ должен быть F0, верно?Однако, когда я запускаю кусок кода, я получаю значение AL равным 50. Как это возможно?Что мне не хватает?Спасибо всем заранее!

Ответы [ 2 ]

3 голосов
/ 18 марта 2019

Я знаю, что jnc указывает, что мы выйдем из этого цикла, когда не будет переполнения переноса, т. Е. CF = 0.

Это не правильно.JNC будет прыгать, если CF = 0, что означает, что он будет прыгать, если нет беззнакового переполнения .

Поскольку si должен указывать на индекс первогоэлемент списка, не будет ли это 80h?И затем, если si увеличивается, оно должно указывать на 70h.После их сложения ответ должен быть F0, верно?

Пока да.

Однако, когда я запускаю кусок кода, я получаю значение AL равным 50. Как это возможно?
Чего мне не хватает?

Возвращаемое значение 50h равно

80h + 70h + 60h = 50h + CARRY flag (unsigned overflow).

Пошагово это

80h + 70h = F0h    (CF = 0 = JUMP)
F0h + 60h = 50h    (CF = 1 = NO JUMP = EXIT LOOP)

Таким образом, последнее добавление устанавливает флаг CARRY на 1 из-за беззнакового переполнения с FFh до 00h (F0h + 0Fh до F0h + 10h (и, наконец, 60h - 10h = 50h)).Поскольку флаг CARRY установлен, условный переход JNC проходит, а AL содержит «переполненное» значение 50 ч.

1 голос
/ 18 марта 2019

Чтобы ответить на заглавный вопрос (который едва связан с остальной частью вашего вопроса):

Куда указывает указатель SI, когда он указан для указания смещения?

В модели сегментированной памяти x86, почти указатели имеют смещения относительно базы сегмента. mov si, OFFSET symbol устанавливает SI для смещенной части seg:off адреса symbol.

Если symbol является меткой в ​​разделе данных вашей программы, и вы используете [SI], тогда как DS база сегмента = начало этого раздела, тогда [SI] дает вам байт (ы) в symbol как операнд памяти.

SI не указывает на смещение, оно содержит смещение после mov si, OFFSET symbol. Этот является указателем.


В простой плоской модели памяти (например, 32- или 64-битный код) все использует base = 0, поэтому offset = linear address.

В 16-битном коде с «крошечной» моделью памяти (например, .com) CS = DS = ES = SS, поэтому все ссылки на память используют одну и ту же базу. Опять же, только 16-битное смещение работает как полный указатель. Неважно, какова фактическая база сегмента, потому что все относительно нее.

...