Здравствуйте!
У меня вопрос: никак не могу понять, зачем в принципе нужна директива Assume в ассемблерах. Везде к книжках пишут, что мол эта директива дает знать ассемблеру о том, какие сегменты нашей программы в каких сегментных регистрах будут. Но это все не ответ.
Я не много разобрался в том, как выглядят com и exe программы в машинных кодах, как правятся адреса сегментов с помощью таблицы замены в ехе программах, как устанавливаются значения сегментных регистров загрузчиком, и хочу сказать, что я так и не понимаю, что с этой директивой делает компилятор и линковщик. В чем ее смысл.
В com программах все сегментные регистры устанавливаются на начало psp. Мы в ней работаем только со смещениями! Зачем ассеблеру нужно знать что там у нас в сегментых регистрах? )
Вопрос к тем, кто знает машинные коды)) Приведите пожалуйста пример с директивой assume и покажите что без нее линковщик ну ни как не сможет слинковать программу ) Не то что там, ему будет тяжело, а просто не сможет)
Потому что у меня простая com программа требует чтобы я обязательно задал assume cs:CSEG. Без этого видите ли не компилируется)
Здравствуйте, Alex16, Вы писали:
A>Вопрос к тем, кто знает машинные коды)) Приведите пожалуйста пример с директивой assume и покажите что без нее линковщик ну ни как не сможет слинковать программу ) Не то что там, ему будет тяжело, а просто не сможет)
ЕМНИП assume нужна в том случае, когда в программе несколько сегментов данных (и/или кода). Тогда понижается вероятность ошибки, что мы загрузим в ds один сегмент данных, и попробуем обратиться к переменной в другом сегменте.
A>Потому что у меня простая com программа требует чтобы я обязательно задал assume cs:CSEG. Без этого видите ли не компилируется)
Что за ассемблер? Насколько помню, TASM никогда не требовал assume для com-файлов. Может нужно указать модель памяти tiny?
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Здравствуйте, ДимДимыч, Вы писали:
ДД>Что за ассемблер? Насколько помню, TASM никогда не требовал assume для com-файлов. Может нужно указать модель памяти tiny?
Ассемблер tasm. Про то, что директива может нам помочь — наверно. Но я не понимаю, почему вот такой код на тасме не работает:
.model tiny
.186
code segment
;ASSUME CS:CODE
org 100h
main:
mov BX, 00H
;jmp far ptr main
mov ax, 4c00h
int 21h
code ends
end main
Ошибка компилятора: **Error** comex.asm(8) CS unreachable from current segment
если строчку c assume расскоментировать, то все работает
Здравствуйте, Alex16, Вы писали:
A>Ошибка компилятора: **Error** comex.asm(8) CS unreachable from current segment A>если строчку c assume расскоментировать, то все работает
Директива code segment всего-лишь объявляет некий сегмент с именем "code". Компилятор не знает, куда нужно помещать скомпилированный код.
Для com-файлов в TASM я использовал такие объявления, без определения отдельных сегментов:
.model tiny
.186
.code
org 100h
.startup
...
end
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re: Assume
От:
Аноним
Дата:
07.07.11 15:32
Оценка:
Здравствуйте, Alex16, Вы писали:
A>У меня вопрос: никак не могу понять, зачем в принципе нужна директива Assume в ассемблерах.
Как это слово переводится?
Если вдруг не знаешь, то это переводится как "считать" или "предполагать". То есть она говорит — далее считать "такой-то сегрег" равным тому-то.
И там где ты явно не напишешь префикс переопределения сегмента при обращении к данным например, будет считаться что используется DS. А так как ты в ассемблере можешь использовать имена переменных, то смешение относительно сегмента в команде будет вычисляться ассемблером. Например одна и так же переменная может быть в разных сегментах программы. Если их несколько. При загрузке программы сегментные регистры настраиваются. И соответственно чтобы адресация была правильная нужно казать в чему считать равным значение сегментного регистра. То есть память в программе идет подряд, а вот сегментные регистры могут быть настроенные по разному. И ты например можешь адресовать одну и ту же ячейку памяти от CS: скажем 200 и от DS: скажем 100.
И например если ты настроил ES через Assume на некий сегмент SSS и в нем есть переменная YYY то если ты обратишься к ней то, автоматически подставится префикс замены сегмента с DS на ES. То есть можно считать что ком программы адресуются от CS и все сегментные регистры смотрят туда же. То например в случае с EXE уже можно взять одно смещение от CS и другое от DS или вообще от ES или SS. То есть проще понимать эту директиву как далее считать что ХХХ сег. регистре равен офсету начала сегмента от начала программы деленному на 16.
Лдним словом это директива как считать смешение для адреса.
Здравствуйте, ДимДимыч, Вы писали:
ДД>Директива code segment всего-лишь объявляет некий сегмент с именем "code". Компилятор не знает, куда нужно помещать скомпилированный код.
Нет. Не согласен. Com программа всегда начинает выполняться со смещения 100h. То что она com указано в модели памяти. Ничего компилятору больше не надо. Загрузчик всегда грузит программу после psp, то есть со смещением 100h. Так что, все мы знаем, где она окажется.
ДД>Для com-файлов в TASM я использовал такие объявления, без определения отдельных сегментов: ДД>
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Alex16, Вы писали:
A>>У меня вопрос: никак не могу понять, зачем в принципе нужна директива Assume в ассемблерах.
А>Как это слово переводится? А>Если вдруг не знаешь, то это переводится как "считать" или "предполагать". То есть она говорит — далее считать "такой-то сегрег" равным тому-то. А>И там где ты явно не напишешь префикс переопределения сегмента при обращении к данным например, будет считаться что используется DS. А так как ты в ассемблере можешь использовать имена переменных, то смешение относительно сегмента в команде будет вычисляться ассемблером. Например одна и так же переменная может быть в разных сегментах программы. Если их несколько. При загрузке программы сегментные регистры настраиваются. И соответственно чтобы адресация была правильная нужно казать в чему считать равным значение сегментного регистра. То есть память в программе идет подряд, а вот сегментные регистры могут быть настроенные по разному. И ты например можешь адресовать одну и ту же ячейку памяти от CS: скажем 200 и от DS: скажем 100.
А>И например если ты настроил ES через Assume на некий сегмент SSS и в нем есть переменная YYY то если ты обратишься к ней то, автоматически подставится префикс замены сегмента с DS на ES. То есть можно считать что ком программы адресуются от CS и все сегментные регистры смотрят туда же. То например в случае с EXE уже можно взять одно смещение от CS и другое от DS или вообще от ES или SS. То есть проще понимать эту директиву как далее считать что ХХХ сег. регистре равен офсету начала сегмента от начала программы деленному на 16.
А>Лдним словом это директива как считать смешение для адреса.
Я уже писал, что я прекрасно понимаю, что assume облегчает нам работу, и вот то что вы написали, автоматический подбор сегментного регистра.
Но мой вопрос заключается в другом: вот я привел кусок com программы. Тут нам от этой директивы пользы как от козла молока.Однако если я не напишу ASSUME CS:CODE прога не скомпилируется! Так почему же она не работает?
Re[5]: Assume
От:
Аноним
Дата:
07.07.11 18:02
Оценка:
Здравствуйте, Alex16, Вы писали:
A>Здравствуйте, ДимДимыч, Вы писали:
ДД>>Директива code segment всего-лишь объявляет некий сегмент с именем "code". Компилятор не знает, куда нужно помещать скомпилированный код.
A>Нет. Не согласен. Com программа всегда начинает выполняться со смещения 100h. То что она com указано в модели памяти. Ничего компилятору больше не надо. Загрузчик всегда грузит программу после psp, то есть со смещением 100h. Так что, все мы знаем, где она окажется.
Сосем не обязательно. Можно хоть с 200.
A>Вопрос остается открытым: почему кусок который привел я, не работает без нее
Я же вроде как уже обьяснил почему.
Но если все еще не понятно, то в ДОСе программы не перемещаемые. И можно например написать COM программу которая будет работать при CS равным конкретной величине. Например 7800 и при этом код будет начинаться со 100 от PSP.
Вообще я не очень понимаю, нафига тебе все эти знания? Раньше было трудно программировать. Зачем сейчас-то мучиться.
Ребят, ну я не просто так спрашиваю, у меня возник вопрос потому что я пописал разные com программы, посмотрел как это выглядит в obj файле, посмотрел, что делает компилятор что линковщик. Как каждая команда переводится в коды. И когда мне стало совсем ясно, как загрузчик запускает com программу на выполнение, т.е. у него для этого все данные есть, встал вопрос: зачем здесь эта директива, если и без нее все уже определено? Почему без нее не работает?
Re[5]: Assume
От:
Аноним
Дата:
07.07.11 18:09
Оценка:
Здравствуйте, Alex16, Вы писали:
A>Здравствуйте, ДимДимыч
A>Ребят, ну я не просто так спрашиваю, у меня возник вопрос потому что я пописал разные com программы, посмотрел как это выглядит в obj файле, посмотрел, что делает компилятор что линковщик. Как каждая команда переводится в коды. И когда мне стало совсем ясно, как загрузчик запускает com программу на выполнение, т.е. у него для этого все данные есть, встал вопрос: зачем здесь эта директива, если и без нее все уже определено? Почему без нее не работает?
Неверно ты понял. Можно написать программу и она будет работать про CS равным ЛЮБОЙ величине. Например 7800 то есть компилятор зная какой будет CS все офсеты пересчитает. Вообщем кури не про COM а про BIN.
Раньше было трудно программировать, теперь то зачем голову на этот изламывать. Считай что это такое программирование в фиксированных адресах. А ого тебе надо?
Здравствуйте, Аноним, Вы писали:
А>Сосем не обязательно. Можно хоть с 200.
Неа.. когда мы пишем org 100h, компилятор просто проверяет эту строчку и без нее линковщик не слинкует. Пометки, что у нас вот там в начале есть 100h байт нулевых в com программе нигде нет. Соотвественно написать org 200h не можем.
Error: Cannot generate COM file : invalid initial entry point addres
А>Я же вроде как уже обьяснил почему.
Нет, вы не объяснили. Вы только сказали, что эта директива полезна. Их ваших слов я понял что без нее можно обойтись. Но я привел кусок кода, в котором обойтись не выходит. Я попросил объяснить зачем она там нужна. Ответа не получил.
А>Но если все еще не понятно, то в ДОСе программы не перемещаемые. И можно например написать COM программу которая будет работать при CS равным конкретной величине. Например 7800 и при этом код будет начинаться со 100 от PSP.
Я ничего не понял насчет неперемещаемости. Программа будет загружена туда, где есть свободное место.
Приведите пример.
Здравствуйте, Alex16,
A>Ассемблер tasm. Про то, что директива может нам помочь — наверно. Но я не понимаю, почему вот такой код на тасме не работает:
A>
A>.model tiny
A>.186
A>code segment
A>;ASSUME CS:CODE
A>org 100h
A>main:
A> mov BX, 00H
A> ;jmp far ptr main
A> mov ax, 4c00h
A> int 21h
A>code ends
A>end main
A>
A>Ошибка компилятора: **Error** comex.asm(8) CS unreachable from current segment
-- См. здесь и далее ищите описание этой ошибки.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Alex16, Вы писали:
A>>Здравствуйте, ДимДимыч
A>>Ребят, ну я не просто так спрашиваю, у меня возник вопрос потому что я пописал разные com программы, посмотрел как это выглядит в obj файле, посмотрел, что делает компилятор что линковщик. Как каждая команда переводится в коды. И когда мне стало совсем ясно, как загрузчик запускает com программу на выполнение, т.е. у него для этого все данные есть, встал вопрос: зачем здесь эта директива, если и без нее все уже определено? Почему без нее не работает?
А>Неверно ты понял. Можно написать программу и она будет работать про CS равным ЛЮБОЙ величине. Например 7800 то есть компилятор зная какой будет CS все офсеты пересчитает. Вообщем кури не про COM а про BIN.
Чего? Что дальше, что cs=7800? В com программе не происходит пересчета офсетов. Да и в ехе программе нет такого. Есть пересчет сегментов.
парень, ты вообще знаешь о чем ты пишешь? Может тебе рассказать, что всего существует 3 типа адресации в процессоре? Короткий ближний и дальний переходы? Причем короткие и ближние отсчитываются от текущей команды! Никогда никакие оффсеты не пересчитываются!
Компилятор НЕ ЗНАЕТ КУДА БУДЕТ ЗАГРУЖЕНА ПРОГРАММА. Он не может пересчитывать. Этим занимается загрузчик. И то, в ехе.
Re[7]: Assume
От:
Аноним
Дата:
07.07.11 18:25
Оценка:
Здравствуйте, Alex16, Вы писали:
A>Здравствуйте, Аноним, Вы писали:
А>>Сосем не обязательно. Можно хоть с 200.
A>Неа.. когда мы пишем org 100h, компилятор просто проверяет эту строчку и без нее линковщик не слинкует. Пометки, что у нас вот там в начале есть 100h байт нулевых в com программе нигде нет. Соотвественно написать org 200h не можем. A>Error: Cannot generate COM file : invalid initial entry point addres
Я же сказал, COM это частный случай BIN. И эта ошибка это просто защита от дурака. И "там" 100 байт не нулей совсем.
A>Я ничего не понял насчет неперемещаемости. Программа будет загружена туда, где есть свободное место. A>Приведите пример.
Слушай, ну и не понял ну ни значит оно нафиг не нужно. Извини, но на самом деле пустое это.
Здравствуйте, Геннадий Майко, Вы писали:
ГМ>Здравствуйте, Alex16,
A>>Ассемблер tasm. Про то, что директива может нам помочь — наверно. Но я не понимаю, почему вот такой код на тасме не работает:
A>>
A>>.model tiny
A>>.186
A>>code segment
A>>;ASSUME CS:CODE
A>>org 100h
A>>main:
A>> mov BX, 00H
A>> ;jmp far ptr main
A>> mov ax, 4c00h
A>> int 21h
A>>code ends
A>>end main
A>>
A>>Ошибка компилятора: **Error** comex.asm(8) CS unreachable from current segment ГМ>-- ГМ>См. здесь и далее ищите описание этой ошибки.
Прочитал. Но меня интересует не ее описание, а вопрос: вообще, какой смысл в этой директиве в этом месте? Почему у режиме masm код вдруг не компилируется??
Re[7]: Assume
От:
Аноним
Дата:
07.07.11 18:35
Оценка:
Здравствуйте, Alex16, Вы писали:
А>>Неверно ты понял. Можно написать программу и она будет работать про CS равным ЛЮБОЙ величине. Например 7800 то есть компилятор зная какой будет CS все офсеты пересчитает. Вообщем кури не про COM а про BIN.
A>Чего? Что дальше, что cs=7800? В com программе не происходит пересчета офсетов. Да и в ехе программе нет такого. Есть пересчет сегментов.
Не понял и ладно. Зачем тебе это?
Я же написал COM это частный случай BIN-a.
A>парень, ты вообще знаешь о чем ты пишешь? Может тебе рассказать, что всего существует 3 типа адресации в процессоре? Короткий ближний и дальний переходы? Причем короткие и ближние отсчитываются от текущей команды! Никогда никакие оффсеты не пересчитываются! A>Компилятор НЕ ЗНАЕТ КУДА БУДЕТ ЗАГРУЖЕНА ПРОГРАММА. Он не может пересчитывать. Этим занимается загрузчик. И то, в ехе.
Ну вот и отлично, я тебе обьяснять не хочу. Так как оно тебе на самом деле не нужно.
Зачем тебе знания о том, что было больше 20 лет назад. Я же написал, СЛОЖНО это все, это тогда еще например в 1985-87 годах понимали 0.1% от все программистов, и то только после пары лет программирования в кодах. Ты решил понять это вот прям так с разу. Да не получится. ДА И НЕ НАДО оно тебе. Хватит дурить.
Здравствуйте, Аноним, Вы писали:
А>Я же сказал, COM это частный случай BIN. И эта ошибка это просто защита от дурака. И "там" 100 байт не нулей совсем.
Вы мне уже надоели своими очевидными замечаниями. Я ЗНАЮ ЧТО ТАМ НЕ НУЛИ!!! Я вам задал конкретный вопрос уже 3 раз, и вы не можете на него ответить. Вы либо настолько ленивый, что не можете код написать, либо сами не знаете.
А>Слушай, ну и не понял
А>Ну вот и отлично, я тебе обьяснять не хочу. Так как оно тебе на самом деле не нужно. А>Зачем тебе знания о том, что было больше 20 лет назад. Я же написал, СЛОЖНО это все, это тогда еще например в 1985-87 годах понимали 0.1% от все программистов, и то только после пары лет программирования в кодах. Ты решил понять это вот прям так с разу. Да не получится. ДА И НЕ НАДО оно тебе. Хватит дурить.
Вам какое дело надо мне это или нет? Я вас не об этом спрашиваю. Если вы не входили в число тех 0.1. программистов так и скажите.
Этот кусок com программы компилируется в 5 байт. И вы говорите, что это сложно? Где сложно? В каком месте? Я вас спросил, можно ли обойтись вообще без директивы? Вы мне хоть что нибудь сказали?
Знаете, не надо писать отписки, если не знаете, так и скажите
Re[9]: Assume
От:
Аноним
Дата:
07.07.11 18:41
Оценка:
Здравствуйте, Alex16, Вы писали:
A>А вы по делу ничевошеньки не сказали.
Тебе расжавать до кашицы ? Так тут трактат на десяток страниц получится. Я вводные дал — считай что в ДОСЕ программы не перемещаемые. И линкера как такового нет. И в момент загрузки делается долинковка. Вообщем — если действительно интересено, разбересь сам. Отладчик то у тебя какой. Скачай ADF. Если найдешь.
Здравствуйте, Аноним, Вы писали:
А>Здравствуйте, Alex16, Вы писали:
A>>А вы по делу ничевошеньки не сказали.
А>Тебе расжавать до кашицы ? Так тут трактат на десяток страниц получится. Я вводные дал — считай что в ДОСЕ программы не перемещаемые. И линкера как такового нет. И в момент загрузки делается долинковка. Вообщем — если действительно интересено, разбересь сам. Отладчик то у тебя какой. Скачай ADF. Если найдешь.
Я вам 2 раза написал, что я все это видел, как происходит долинковка в памяти, и алгоритм загрузчика. Я не могу разобраться сам, потому что:
1.) По моему мнению директива не нужна
2.) Но без нее программа не работает
3.) Все объяснения которые я нашел — на детском уровне
Скажите, вы способны хоть что то по сути написать, вы хоть почитайте ответы других. Можно объяснить самому, отправить к книге, или к статье. Вы же — ну ничего !
Я так понимаю, что вы последний раз занимались этим лет 20 назад, да и то не оч. разбирались. А сейчас вообще ниче уж не помните. Ну так вы НЕ ПИШИТЕ!
Здравствуйте, 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-ы.