Азы. Счетчик адреса в сочетании с ORG. TASM.

Тема в разделе "WASM.BEGINNERS", создана пользователем l_inc, 23 окт 2006.

  1. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Это скорее не вопрос, а жалоба на некорректность или, возможно, нечеткость в книге Юрова, которую (в смысле жалобу) можно сформулировать, как вопрос.
    Вот что написано в книге Юрова:
    1) "Счетчик адреса -- специфический вид операнда. Он обозначается знаком $."
    2) "TASM позволяет при необходимости установить счетчик адреса в нужное абсолютное значение. Это делается с помощью директивы ORG."
    А теперь предположим, что я пишу com-программку, кот. будет выглядеть вот так:
    Код (Text):
    1. masm
    2. model tiny
    3. .code
    4. org 100h
    5.  
    6. start:
    7.     jmp near ptr code_seg
    8.         message db "Ош-ка чтения"
    9.     code_seg:
    10.     xor ax, ax
    11.     mov ss, ax
    12.     ..............................
    13.     mov si, offset message - 100h
    14.     ..............................
    15.     jmp $
    16.     ..............................
    17. end start
    Отсюда видно, что, чтобы получить доступ к данным, все их смещения приходится рассчитывать, вычитая 100h. Тем не менее для получения адреса текущей команды (используя именно тот счетчик адреса, который, согласно Юрову, должен быть якобы тоже смещенным на 256 байт) необходимо указывать "$", а не "$ - 100h". При этом в случае "jmp $" TASM формирует код "EB FE", а в случае "jmp $ - 100h" формирует некороткий переход на четверть килобайта назад: "E9 FD FE". И собственно вопрос: ПОЧЕМУ?
     
  2. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    1.А что у Юрова так и сказано, что для получения адреса текущей команды нужно писать $-100? Юрова вобщем-то не читал, но не думаю, чтобы он так писал. (После ORG 100h, он действительно должен быть 100h, и дальше увеличиваться.)

    2.Короткий переход формируется в пределах 256 байт от текущего адреса, и за пределами этого диапазона коротким быть уж конечно не должен.
     
  3. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    1) Я привел цитату. Добуквенно. Могу дать номера страниц и строк.
    P.S. Он не писал, что нужно писать $-100. Это мне так кажется исходя из приведенных мной цитат. Именно исходя из них я и думаю, что переход "jmp $" должен уводить на четверть килобайта вперед.
    2) Спасибо. Я в курсе.
     
  4. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    1.
    Из этой цитаты этого не видно.

    2.А в чём тогда был вопрос?
     
  5. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    1) Чего не видно из цитаты (кстати это две разные цитаты :) )?
    2) Вопрос в том, почему нужно писать jmp $, а не jmp $ - 100h. Возможно я неправильно понимаю значение директивы ORG?
     
  6. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Не видно того, что для получения адреса текущей команды нужно писать $-100.

    $ - это адрес текущей команды, вычисляется препроцессорм (если не ошибаюсь). Какие тут могут быть $-100 для вычисления текущего адреса? А ORG смещает расположение кода на указанное значение, и есно адрес первой команды будет начинаться с этой величины.
     
  7. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Расположение кода? Боюсь что препроцессору (Вы не ошибаетесь: вычисляет именно препроцессор) не под силу сместить расположение кода. Это по силам только загрузчику (в моем случае: загрузчик BIOS, который пишет мой код в 7с00h независимо от аргумента директивы ORG). А согласно цитате, директива ORG смещает именно значение $ (но никак не расположение кода).
     
  8. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    l_inc
    Он туда нопов напихает и код сместится вниз на нужный адрес. Или тихо перепишет код, который выше. Кстати, так лихо орудует оргом только масм/тасм. Другие ассемблеры воспринимают орг совсем иначе.
     
  9. Booster

    Booster New Member

    Публикаций:
    0
    Регистрация:
    26 ноя 2004
    Сообщения:
    4.860
    Ну правильно (только не надо цепляться к словам), кто там в итого размещает код со смещением: компилятор или загрузчик не важно, главное он так размещается, и вычислять адреса нужно с учётом этого (кто это делает тоже вобщем-то до лампочки, зависит от реализации).
    А то что этого явно не сказано, конечно минус, но не катастрофически, бывает и по хлеще.
     
  10. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Quantum
    Дизассемблер, да и просто Hex-редактор, говорят, что нету там никаких нопов. Согласно WinHex код начинается именно с E9 <двухбайтовый адрес перехода> (что означает, как я понимаю "jmp near ptr code_seg"). Поэтому мой код без всяких нопов начинается прямо с 7c00h. Тем не менее значение $, в соответствии с Юровым, меняется.
    Booster
    Извиняюсь. Я не цеплялся к словам. Все, что касается программирования в принципе, я просто вынужден понимать буквально. Иначе, как и в данном случае с Юровым, возникает недопонимание.
    В том то и дело, что не размещается (см. выше :derisive: ).
     
  11. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Мне, например, не видно. Ты разберись с понятиями, что значит виртуальный адрес и физическое смещение.

    Смотри, ты пишешь "org 100h". Зачем? Подумай. Затем, что com-проги грузятся не по 0 адресу, а по 100h, т.к. до этого адреса лежат системные данные. Если бы ты не написал "org 100h", то все метки (code ? data) определялись бы по смещению начиная от 0. При запуске прога грузится по другому адресу, в результате все смещения в коде нарушаются.
    Поэтому и назначается вначале базовый адрес (+256) для того, чтобы компилятор дальше сам вычислял смещения меток.
     
  12. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Спасибо. Я все это знаю, но ответа на вопрос так и не получил.
    Как это не видно?
    А вот это что: "mov si, offset message - 100h"? Причем дизасм показывает, что препроцессор подставляет правильный адрес.
    Зачем я пишу org 100h? Хотел тасмом получить что-то максимально приближенное к бинарнику, т.е. com, а в тасме прокатывает компиляция com-файла только, если указано смещение 100h (мне ничего не стоит скомпилировать данный код в fasm'е и получить то, что хотел, но в данном случае это не важно: просто хочется разобраться кто больше прав: я или Юров :), как бы смешно это не звучало).
    Итак, org 100h оставляем в проге нетронутым. Вопрос остается актуальным: именно при данных условиях (когда все таки есть 100h и не важно зачем), почему верен переход на самого себя при указании "jmp $", а не jmp $ - 100h? Ведь, в соответствии с Юровым, значение $ должно быть на 100h больше.
     
  13. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Потому что jmp $ это то же, что и "@@: jmp @B", а @@ равно 100h + (@@ - start) по твоему коду. "jmp $-100h" будет равно "@@ - start" и будет указывать до начала программы.

    Ты всё же не захотел подумать.

    Если бы ты знал всё это, то не спрашивал бы.
     
  14. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    l_inc
    Первый орг не в счёт.

    По какой-то причине автору понадобилось посчитать адрес метки от начала файла. Приведите полный код, чтобы понять смысл этой странной инструкции.

    Айс уже дал исчерпывающий ответ на этот вопрос.

    $ - это относительный адрес. Базовый адрес на него никак не влияет.
     
  15. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    IceStudent
    Все еще не понятно.
    Извиняюсь за то, что цепляюсь к словам, но это только в результате непонимания (ведь ошибки в учебнике ставят новичков в тупик). Посему появляется сразу куча вопросов вместо одного:
    1) "@@: jmp @B" <=> "jmp $". Разумеется, но что это объясняет?
    2)
    Надо понимать, что слово "равно" заменяет математическое равенство, а не присвоение в программировании. Перенося содержимое в скобках в правую часть получаем start = 100h. учитывая то, что я написал ORG 100h, это и так очевидно, но опять таки: что это объясняет (надо дополнить, что к физическому адресу это 100h никакого отношения не имеет; для загрузчика DOS - имеет, потому что он все com-программки по этому смещению пишет, которое и выравнивается благодаря ORG 100h, но не в моем случае)?
    3)
    Код (Text):
    1. "jmp $-100h" будет равно "@@ - start"
    Еще одна не совсем понятная формулировка, но вероятно имелось ввиду "$-100h" будет равно "@@ - start" (повторяю: я не пытаюсь кого-то подколоть, просто я - новичок и обязан понимать все буквально), что тоже вполне очевидно.
    4)
    Возможно я неправильно понял, но по-моему это совсем не факт, если учесть, что в приведенном мной коде вместо "....................................." может подставляться произвольное количество операций.
    5) Возможно я не понимаю из-за того, что Вы объясняете в расчете на то, что программку будет грузить загрузчик DOS, а я говорил (и я это уже упоминал), что ее грузит BIOS.
    Quantum
    Первый орг? Это о чем? Там вообще никаких нопов вначале нету. Собственно так и ожидается, ведь конечный com ничем не отличается от простого бинарника.
    Не совсем понял на какой вопрос. Этот вопрос я сам себе задал и сам на него ответил в пояснении своего вопроса. (ДА ПОЧЕМУ Ж НИКТО ПОНЯТЬ НЕ МОЖЕТ)
    Возможно правильный вопрос, но объяснит Вам не код, а вот что: это смещение именно сообщения message, правильно посчитанное!!! В результате по этому смещению я просто выведу текст этого сообщения. И вот почему: не смещает у меня загрузчик на 100h, потому что это не Досовский загрузчик, а BIOS и он понятия не имеет о том, как надо загружать файлы com в память: просто грузит, что видит из первого сектора по адресу 7c00h (хотя я это уже писал).
    P.S. Вопрос остается открытым.
     
  16. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    l_inc
    Первый орг задаёт базу и ничего никуда не смещает. Второй орг уже сместит код относительно предыдущего орга и т.д. Я же не сразу посмотрел на Ваш код и заметил, что там только 1 орг. Поэтому реплику про смещение кода компилятором в экзешнике согласно директивам орг можно опустить - в данном случае это не в счёт.

    Если файл загрузится по смещению 100h, как это делают досовские com'ы, мы получим не адрес метки, а адрес метки - 100h.

    Грузит в память по адресу 0x7C00? Тогда нужен org 7C00h, чтобы адрес метки сообщения вычислялся правильно.
     
  17. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Quantum
    Да как же ж можно делать такие предположения, если я уже тысячу раз сказал, что файл не грузится по этому смещению!!!
    И это тоже не нужно!!! Потому что BIOS инициализирует сегментные регистры не так: cs = ds = 0, а вот так: cs = ds = 7c00h. И соответственно правильное!!! смещение я получаю вот так: offset message, если нету ORG 100h и offset message - 100h, если есть ORG 100h. ORG 100h приходится писать по вышеуказанным причинам. Просьба не подвергать больше сомнению правильность определения адреса метки, потому что в данном случае "адрес метки от начала файла" совпадает со смещением данных, на которые указывает метка, от начала сегмента.
    Но раз никто не понимает, давайте абстрагируемся от скомпилированной программы и от программы на стадии выполнения, а займемся буквоедством и глянем на мои цитаты из начала топика. Из цитат следует: если ORG <аргумент>, то $ = <аргумент>+<текущее смещение от начала файла>. Отсюда простой вопрос: почему препроцессор формирует аргумент команды "jmp $" так, что эта команда совпадает с "@@: jmp @B", а не с "@@: jmp @B + 100h"? IceStudent в попытках ответить мне принял это, как аксиому, а на самом деле именно это я и просил объяснить.
     
  18. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    От базы кода (в фасме есть $$ для определения базы).
     
  19. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    l_inc
    Надо было сразу сказать, что файл грузится по адресу 0. Поэтому -100h необходим во всех абсолютных адресах. На относительные адреса это не распространяется, т.к. относительный адрес относится к текущему счётчику инструкций, а не к базовому адресу. Поэтому $ - он и в Африке укажет сам на себя.
     
  20. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    IceStudent
    Да что ж это такое!!!
    Сколько я писал о том, что объяснения формулируются непонятно (неполными, несогласованными предложениями) и что новичку трудно додумывать.
    Но могу предположить, что имелось в виду заменить неверное "$ = <аргумент>+<текущее смещение от начала файла>." на верное "$ = <аргумент>+<текущее смещение от базы кода>."
    И тогда могу сказать (при этом я повторяюсь уже в тысячный раз), что в данном случае <текущее смещение от базы кода> = <текущее смещение от начала файла>.
    Зачем это нужно, если здесь $$ = <аргумент>? (если я правильно понял) Вот только в программе на стадии выполнения это верно только для случая, когда грузит стандартный загрузчик ДОС. Он видит, что это файл com и выставляет ds на сотню меньше, чем реальный адрес начала программы, на который передается управление. Именно это и компенсирует ORG 100h, смещая все метки. Но вопрос не в этом.
    Еще раз перефразирую вопрос. Грубо говоря: Почему Юров говорит, что ORG меняет значение $, а на самом деле это не так (что довольно отчетливо видно из того, что jmp $ компилируется в EB FE)???
    Quantum
    Во-о-от!!! Меня поняли!!! И я про то же. Но ведь Юров пишет, что ORG меняет $ (из цитат видно)!!! Вот в чем проблема!!!
    1) Я думал, что это очевидно из того, что я вычитал 100h из метки message (тем не менее я не один раз это уточнял после).
    2) На самом деле это уже подробности, потому что вопрос относится только к противоречию того, что говорит Юров с тем что делает препроцессор TASM (если выразиться точнее, то к противоречию моего понимания того, что говорит Юров, с моим пониманием того, что делает препроцессор). А на стадии работы препроцессора пофиг какой там будет уже загрузчик и чем он сегментные регистры инициализировать будет.