Здравствуйте, Alex16,
A>>>Ошибка компилятора: **Error** comex.asm(8) CS unreachable from current segment ГМ>>-- ГМ>>См. здесь и далее ищите описание этой ошибки.
A>Прочитал. Но меня интересует не ее описание, а вопрос: вообще, какой смысл в этой директиве в этом месте? Почему у режиме masm код вдруг не компилируется??
--
Наверное потому, что "in MASM mode, the value that the CS register isASSUMEd to be is used to determine the segment or group a label belongs to. Thus, the CS register must be correctly specified in anASSUME directive..."
Здравствуйте, Alex16, Вы писали:
A>Com программа всегда начинает выполняться со смещения 100h. То что она com указано в модели памяти.
Нет. Что она com — указано опцией линкера /t. Один и тот же объектник может быть слинкован как в com, так и в exe.
Модель памяти всего лишь указывает на способ адресации. Для модели tiny: код near и данные near.
A>Вопрос остается открытым: почему кусок который привел я, не работает без нее
Потому что компилятор на момент компиляции не знает, что это будет com-программа с единственным сегментом кода.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, ДимДимыч, Вы писали:
ДД>Здравствуйте, Alex16, Вы писали:
A>>Com программа всегда начинает выполняться со смещения 100h. То что она com указано в модели памяти.
ДД>Нет. Что она com — указано опцией линкера /t. Один и тот же объектник может быть слинкован как в com, так и в exe. ДД>Модель памяти всего лишь указывает на способ адресации. Для модели tiny: код near и данные near.
Согласен, компилируется и так и так.
A>>Вопрос остается открытым: почему кусок который привел я, не работает без нее
ДД>Потому что компилятор на момент компиляции не знает, что это будет com-программа с единственным сегментом кода.
А зачем ему такая информация? Ему недостаточно видеть, где начинается и заканчивается сегмент в программе?
Послушайте, если у нас выполняется код какого то сегмента, то очевидно, что CS = адресу сегмента!
Здравствуйте, Геннадий Майко, Вы писали:
ГМ>Здравствуйте, Alex16,
A>>>>Ошибка компилятора: **Error** comex.asm(8) CS unreachable from current segment ГМ>>>-- ГМ>>>См. здесь и далее ищите описание этой ошибки.
A>>Прочитал. Но меня интересует не ее описание, а вопрос: вообще, какой смысл в этой директиве в этом месте? Почему у режиме masm код вдруг не компилируется?? ГМ>-- ГМ>Наверное потому, что "in MASM mode, the value that the CS register isASSUMEd to be is used to determine the segment or group a label belongs to. Thus, the CS register must be correctly specified in anASSUME directive..."
Вы как сами считаете, то что при выполнении кода CS = адресу сегмента кода, это неочевидно? Вы как считаете, компилятор без нее смог бы скомпилировать?
A>>Прочитал. Но меня интересует не ее описание, а вопрос: вообще, какой смысл в этой директиве в этом месте? П
Здравствуйте, Alex16,
A>>>>>Ошибка компилятора: **Error** comex.asm(8) CS unreachable from current segment ГМ>>>>-- ГМ>>>>См. здесь и далее ищите описание этой ошибки.
A>>>Прочитал. Но меня интересует не ее описание, а вопрос: вообще, какой смысл в этой директиве в этом месте? Почему у режиме masm код вдруг не компилируется?? ГМ>>-- ГМ>>Наверное потому, что "in MASM mode, the value that the CS register isASSUMEd to be is used to determine the segment or group a label belongs to. Thus, the CS register must be correctly specified in anASSUME directive..."
A>Вы как сами считаете, то что при выполнении кода CS = адресу сегмента кода, это неочевидно? Вы как считаете, компилятор без нее смог бы скомпилировать?
--
Увы, я не разрабатывал masm и поэтому не могу ответить на вопрос, почему появилась необходимость в директиве ASSUME в данном месте. У меня есть кое-какие спекуляции по этому поводу, но я в них не уверен и поэтому лучше промолчу. Для меня достаточно, что в документации об этом явно написано.
Но похоже, что я не очень понимаю, что Вас таки беспокоит...
Здравствуйте, Alex16,
A>>Вы как сами считаете, то что при выполнении кода CS = адресу сегмента кода, это неочевидно? Вы как считаете, компилятор без нее смог бы скомпилировать? ГМ>-- ГМ>Увы, я не разрабатывал masm и поэтому не могу ответить на вопрос, почему появилась необходимость в директиве ASSUME в данном месте. У меня есть кое-какие спекуляции по этому поводу, но я в них не уверен и поэтому лучше промолчу. Для меня достаточно, что в документации об этом явно написано.
--
И вдогонку (хотя это по прежнему не отвечает на Ваши вопросы): "MASM 6.1 automatically gives CS the address of the current code segment. Therefore, you do not need to include ASSUME CS : MY_CODE at the beginning of your program if you want the current segment associated with CS."
C уважением,
Геннадий Майко.
Re[8]: Assume
От:
Аноним
Дата:
07.07.11 21:13
Оценка:
Здравствуйте, Геннадий Майко, Вы писали:
ГМ>Но похоже, что я не очень понимаю, что Вас таки беспокоит...
Он не понимает почему обязательно надо указывать чему будет равен CS. Типа вроде и так ясно. Я ему говорил, что нифига не ясно. CS в принципе может быть любым. И дело не в том, что это якобы возможно только для EXE. Просто ИМХО он не понимает, что COM это не обязательно программа, это может быть например кусок в БИОСе по фиксированному адресу. Но он ну никак этого понять не может. ИМХО это из за того, что он никогда не писал ничего для железа, например в виде того что будет прошито в ПЗУ. Ну и как ему тогда можно объяснить зачем нужно указывать чему равен CS. А вообще у тасма кажется есть просто такой ключ, не помню уже точно — но звучит как "дикости MASM". Ну и вообще MASM весьма не прост. Там все не так уж очевидно. И подчас действительно странно. Но это оправданно. Время тогда такое было.
Здравствуйте, Alex16, Вы писали:
A>Я уже писал, что я прекрасно понимаю, что assume облегчает нам работу, и вот то что вы написали, автоматический подбор сегментного регистра. A>Но мой вопрос заключается в другом: вот я привел кусок com программы. Тут нам от этой директивы пользы как от козла молока.Однако если я не напишу ASSUME CS:CODE прога не скомпилируется! Так почему же она не работает?
Вполне может быть простым маленьким недостатком транслятора, без особого смысла . Не стали усложнять и делать assume опциональным для com-файлов (как и как-то особенно менять синтаксис). FASM, к примеру, не требует подобного, если говорить о com-файлах. ЕМНИП, он по-особому обрабатывает "org 100h", встреченную в начале листинга (для других форматов у него более явные ключевые слова).
Здравствуйте, Alexey F, Вы писали:
AF>Вполне может быть простым маленьким недостатком транслятора, без особого смысла . Не стали усложнять и делать assume опциональным для com-файлов (как и как-то особенно менять синтаксис). FASM, к примеру, не требует подобного, если говорить о com-файлах. ЕМНИП, он по-особому обрабатывает "org 100h", встреченную в начале листинга (для других форматов у него более явные ключевые слова).
В том-то и дело, что TASM на этапе компиляции не знает, будет ли это COM или EXE.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, Alex16, Вы писали:
A>А зачем ему такая информация? Ему недостаточно видеть, где начинается и заканчивается сегмент в программе? A>Послушайте, если у нас выполняется код какого то сегмента, то очевидно, что CS = адресу сегмента!
Компилятор не знает, будет ли еще какой-нибудь код, и будет ли он ссылаться на текущий сегмент. Assume нужна для определения сегментов меток (символов), если к ним будут обращения из других сегментов.
Сегмент кода без меток компилируется и без assume.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, ДимДимыч, Вы писали:
AF>>Вполне может быть простым маленьким недостатком транслятора, без особого смысла . Не стали усложнять и делать assume опциональным для com-файлов (как и как-то особенно менять синтаксис). FASM, к примеру, не требует подобного, если говорить о com-файлах. ЕМНИП, он по-особому обрабатывает "org 100h", встреченную в начале листинга (для других форматов у него более явные ключевые слова).
ДД>В том-то и дело, что TASM на этапе компиляции не знает, будет ли это COM или EXE.
И я о том же — не стали переусложнять и вводить специальные случаи, которые потом будет разруливать линкер из-за одной директивы. Это FASM'му можно — он сам себе и компилятор, и линкер.
Re: Assume
От:
Аноним
Дата:
08.07.11 22:24
Оценка:
Через эту директиву удобно описывать ссылки. Например есть структура MYSTRUCT. Можно обращаться к ней по непосредственно указанным смещениям, тоесть mov eax,MYSTRUCT.Field[ebx], но при большом числе обращений это не удобно. Можно определить ссылку assume ebx:ptr MYSTRUCT и обращаться к структуре через эту ссылку, например mov eax,[ebx].Field
А>>Лдним словом это директива как считать смешение для адреса. A>Я уже писал, что я прекрасно понимаю, что assume облегчает нам работу, и вот то что вы написали, автоматический подбор сегментного регистра.
Аноним 733 сказал правильно но, возможно, и не совсем разжевал чтобы полностью дошло. Я тоже попробую чуть ниже но, чур, ногами не бить. Давно не программировал на ассемблере.
A>Но мой вопрос заключается в другом: вот я привел кусок com программы. Тут нам от этой директивы пользы как от козла молока.Однако если я не напишу ASSUME CS:CODE прога не скомпилируется! Так почему же она не работает?
Это не совсем удачный пример для того чтобы понять что делает assume. Можно я приведу другой пример для простоты?
Итак. Допустим ты пишешь exe. У тебя есть сегмент данных с несколькими переменными. Всякий раз когда ты пишешь инструкцию
mov ax, variable
она транслируется в опкод который неявно задействует регистр ds.
Теперь, допустим ты хочешь адресовать все переменные относительно регистра es. Если ты напишешь вначале программы что-то вроде assume es:data, то вышеназванная инструкция будет транслироваться в инструкцию
mov ax, es:variable
В машинном коде это будет транслироваться в один дополнительный байт перед самим mov-ом который будет говорить процессору что нужно задействовать регистр es для адресации переменной которую нужно положить в ax.
Поэтому вначале программы ты задаешь значения сегментым регистрам вручную, а assume говорит ассемблеру как генерировать машинный код при адресации переменных. На всякий случай напомню что assume — директива ассемблеру.
Вообще это называется red tape и ассемблер генерирует немного другой код "behind your back." В А86, к примеру, этого нету и ты можешь писать только машинные инструкции.
Ну и относительно твоего примера. Предполагаю что ассемблер просто не знает какой опкод генерировать для джампа, то есть смещение-то ему ясно, а вот в каком сегментном регистре находится сам сегмент он не знает. Добавив assume ты говоришь ему как генерировать машинный код (какой сегментный регистр). Ну или явно указав регистр в джампе. Например jmp far ptr es:main.
Вообще посиди с отладчиком и посмотри как генерируются эти mov-ы и jmp-ы.