Assume
От: Alex16  
Дата: 07.07.11 13:47
Оценка:
Здравствуйте!
У меня вопрос: никак не могу понять, зачем в принципе нужна директива Assume в ассемблерах. Везде к книжках пишут, что мол эта директива дает знать ассемблеру о том, какие сегменты нашей программы в каких сегментных регистрах будут. Но это все не ответ.
Я не много разобрался в том, как выглядят com и exe программы в машинных кодах, как правятся адреса сегментов с помощью таблицы замены в ехе программах, как устанавливаются значения сегментных регистров загрузчиком, и хочу сказать, что я так и не понимаю, что с этой директивой делает компилятор и линковщик. В чем ее смысл.
В com программах все сегментные регистры устанавливаются на начало psp. Мы в ней работаем только со смещениями! Зачем ассеблеру нужно знать что там у нас в сегментых регистрах? )
Вопрос к тем, кто знает машинные коды)) Приведите пожалуйста пример с директивой assume и покажите что без нее линковщик ну ни как не сможет слинковать программу ) Не то что там, ему будет тяжело, а просто не сможет)
Потому что у меня простая com программа требует чтобы я обязательно задал assume cs:CSEG. Без этого видите ли не компилируется)
masm assume
Re: Assume
От: ДимДимыч Украина http://klug.org.ua
Дата: 07.07.11 13:58
Оценка:
Здравствуйте, Alex16, Вы писали:

A>Вопрос к тем, кто знает машинные коды)) Приведите пожалуйста пример с директивой assume и покажите что без нее линковщик ну ни как не сможет слинковать программу ) Не то что там, ему будет тяжело, а просто не сможет)


ЕМНИП assume нужна в том случае, когда в программе несколько сегментов данных (и/или кода). Тогда понижается вероятность ошибки, что мы загрузим в ds один сегмент данных, и попробуем обратиться к переменной в другом сегменте.

A>Потому что у меня простая com программа требует чтобы я обязательно задал assume cs:CSEG. Без этого видите ли не компилируется)


Что за ассемблер? Насколько помню, TASM никогда не требовал assume для com-файлов. Может нужно указать модель памяти tiny?
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[2]: Assume
От: Alex16  
Дата: 07.07.11 14:23
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Что за ассемблер? Насколько помню, 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 расскоментировать, то все работает
Re[3]: Assume
От: ДимДимыч Украина http://klug.org.ua
Дата: 07.07.11 15:11
Оценка:
Здравствуйте, 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.

Лдним словом это директива как считать смешение для адреса.
Re[4]: Assume
От: Alex16  
Дата: 07.07.11 17:53
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Директива code segment всего-лишь объявляет некий сегмент с именем "code". Компилятор не знает, куда нужно помещать скомпилированный код.


Нет. Не согласен. Com программа всегда начинает выполняться со смещения 100h. То что она com указано в модели памяти. Ничего компилятору больше не надо. Загрузчик всегда грузит программу после psp, то есть со смещением 100h. Так что, все мы знаем, где она окажется.

ДД>Для com-файлов в TASM я использовал такие объявления, без определения отдельных сегментов:

ДД>
ДД>.model tiny
ДД>.186
ДД>.code
ДД>org 100h
ДД>.startup
ДД>   ...
ДД>end
ДД>


Директива .code — это сокращение от такой записи:
code segment 'code'
ASSUME CS: code

Короче там уже учтен assume.

Вопрос остается открытым: почему кусок который привел я, не работает без нее
Re[2]: Assume
От: Alex16  
Дата: 07.07.11 17:58
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, 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.

Вообще я не очень понимаю, нафига тебе все эти знания? Раньше было трудно программировать. Зачем сейчас-то мучиться.
Re[4]: Assume
От: Alex16  
Дата: 07.07.11 18:04
Оценка:
Здравствуйте, ДимДимыч

Ребят, ну я не просто так спрашиваю, у меня возник вопрос потому что я пописал разные com программы, посмотрел как это выглядит в obj файле, посмотрел, что делает компилятор что линковщик. Как каждая команда переводится в коды. И когда мне стало совсем ясно, как загрузчик запускает com программу на выполнение, т.е. у него для этого все данные есть, встал вопрос: зачем здесь эта директива, если и без нее все уже определено? Почему без нее не работает?
Re[5]: Assume
От: Аноним  
Дата: 07.07.11 18:09
Оценка:
Здравствуйте, Alex16, Вы писали:

A>Здравствуйте, ДимДимыч


A>Ребят, ну я не просто так спрашиваю, у меня возник вопрос потому что я пописал разные com программы, посмотрел как это выглядит в obj файле, посмотрел, что делает компилятор что линковщик. Как каждая команда переводится в коды. И когда мне стало совсем ясно, как загрузчик запускает com программу на выполнение, т.е. у него для этого все данные есть, встал вопрос: зачем здесь эта директива, если и без нее все уже определено? Почему без нее не работает?


Неверно ты понял. Можно написать программу и она будет работать про CS равным ЛЮБОЙ величине. Например 7800 то есть компилятор зная какой будет CS все офсеты пересчитает. Вообщем кури не про COM а про BIN.

