Вопрос № 27898: Всем добрый день! Уважаемые эксперты, по ходу просвящения ассемблером в одной из книжек увидел я следующий пример адрессации:
см. ниже
так вот, штука такая:
1- массив из байтов, а пишем мы туда слово из 'ax' . Не знаю как это понимать.<br...
Вопрос № 27.898
Всем добрый день! Уважаемые эксперты, по ходу просвящения ассемблером в одной из книжек увидел я следующий пример адрессации:
см. ниже
так вот, штука такая:
1- массив из байтов, а пишем мы туда слово из 'ax' . Не знаю как это понимать.
2- и собственно как транслятор догадывается что после инкремента [si]
мы передвинемся именно на байт, а не на 2 а то и 3 или 4. Может это связано каким-то образом с обявлением массива? например сделай я его массивом слов так сразу после инкремента [si] переходил бы на 2 байта вперед в памяти?
Отвечает: Евгений Иванов
Здравствуйте, Solodov Evgeniy Vladimirovich!
Это значит, что слова будут перекрываться.
Здесь идёт индексная адресация.
SI работает в качестве индекса.
BX - база.
Здесь именно алгоритм такой, что нужно байты перемешивать ,)
слово - 2 байта.
байт - 8 бит.
--------- Что имеем - не храним, потерявши - плачем
Ответ отправил: Евгений Иванов (статус: Профессор)
Отправлен: 18.10.2005, 17:41 Оценка за ответ: 4 Комментарий оценки: спасибо за ответ. с первым вопросом теперь все ясно.:-)
Отвечает: Лысков Игорь Витальевич
Здравствуйте, Solodov Evgeniy Vladimirovich!
1. Понимать следует так: пишем два байта по адресу DS:[BX+SI]. После чего сдвигаем адрес на один байт и опять пишем два байта. Дело в том, что, когда мы загрузили в BX адрес массива, то для компилятора и процессора этот адрес сразу же обезличился - превратился в адрес некой ячейки памяти. Разумеется, корректно было бы сказать mov [bx][si],al. Для проверки правильности при ассемблтровании можно использовать форму mov array[si],al. Если указать AX, то в этом случае ассемблер выдаст сообщение о несоответствии
типов.
2. Ты ж сам пишешь - inc si :) - вот твоя программа и инкрементирует на один
С объявлением массива это никак не связано.
--------- Удачи!
Ответ отправил: Лысков Игорь Витальевич (статус: 5-ый класс)
Отправлен: 18.10.2005, 18:12 Оценка за ответ: 5 Комментарий оценки: Спасибо за ответ.
1. Мы нигде не определяем массив из байтов. В том-то и отличие ассемблера от языков высокого уровня, что в нем нет структур данных! Все структуры реализуются вручную, а ассемблер только предоставляет возможность адресоваться к любому байту памяти.
Поэтому объявление array db 256 dup (0) не определяет массив из 256 байт. Это объявление только резервирует область из 256 байт, заполненную нулями, и присваивает имя array первой ячейке этой области.
А как ты будешь обращаться к этой области - побайтно, пословно, двойными словами, через адресацию через array или игнорируя это имя, с начала, с конца, с середины - это исключительно проблема программиста.
А пишем мы в эту область слово ax. al при этом помещается в ячейку [bx][si], а ah - в ячейку [bx][si+1].
2. Транслятор ни до чего не догадывается. Кстати, процессор тоже. Если написано inc si, то будет выполнена операция увеличения значения регистра si на 1. И всем глубоко наплевать, как резервировалась (и резервировалась ли вообще) память, на которую указывает si. Кстати, значение si вообще может не иметь никакого отношения к указателю на память, а просто быть числом.
Единственные команды, при выполнении которых регистры si и di изменяет свое значение в зависимости от размера операнда, это строковые: lods, movs, stos, cmos и scas.
Так что, если бы ты сделал массив слов и адресовался бы через si, то тогда ты должен был бы сам изменять значение регистра si на 2: add si, 2 или 2 инкремента.
Кстати, запись inc [si] - это изменение значения по адресу, содержащемуся в регистре si. Так что в своем вопросе ты зря писал si в квадратных скобках.
--------- Трудное - то, что можно сделать немедленно. Невозможное - то, для выполнения чего требуется немного больше времени
Ответ отправил: Ayl (статус: Профессор)
Отправлен: 18.10.2005, 18:15 Оценка за ответ: 5 Комментарий оценки: Спасибо за ответ.
1. Почему в массив записывается слово, а инкремент увеличивается на 1 (байт), не знаю наверно ошибка.
Должно быть так:
mov [bx][si], al - одно и тоже, что и mov [bx+si], al
2. "собственно как транслятор догадывается что после инкремента [si]
мы передвинемся именно на байт, а не на 2 а то и 3 или 4." оч просто, ты сам указываешь на сколько увеличивать инкремент и сам определяешь размерность данных:
inc si - + 1 байт
add si, 2 - + 2 байта
и т.д.
есть ещё вариант адресации
mov [bx+si*x], y - где х размер элемента массива в байтах, у - должен соответствовать размерности х (в твоем случае)
Как пример смотри приложение - работа с массивом размерностью в слово
Приложение:
Ответ отправил: Хузин Макс (статус: 1-ый класс)
Отправлен: 19.10.2005, 08:35 Оценка за ответ: 5 Комментарий оценки: Спасибо за ответ.