<?xml version='1.0' encoding="utf-8"?>
      <rss version='2.0'>
      <channel>
      <title>Форум на Исходниках.RU</title>
      <link>https://forum.sources.ru</link>
      <description>Форум на Исходниках.RU</description>
      <generator>Форум на Исходниках.RU</generator>
  	
      <item>
        <guid isPermaLink='true'>https://forum.sources.ru/index.php?showtopic=165248&amp;view=findpost&amp;p=1381851</guid>
        <pubDate>Mon, 18 Dec 2006 21:10:48 +0000</pubDate>
        <title>[Общее] Устройство некоторых типов данны</title>
        <link>https://forum.sources.ru/index.php?showtopic=165248&amp;view=findpost&amp;p=1381851</link>
        <description><![CDATA[ANDLL: <strong class='tag-b'>Картинка</strong><br>
<img class='tag-img' src='http://internal.danasoft.ws/etc/BSTR.gif' alt='user posted image'><br>
Некий <strong class='tag-b'>BV </strong>надоумил меня нарисовать пару картинок на тему устройства типов данных.<br>
<strong class='tag-b'>Строки</strong><br>
Тут я описал три способа хранить строки(на самом деле способов можно придумать бесчисленное множество, но наиболее распространены как мне кажеться эти).<br>
Итак, первый тип, BSTR(именно он использовуется в переменных типа String в VB6) - строка из unicode-символов, которая кончается двухбайтовым терминатором и перед которой стоит ее длина. Ввиду того, что сама строка содержит свою длину она может содержать произвольные символы.<br>
Во второй тип, ABSTR, VB преобразует строки перед тем как передать их в API-функции. Этот тип отличается от BSTR тем, что содержит однобайтовые символы, вместо двухбайтовых.<br>
Третий, LPSTR традиционно используется в C. Этот тип нигде не хранит длину строки, окончание строки определяется по нулевому терминатору в конце. Строка содержит однобайтовые символы. В отличие от первых двух типов, где нулевой терминатор стоит в конце лишь для совместимости со старыми типами, в LPSTR нулевой терминатор необходим, так как он указывает на конец строки. Так же нелишне отметить, что <strong class='tag-b'>LPSTR строки по определению не могут содержать нулевых символов</strong>. Если вы поместите в LPSTR нулевой символ то для всех использующих ее функций строка &quot;обрежется&quot; до этого символа(по вполне очевидным причинам). Не менее важный минус LPSTR заключается в том, что время определения длины такой строки прямо пропорционально длине строки. Для очень длинных строк, порядка мегабайта, определение длины может оказаться весьма дорогой ситуацией. Типы (A)BSTR этого недостатка лишены.<br>
<strong class='tag-b'>Адреса</strong><br>
Напоследок раскажу об устройстве адреса в ОС windows. Вам ведь известно, что любую ячейку памяти процесса можно &quot;обозвать&quot; четырехбайтовым числом? Если известно, то увы вы малость заблуждаетесь.<br>
На самом деле АП процесса содержит как минимум два сегмента - основной сегмент и вспомогательный.<br>
Номер основного сегмента хранится в регистрах ds,cs,ss,es. gs не используется.<br>
В fs хранится номер второго, служебного сегмента(который правда, является частью основного сегмента) и в этом сегменте храняться некоторые полезные данные о процессе, например его id.<br>
Однако на практике этот сегмент используется только внутри ОС, так как его содержимое вообще говоря малокументировано(описание некоторого содержимого fs можно прочитать <a class='tag-url' href='http://bbs.vbstreets.ru/viewtopic.php?t=25400' target='_blank'>в топике tyomitch</a>).<br>
А вот со вторым сегментом, номер которого всегда хранится в DS и ведет работа наша программа.<br>
Если теперь принять утверждение о том, что написанная нами часть кода программы будет работать только с теми данными, что лежат в основном сегменте, то становится очевидным, почему так часто говорят что адрес в windows это только лишь четырех байтовое число.<br>
Полное устройство адреса показано на рисунке, как видно он состоит из трех частей, номера сегмента, номера страницы и смещения внутри страницы.<br>
Номер сегмента, как было сказано всегде лежит в ds и ss, так что про него можно &quot;забыть&quot; в большинстве случаев.<br>
Номер страницы и смещение храняться внути 4-х байтового числа, void* в C++ или просто Long в VB. При этом под смещение страницы выделяется 12 бит а под номер - 20 бит. Если вам вдруг потребуется разрубить адрес на две части(я с трудом, правда, представляю, зачем вам это), то можно воспользоваться такой простой формулой:<br>
<div class='tag-code'><span class='pre_code'></span><div class='code  code_collapsed ' title='Подсветка синтаксиса доступна зарегистрированным участникам Форума.' style=''><div><div><ol type="1"><div class="code_line">Offset=Address\&amp;h1000</div><div class="code_line">PageNumber=Address AND &amp;hfffff000</div></ol></div></div></div></div><script>preloadCodeButtons('1');</script>]]></description>
        <author>ANDLL</author>
        <category>Visual Basic: Общие вопросы</category>
      </item>
	
      </channel>
      </rss>
	