Раньше было трудно программировать, теперь то зачем голову на этот изламывать. Считай что это такое программирование в фиксированных адресах. А ого тебе надо?
Re[6]: Assume
От: Alex16  
Дата: 07.07.11 18:14
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Сосем не обязательно. Можно хоть с 200.


Неа.. когда мы пишем org 100h, компилятор просто проверяет эту строчку и без нее линковщик не слинкует. Пометки, что у нас вот там в начале есть 100h байт нулевых в com программе нигде нет. Соотвественно написать org 200h не можем.
Error: Cannot generate COM file : invalid initial entry point addres

А>Я же вроде как уже обьяснил почему.


Нет, вы не объяснили. Вы только сказали, что эта директива полезна. Их ваших слов я понял что без нее можно обойтись. Но я привел кусок кода, в котором обойтись не выходит. Я попросил объяснить зачем она там нужна. Ответа не получил.

А>Но если все еще не понятно, то в ДОСе программы не перемещаемые. И можно например написать COM программу которая будет работать при CS равным конкретной величине. Например 7800 и при этом код будет начинаться со 100 от PSP.

Я ничего не понял насчет неперемещаемости. Программа будет загружена туда, где есть свободное место.
Приведите пример.
Re[3]: Assume
От: Геннадий Майко США  
Дата: 07.07.11 18:17
Оценка:
Здравствуйте, 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

--
См. здесь и далее ищите описание этой ошибки.

C уважением,
Геннадий Майко.
Re[6]: Assume
От: Alex16  
Дата: 07.07.11 18:22
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, 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>Приведите пример.

Слушай, ну и не понял ну ни значит оно нафиг не нужно. Извини, но на самом деле пустое это.
Re[4]: Assume
От: Alex16  
Дата: 07.07.11 18:29
Оценка:
Здравствуйте, Геннадий Майко, Вы писали:

ГМ>Здравствуйте, 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% от все программистов, и то только после пары лет программирования в кодах. Ты решил понять это вот прям так с разу. Да не получится. ДА И НЕ НАДО оно тебе. Хватит дурить.
Re[8]: Assume
От: Alex16  
Дата: 07.07.11 18:36
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Я же сказал, COM это частный случай BIN. И эта ошибка это просто защита от дурака. И "там" 100 байт не нулей совсем.


Вы мне уже надоели своими очевидными замечаниями. Я ЗНАЮ ЧТО ТАМ НЕ НУЛИ!!! Я вам задал конкретный вопрос уже 3 раз, и вы не можете на него ответить. Вы либо настолько ленивый, что не можете код написать, либо сами не знаете.

А>Слушай, ну и не понял


А вы по делу ничевошеньки не сказали.
Re[8]: Assume
От: Alex16  
Дата: 07.07.11 18:40
Оценка:
Здравствуйте, Аноним, Вы писали:


А>Ну вот и отлично, я тебе обьяснять не хочу. Так как оно тебе на самом деле не нужно.

А>Зачем тебе знания о том, что было больше 20 лет назад. Я же написал, СЛОЖНО это все, это тогда еще например в 1985-87 годах понимали 0.1% от все программистов, и то только после пары лет программирования в кодах. Ты решил понять это вот прям так с разу. Да не получится. ДА И НЕ НАДО оно тебе. Хватит дурить.

Вам какое дело надо мне это или нет? Я вас не об этом спрашиваю. Если вы не входили в число тех 0.1. программистов так и скажите.

Этот кусок com программы компилируется в 5 байт. И вы говорите, что это сложно? Где сложно? В каком месте? Я вас спросил, можно ли обойтись вообще без директивы? Вы мне хоть что нибудь сказали?
Знаете, не надо писать отписки, если не знаете, так и скажите
Re[9]: Assume
От: Аноним  
Дата: 07.07.11 18:41
Оценка:
Здравствуйте, Alex16, Вы писали:


A>А вы по делу ничевошеньки не сказали.


Тебе расжавать до кашицы ? Так тут трактат на десяток страниц получится. Я вводные дал — считай что в ДОСЕ программы не перемещаемые. И линкера как такового нет. И в момент загрузки делается долинковка. Вообщем — если действительно интересено, разбересь сам. Отладчик то у тебя какой. Скачай ADF. Если найдешь.
Re[10]: Assume
От: Alex16  
Дата: 07.07.11 18:49
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Alex16, Вы писали:



A>>А вы по делу ничевошеньки не сказали.


А>Тебе расжавать до кашицы ? Так тут трактат на десяток страниц получится. Я вводные дал — считай что в ДОСЕ программы не перемещаемые. И линкера как такового нет. И в момент загрузки делается долинковка. Вообщем — если действительно интересено, разбересь сам. Отладчик то у тебя какой. Скачай ADF. Если найдешь.


Я вам 2 раза написал, что я все это видел, как происходит долинковка в памяти, и алгоритм загрузчика. Я не могу разобраться сам, потому что:
1.) По моему мнению директива не нужна
2.) Но без нее программа не работает
3.) Все объяснения которые я нашел — на детском уровне

Скажите, вы способны хоть что то по сути написать, вы хоть почитайте ответы других. Можно объяснить самому, отправить к книге, или к статье. Вы же — ну ничего !
Я так понимаю, что вы последний раз занимались этим лет 20 назад, да и то не оч. разбирались. А сейчас вообще ниче уж не помните. Ну так вы НЕ ПИШИТЕ!
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.