Несколько вопросов начинающего

Тема в разделе "WASM.BEGINNERS", создана пользователем s3dworld, 6 окт 2010.

  1. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    s3dworld
    Ну конечно, ноль со смещением сложите - смещение и получите.
     
  2. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Nafanya
    Мне как раз так и нужно. А вот ещё интересно: я для любого прерывания (не своего, а прерываний процессора, от 0 и так штуки 24) могу сам по желанию установить любой из дескрипторов (задачи, прерывания, ловушки) независимо от номера прерывания? Или же для определённых дескрипторов (например 0 - деление на ноль) нельзя установить любой из дескрипторов?
     
  3. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    s3dworld
    Вы для любого прерывания можете установить свой собственный обработчик(определяя в дескрипторе IDT - селектор и смещение). Номер прерывания жёстко привязан к номеру дескриптора в IDT.
     
  4. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Nafanya
    Я не про это. Бывают три вида обработчика прерываний: задача, ловушка, прерывание. Для каждого свой формат дескриптора (там только несколько бит изменяется). Так вот я и спрашиваю, для любого прерывания я могу установить любой дескриптор из этих трёх?

    Вот, например, прерывания и ловушки работают в той же задаче, а задачи - переключают TSS.

    Или же, например, для прерывания 0 (деление на ноль) можно установить только дескриптор ловушки и ничего другого? Или же всё равно что?
     
  5. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    s3dworld
    Любой. Надо учитывать разницу между ними, чтобы понимать, для каких целей что нужно использовать. Так, для внешних прерываний (от внешних устройств) целесообразно использовать шлюз прерывания: когда произойдёт это прерывание, процессор сам запретит дальнейшие прерывания до тех пор, пока программист их явным образом не разрешит. В случае же со шлюзом ловушки прерывания не запрещаются, что может привести к прерыванию текущего обработчика более приоритетным прерыванием, а это не всегда допустимо. Шлюз задачи имеет смысл только для обработки исключения, вызываемого неправильным стеком системы, когда обработать прерывание обычным образом попросту невозможно из-за невозможности переключиться на этот самый стек стек (при наличии шлюза задачи произойдёт переключение на стек, указанный в TSS именно этой задачи -- а это, по идее, будет отдельный, гарантированно работоспособный стек, что и позволит обработать прерывание, а не уйти на перезагрузку).
     
  6. Semiono

    Semiono Member

    Публикаций:
    0
    Регистрация:
    27 ноя 2005
    Сообщения:
    774
    Код (Text):
    1. include '%fasm%\win32ax.inc'
    2. section '.code' executable
    3. start:
    4.         invoke GetCommandLine
    5.                mov [ebx],eax
    6.         invoke GetModuleFileName,NULL,lpFile,MAX_PATH
    7.         invoke lstrlen,lpFile
    8.                sub [ebx],eax
    9.                inc ebx
    10.                cmp byte [ebx],'h'
    11.                jne @f
    12.         invoke TileWindows,NULL,MDITILE_HORIZONTAL,NULL,NULL,NULL
    13.                jmp exit
    14. @@:
    15.         invoke TileWindows,NULL,MDITILE_VERTICAL,NULL,NULL,NULL
    16. exit:
    17.         invoke ExitProcess,NULL
    18.  
    19. .end start
    20.  
    21. section '.data' readable writable
    22.  
    23.         lpFile dd ?
    Быть может я и намудрил с вычитанием GetModuleFileName из GetCommandLine,
    потому что другого способа не пришло на ум, но имхо почему не работает вообще!
    Тупо переход на метку @@: в любом случае.

    --
    Зделал по-другому, получилось! Но коментарии по первому коду было бы любопытно.

    Код (Text):
    1. include '%fasm%\win32ax.inc'
    2. section '.code' executable
    3. start:
    4.         invoke GetCommandLine
    5.                mov ebx,eax
    6. @@:
    7.                cmp byte [ebx],NULL
    8.                je  exec
    9.                cmp byte [ebx],'h'
    10.                je  @f
    11.                cmp byte [ebx],'H'
    12.                je  @f
    13.                inc ebx
    14.                jmp @r
    15. @@:
    16.                inc ebx
    17.                cmp byte [ebx],' '
    18.                je  @r
    19.  
    20.         invoke TileWindows,NULL,MDITILE_HORIZONTAL,NULL,NULL,NULL
    21.                jmp exit
    22. exec:
    23.         invoke TileWindows,NULL,MDITILE_VERTICAL,NULL,NULL,NULL
    24. exit:
    25.         invoke ExitProcess,NULL
    26.  
    27. .end start
     
  7. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    А вот у меня такой вопрос (всё про страничную организацию памяти)...

    Теперь я понимаю как составлять странички, как обращаться к нужной страничке и к нужному байту в ней. Давайте предположим что у меня одна страничка будет занимать 4 МБ. Предположим что я написал какое-то подобие операционной системы. И вот пускай была создана программа пользователя, которая в себе содержит столько кода и данных, что превышает 4 МБ (одну страничку), предположим что всё это умещается в 12 МБ (три странички).

    Ведь для программиста сторонней программы вся память плоская и он ничего не знает о страничках, их номерах и прочего. Вот тут я и не понимаю алгоритм разбиения кода и данных на странички.

    Пускай я все эти 12 МБ разобью по страничкам (получится три странички). Но вот скажем будет в конце странички первой идти переход на код, который идёт дальше по адресу, но именно я его перетащил во вторую страничку. Получится ошибка. Как же тогда быть?

    Или же нужно программировать программы так, чтобы заранее заботиться о страничках прикладному программисту?

    Как вот это делается в Windows? Как размер страничке в x86 версии? А какой в x64?

    Насколько я помню, при разработке программ под Windows, мы ни с какими страничками дело не имеем (у нас плоская память), то как же получается что код с одной странички на другую прыгает, когда мы явно это не указываем?
     
  8. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Вот как осуществлять переход то со страницами на код уже другой страницы, если программа пользователя не знает ничего об страничках и думает что всё плоское:

    [​IMG]

    И если не делать переходы, а код сам выполняется и как тогда будет идти переход от конца страницы до начало другой страницы, если же программа не знает о страничках:

    [​IMG]

    Поясните, пожалуйста, как же идёт такое формирование. Ведь при разработке Windows программ на ассемблере, мы ведь не указываем никаких страниц с которыми будем работать. Или же строгое ограничение, чтобы код не занимал больше 4 МБ?
     
  9. Nafanya

    Nafanya Member

    Публикаций:
    0
    Регистрация:
    26 июл 2006
    Сообщения:
    581
    s3dworld
    У Вас прям нескончаемый поток вопросов.
    Почитайте про менеджер виртуальной памяти. В случае обращения к отсутствующей странице в памяти возникает исключение page_fault, и менеджер памяти подгружает её с винта.
     
  10. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Вы не понимаете фундаментальных принципов работы ОС, в частности, организации виртуальной памяти. Читайте умные книги -- там всё это есть.
     
  11. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Да я понимаю про исключения отсутствия странички в памяти подгрузку данных в этот страничный кадр. Понимаю я зачем нужна виртуальная память (удобно использовать LDT). Я не понимаю другого.

    Пускай у меня будет код программы на 8 МБ данных. Если не использовать странички и использовать только лишь сегменты, то всё легко. Мы сделаем один сегмент с базой 0 и максимальным лимитом, со включённым битом гранулярностью. То есть опишем 4 ГБ данных. Загрузим по какому-нибудь смещение эти 8 МБ кода и передадим управление на начало кода. И код будет выполнять как плоская модель памяти, команда от команды (если нужно, то переходы от 0-3 МБ в 4-7 МБ). Мы сможем просто написать jmp и указать смещение.

    А если включить страничное преобразование и каждую страничку представить как 4 МБ данных, то тут я уже не понимаю принципов работы. Я разделяю код от 0-3 МБ в страничку №1, а код от 4-7 МБ - в страничку №2. И вот выполняется последняя команда в страничке №1 и следом должна идти команда в начале страничке №2. Но как это так сделать?

    Да и переходы идут так, что я указываю в 32-битном регистре индекс (10 бит) и смещение (22 бита), то есть определяю страничку и смещение в ней. А если я встречу в коде, который писался не зная ничего об программных особенностях операционной системы, который только работает со всей памятью, как с плоской - если я встречу команду дальнего перехода (больше 128), то получится неразбериха. Для плоской модели можно подумать что это 32-битное значение будет определять смещение в сегменте, а для страничной организации памяти - будет определять страничку и смещение в ней.

    Так вот и получается, что мне на у меня только один выход - проектирование программ так, чтобы разработчик уже знал какие данные в какой страничке окажутся и обращался именно к страничкам.

    Но ведь в том же Windows так не используется. Там мы же пишем программы как будто для сегментов (ничего не учитываем для страниц). Как же это так получается?
     
  12. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    Ничего Вы не понимаете. LDT никакого отношения к виртуальной памяти не имеет; более того, подавляющее большинство процессорных архитектур никаких аналогов интеловских сегментов (а соответственно, и GDT-LDT) не имеет -- что не мешает иметь на них полноценную виртуальную память. Так что не флудите, а читайте литературу.
     
  13. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    SII
    Да блин. Согласен, LDT я зря туда пихнул, если использовать страничную организацию.
     
  14. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Возможно никто не понял что я хочу сказать Вам. Поэтому попытаюсь объяснить всё тоже самое, но только с другой стороны.

    Вот у меня есть код:

    Код (Text):
    1. mov EAX,0
    2. mov EAX,1
    3. mov EAX,2
    4. mov EAX,3
    5. mov EAX,4
    6. mov EAX,5
    7. mov EAX,6
    8. mov EAX,7
    9. hlt
    Данный код будет занимать 49 байт (8 команд по 6 байт + 1 байт остановки процессора). Получается такая картина:

    Я в глобальной таблице дескрипторов (GDT) могу описать дескриптор, который описывал бы сегмент в 49 байт. Загрузить в память, куда указывает этот дескриптор, выше описанные коды команд и передать туда управление.

    А теперь давайте предположим что странички имеют размер не в 4 КБ, а в 36 байт.

    Я для программы выделяю два страничных кадра. Предположим это будут странички с индексами 0 и 1 в каталоге таблиц. В страничку с индексом 0 я копирую:

    А в страничку с индексом 1 я копирую:

    Передаю управление на страничку с индексом 0 по нулевому смещению. И что будет дальше?

    Возможно всё пройдёт как и положено (давайте не будем брать во внимание то, что команда hlt не выполнится на третьем уровне привилегий - на уровне пользователя), если странички лежал границами друг к другу. Если всё таки они лежат границами друг к другу, тогда всё пойдёт по плану - выполнится и тот и другой код?
     
  15. barmaley57

    barmaley57 New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2009
    Сообщения:
    58
    s3dworld, с теорией у тебя явно не все хорошо. Вопрос достаточно сложный и вот так вот с первого раза можно не въехать. При страничной организации пользовательскому приложению в принципе нафиг не надо знать как и куда отображены его страницы в физ.памяти. Трансляцией адресов занимается сам процессор. У него для этого есть все необходимое: CR3, GDT, PDE, PTE. Если аппаратный блок процессора при попытке трансляции обнаруживает, что страницы нет в физ. памяти - он генерит прерывание, и обработкой отсутствия страницы уже занимается код ядра. Либо страница подгружается из свопа, либо генерится уже исключение пользователю.
     
  16. barmaley57

    barmaley57 New Member

    Публикаций:
    0
    Регистрация:
    10 авг 2009
    Сообщения:
    58
    s3dworldпро твои размышления насчет границ страницек и пр. Есть у процесса 0-вая т страница в 4kb. Она отображена допустим в N-ый мегабайт физ.памяти. Есть также у него 1-я страница в 4kb. Она отображена в M-ный мегабайт памяти. Код приложения находится в этих двух страницах. Физически они расположены в разных местах, а виртуально они расположены последовательно, поэтому никаких проблемм у процессора при выборе очередной инструкции из памяти не будет, ибо он транслирует вирт.адреса в физ.адреса автоматом...
     
  17. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    s3dworld,

    Более того, первый байт многобайтной команды может принадлежать одной странице, а последний — другой. Аналогично и для многобайтных данных. Ничего специального делать не надо: страничная трансляция работает автоматически.
     
  18. s3dworld

    s3dworld Сергей

    Публикаций:
    0
    Регистрация:
    16 мар 2010
    Сообщения:
    387
    Адрес:
    Ртищево
    Ребят, то есть получается что всё равно какую физическую память описывают странички. Если у меня выполняется страничка под индексом 34, то после выполнения её последней команды, процессор автоматически перейдёт выполнять код со странички 35?
     
  19. baldr

    baldr New Member

    Публикаций:
    0
    Регистрация:
    29 апр 2010
    Сообщения:
    327
    s3dworld,

    Страницы лежат глубже. Процессор просто следует инструкциям и считывает текущую по логическому адресу cs:eip. Сегментация преобразует логический адрес в линейный, страничная адресация преобразует линейный в физический. Контроллер памяти определяет, куда послать запрос на чтение, исходя из того, как он сконфигурирован. В общих чертах, всё.
     
  20. Tronix

    Tronix Member

    Публикаций:
    0
    Регистрация:
    10 сен 2010
    Сообщения:
    122
    Оффтоп: Ничего себе "вопросы начинающего". Я из этой темы почерпнул много сведений, которых раньше не знал. s3dworld желаю разобраться во всех нюансах, хорошо что есть еще люди вроде вас.