<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Hard-Soft News</title>
	<atom:link href="http://hsnews.symmetrica.net/feed" rel="self" type="application/rss+xml" />
	<link>http://hsnews.symmetrica.net</link>
	<description>Новости железа и софта</description>
	<lastBuildDate>Wed, 01 Feb 2012 11:05:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Программирование в Qt: создаем виджет в стиле HUD</title>
		<link>http://hsnews.symmetrica.net/archives/543</link>
		<comments>http://hsnews.symmetrica.net/archives/543#comments</comments>
		<pubDate>Wed, 01 Feb 2012 11:05:01 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[Qt]]></category>
		<category><![CDATA[soft]]></category>
		<category><![CDATA[мои решения]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=543</guid>
		<description><![CDATA[Меню с поисковой строкой Под влиянием новых интерфейсов GNOME я решил сделать виджет для Qt – меню с поисковой строкой в верхней части. Этот виджет можно расматривать как дополнение к примерам нестандартных виджетов, описанных в. В остальной части меню отображаются команды приложения, в наименование которых входит текст, введенный в строке. Такое меню может быть полезно [...]]]></description>
			<content:encoded><![CDATA[<p><em>Меню с поисковой строкой</em><br />
Под влиянием новых интерфейсов GNOME я решил сделать виджет для Qt – меню с поисковой строкой в верхней части. Этот виджет можно расматривать как дополнение к примерам нестандартных виджетов, описанных в. В остальной части меню отображаются команды приложения, в наименование которых входит текст, введенный в строке. Такое меню может быть полезно для пользователей, которые помнят, как называется команда, но не помнят, в каком разделе главного меню он находится, или не хотят «ползать» по бесконечным» выпадающим под-меню.</p>
<p><img class="aligncenter" title="Меню с поисковой строкой" src="http://symmetrica.net/qt4/hudlike.png" alt="Меню с поисковой строкой" width="456" height="190" /></p>
<p><a href="http://symmetrica.net/qt4/hudlike.htm">Читать дальше</a></p>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/543/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Поцелуи с точки зрения параноика (свободная фантазия на биологическую тему)</title>
		<link>http://hsnews.symmetrica.net/archives/533</link>
		<comments>http://hsnews.symmetrica.net/archives/533#comments</comments>
		<pubDate>Mon, 30 Jan 2012 16:25:22 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[просто так]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=533</guid>
		<description><![CDATA[Просьба не воспринимать все написанное ниже очень серьезно. В мире известно немало паразитов, которые атакуют нервную систему жертвы и заставляют ее подчиняться своим целям. Может ли такой паразит взять под контроль нервную систему человека? Пожалуй, самый известный пример паразита, способного контролировать нервную систему другого существа &#8212; Leucochloridium paradoxum. Этот паразит живет в телах улиток, но [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: right;"><em>Просьба не воспринимать все написанное ниже очень серьезно.</em></p>
<p>В мире известно немало паразитов, которые атакуют нервную систему жертвы и заставляют ее подчиняться своим целям. Может ли такой паразит взять под контроль нервную систему человека?<a href="http://hsnews.symmetrica.net/wp-content/uploads/2012/01/toksoplazmoz1.jpg"><img class="alignright size-full wp-image-534" title="toksoplazmoz1" src="http://hsnews.symmetrica.net/wp-content/uploads/2012/01/toksoplazmoz1.jpg" alt="" width="203" height="152" /></a></p>
<p>Пожалуй, самый известный пример паразита, способного контролировать нервную систему другого существа &#8212; <em>Leucochloridium paradoxum</em>. Этот паразит живет в телах улиток, но для успешного размножения ему нужно быть съеденным птицей. И вот, в определенный момент улитка, как зомби, выползает из укрытия и при этом еще фосфоресцирует, привлекая внимание птиц, которые улитками обычно не питаются. И это далеко не единственный паразит такого рода. Например <em>Toxoplasma gondii</em>, возбудитель токсоплазмоза, может проводить определённые периоды жизни в теле самых разных теплокровных животных, а вот размножаться способен только в кишечнике кошек. Поэтому, если возбудитель попадает в тело мыши или крысы, ему становится выгодно, чтобы животное-хозяин было съедено кошкой. Паразит захватывает контроль над нервной системой животного, в результате чего мыши становятся «бесстрашными» &#8212; запах кошки их больше не пугает. Соответственно для них возрастает риск быть съеденными. Важно отметить, что в остальном больные токсоплазмозом мыши ничем не отличаются от здоровых собратьев. За исключением запаха кошки они по-прежнему пугливы.</p>
<p><span id="more-533"></span></p>
<p>Как видим, паразиты могут захватывать и успешно использовать нервную систему сравнительно высокоорганизованных животных. Могут ли такие паразиты распространятся в популяциях разумных существ? Если паразит, контролирующий нервную систему, вызывает не очень заметные изменения в поведении хозяина, если действия паразита не ведут к быстрой гибели хозяина (а большинству паразитов быстрая гибель хозяина крайне не выгодна, так что вред, который они наносят хозяину, иногда компенсируется некоторой пользой, в крайних формах такие отношения становятся симбиотическими), то число инфицированных может стать чрезвычайно велико и тогда деятельность паразита будет крайне незаметна. Инфицированных, в силу их многочисленности и незначительности отклонений в поведении признают нормальными. Приведенные выше примеры широко известны потому, что паразит на определенном этапе своего развития заставляет хозяина быть съеденным. Но в принципе паразиту, контролирующему нервную систему хозяина, вовсе не обязательно заставлять хозяина преждевременно умереть. Такое может потребоваться только в том случае, если разные части жизненного цикла паразита протекают в организмах разных животных. Если все стадии жизненного цикла паразита протекают в организме одного животного, все, что требуется паразиту от хозяина – заставить хозяина выполнять некие действия, способствующие распространению паразита. И эта стратегия является более выигрышной с точки зрения паразита, нежели стратегия, подразумевающая преждевременную смерть одного из хозяев.</p>
<p>Если бы я был демиургом и проектировал вирус для контроля нервной системы человека, в техническом задании я перечислили бы следующие обязательные требования:</p>
<ul>
<li>Вирус не должен приводить к преждевременной смерти человека. Люди – разумные существа и борются за продление собственной жизни. Вирус, приводящий к преждевременной смерти, скорее всего, обнаружат и постараются уничтожить.</li>
<li>Вирус не должен вызывать слишком сильных девиаций в поведении человека. Даже мыши, больные токсоплазмозом, не могут быть слишком девиантными. Люди – общественные существа со сложной социальной структурой. Девиантов они изолируют, а иногда даже уничтожают, следовательно и вирус, вызывающий сильные отклонения от норм поведения, никогда не сможет стать массовым.</li>
<li>Для своего распространения вирус должен заставлять человека совершать «невинные» действия, которое будут социально приемлемы для самых разных культур. В том числе и действие, необходимое для распространения вируса, не должно выглядеть слишком странным или угрожающим.</li>
</ul>
<p>Вирус, обладающий перечисленными выше качествами, в человеческой популяции будет распространяться  очень быстро, а  обнаружить его будет крайне трудно.<br />
Какое действие может использовать вирус для передачи от одного человека к другому? Самым подходящим кандидатом на роль такого действия является поцелуй. Физиологическая функция поцелуя до сих пор не ясна (на этот счет существует несколько теорий), при этом поцелуй (контакт слизистых оболочек ротовой полости) является очень хорошим мостом для передачи микроорганизмов, в том числе возбудителей инфекций (и мы знаем немало инфекций, способных передаваться таким путем). И вот, не смотря на то, что поцелуй потенциально опасен, поцелуи распространены у всех народов, а так же у ближайших родственников человека – шимпанзе.<br />
А что, если предположить, что вместе с уже известными микроорганизмами в процессе поцелуя передается некий неизвестный, который собственно и заставляет людей и высших приматов получать удовольствие от поцелуя – посредством контроля центральной нервной системы?</p>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/533/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Разработка программ для микроконтроллеров ARM для работы на голом железе</title>
		<link>http://hsnews.symmetrica.net/archives/524</link>
		<comments>http://hsnews.symmetrica.net/archives/524#comments</comments>
		<pubDate>Mon, 16 Jan 2012 11:10:44 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[soft]]></category>
		<category><![CDATA[железо]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Железо]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=524</guid>
		<description><![CDATA[Поскольку в некоторых (правда не очень широких) кругах я считаюсь специалистом по процессором ARM и всем, что с ними связано, еще недавно мне часто задавали вопрос как установить Linux на ту или иную железку ARM. Сейчас после появления Android такие вопросы задают гораздо реже и это еще одна польза от Android (по крайней мере для [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-full wp-image-525" style="margin: 2px;" title="baremetal1" src="http://hsnews.symmetrica.net/wp-content/uploads/2012/01/baremetal1.png" alt="" width="290" height="115" /> Поскольку в некоторых (правда не очень широких) кругах я считаюсь специалистом по процессором ARM и всем, что с ними связано, еще недавно мне часто задавали вопрос как установить Linux на ту или иную железку ARM. Сейчас после появления Android такие вопросы задают гораздо реже и это еще одна польза от Android (по крайней мере для меня). Главная проблема с установкой Linux ARM заключается в том, что не существует стандартный платформы ARM, подобной стандартный платформе PC. Современные системы ARM, это системы выполненные на одном кристалле, на котором помимо процессора расположены различные контроллеры. Проблема в том, что в разных моделях и архитектура контроллеры и адреса регистров, и даже значение, которые записываются в эти адреса, могут развиться даже в рамках одного модельного ряда. Это значит, что для установки Линукса на любое железо ARM необходим свой уникальный набор драйверов. Этот факт очень важно понять не только тем кто пытается поставить Линукс на ARM, но и тем, кто просто пишет программы для ARM-систем, например для микроконтроллеров. Далее мы рассмотрим три типа современных систем на основе ARM и пример программы, предназначенной для работы на голом железе микроконтроллера ARM.</p>
<p><span id="more-524"></span></p>
<p>Устройства, основанные на ARM можно разделить на три группы.</p>
<p>Первую группу составляют самые простые устройства, у которых недостаточно ресурсов для того чтобы выполнять простейшие операционные системы. Программы, которые пишут для таких устройств, обычно работают «на голом железе», то есть  напрямую взаимодействуют со всем оборудование системы.</p>
<p>Ко второй группе относятся устройства которые уже могут выполнять специализированные операционные системы, предназначенные для микроконтроллеров, но они все еще достаточно просты для того чтобы для них можно было писать программы, работающие на голом железе.</p>
<p>Наконец, третья категория, &#8212; это устройства, достаточно мощные для того чтобы работать под операционными системами общего назначения, предназначенными для обильных устройств (например Android). Неудивительно, что в последнее время именно устройств этой категории становится все больше и больше.</p>
<p>Однако это не значит, что устройства первой ив торой категорий больше не нужны. Попробуйте соорудить микроконтроллер на основе обычного мобильного устройства. Это не так-то просто, не говоря уже о цене подобного решения.<br />
Обширный зоопарк устройств на основе ARM приводит к тому, что про программирование для них становится довольно трудно писать. Точнее говоря, трудно приводить примеры программ, которые будут работать не только на устройствах, которые есть у автора, но и на устройстве, которым располагает читатель.</p>
<p>Труднее всего, конечно, описывать программирование на голом железе, потому что любая ОС создает некую среду, сохраняющую единообразие на всех платформах. Но мы начнем именно с самых простых устройств, которые оказываются самыми сложными в программировании. Даже самая простая программа, предназначенная для работы на голом железе, должна выполнить ряд неочевидных для обычного (привыкшего к программированию под ОС) программиста действий. Чтобы понять механику работы программы на голом железе, давайте вспомним, что делает операционная система с момента загрузки и до момента запуска прикладной программы. Прежде всего, любая ОС подготавливает компьютер к работе: настраивает средства управления различными элементами машины, в том числе, например, устанавливает скорость доступа к шинам и памяти. Важный этап в работе любой ОС – настройка таблицы векторов прерываний.</p>
<p>Когда операционная система загружает прикладную программу, она, помимо прочего, создает различные элементы среды окружения для этой программы, и располагает различные блоки программы в оперативной памяти так, чтобы они могли найти друг друга. Все, что я пишу здесь про работу ОС, представляет собой довольно упрощенную картину. Это тот необходимый минимум, который нужно знать, чтобы понять, как работает программа на голом железе. Одной из задач, которые такая программа должна решить самостоятельно, является заполнение таблицы векторов прерываний. Вот как выглядит таблица векторов прерываний минимальной программы для микроконтроллера ARM (пример позаимствован из <a href="http://balau82.wordpress.com">замечательного блога</a> ):</p>
<pre> B Reset_Handler /* Reset */
 B . /* Undefined */
B . /* SWI */
B . /* Prefetch Abort */
B . /* Data Abort */
B . /* reserved */
B . /* IRQ */
B . /* FIQ */</pre>
<p>Таблица векторов прерываний состоит из команд безусловного перехода (B). Таблица векторов может содержать и другие команды, но смысл их должен быть тот же – переход по некоторому адресу. Команда</p>
<pre>В.</pre>
<p>(B с точкой) это переход на тот же адрес, по которому расположена инструкция, то есть бесконечный цикл. Таким образом, мы видим, что в приведенной таблице прерываний определен только обработчик прерывания Reset. Прерывание Reset может быть генерировано, например, кнажатием кнопки Reset. В любом случае это единственное прерывание, которое программа обязана  обрабатывать. Нетрудно видеть, что любое другое прерывание, буде фоно возникнет, приведет к зависанию программы. Обработчик прерывания Reset выглядит следующим образом:</p>
<pre>Reset_Handler:
 LDR sp, =stack_top
 BL c_entry
 B .</pre>
<p>Первая инструкция загружает в регистр SP адрес верхушки стека. Следующая инструкция – это вызов процедуры c_entry, с которой начинается, собственно, работа нашей программы. Фактически вся наша программа умещается в обработчике прерывания Reset. Вам может показаться, что это не самое элегантное решение, но многие серьезные программы для микроконтроллеров делают точно так же.</p>
<p>Далее следует уже знакомая нам «B с точкой». После выхода из функции c_entry программа снова зацикливается (если бы программа работала под управлением операционной системы, она должна была бы передать управление системе, но программе, которая работает сама по себе, после выхода из основной функции просто нечего делать. Коротко говоря, прерывание Reset заставляет систему запустить программу на выполнение. Все вместе это собирается в ассемблерный файл crt.s:</p>
<pre>.section INTERRUPT_VECTOR, "x"
.global _Reset
_Reset:
B Reset_Handler /* Reset */
B . /* Undefined */
B . /* SWI */
B . /* Prefetch Abort */
B . /* Data Abort */
B . /* reserved */
B . /* IRQ */
B . /* FIQ */

Reset_Handler:
  LDR sp, =stack_top
  BL c_entry
  B .</pre>
<p>Первая строка  ассемблерного файла  сообщает компоновщику, что файл содержит раздел INTERRUPT_VECTOR, который содержит исполнимый код &#171;x&#187;. Вторая строчка объявляет глобально видимое имя «_Reset». Оно тоже понадобится компоновщику. Все, что следует дальше, мы уже описали.</p>
<p>Теперь нам нужна собственно функция c_entry. В нашем случае она  будет выглядеть так:</p>
<pre>int c_entry()
{
return 0;
}</pre>
<p>Эта функция не делает ничего полезного, но именно по этой причине она будет выполняться на любом микроконтроллере (назовем файл, содержащий этот код, test.c).</p>
<p>Дальше нам нужно написать еще один скрипт, с которым прикладные программисты обычно не имеют дела. Речь идет о скрипте компоновщика, который указывает, как скомпоновать программу. Когда программа собирается для операционной системы, компоновщик, рассчитанный на эту ОС, сам знает, что ему делать. Но в случае программирования на голом железе мы должны рассказать ему об этом. Наш скрипт предназначен для компоновщика GNU (ld), так в дальнейшем для сборки программ мы будем пользоваться именно инструментами GNU.</p>
<pre>ENTRY(_Reset)
SECTIONS
{
 . = 0x0;
 .text : {
 startup.o (INTERRUPT_VECTOR)
 *(.text)
 }
 .data : { *(.data) }
 .bss : { *(.bss) }
 . = . + 0x1000; /* 4kB of stack memory */
 stack_top = .;
}</pre>
<p>Первая строка скрипта компоновки указывает точку входа в программу. Таким образом выполнении нашей программы начнется с перехода на обработчик прерывания Reset, который вызовет функцию c_entry. Дальше мы сообщаем компоновщику, что секция INTERRUPT_VECTOR находится в файле starup.o и должна быть расположена, начиная с адреса 0&#215;0. Затем следует еще описание нескольких секций, которые мы сейчас пропустим. Интересно для нас то, как заполняется переменная stack_top, которую использует процедура инициализации. Вы уже наверное догадались, что точка означает в этом скрипте то же, что и в ассемблерном файле – текущий адрес. Таким образом, выражение</p>
<pre> . = . + 0x1000;</pre>
<p>Означает «прибавить к текущему адресу значение 4096». То есть верхушка стека оказывается смещена на 4096 байтов относительно завершающего адреса последней секции программы. Для программ на микроконтроллерах 4096 байтов стека – совсем неплохо (а для нашей конкретной программы даже слишком много).</p>
<p>И так теперь мы знаем, из каких основных элементов должна состоять программа, предназначенная для работы на голом железе. Во-первых, это инициализирующая часть, написанная обычно на ассемблере (хотя может использовать и C), во-вторых, это собственно программа, которую нужно выполнить, в третьих это сценарий компоновщика.</p>
<p>Разделение программ на инициализирующую часть и основной код удобно тем, что можно использовать один и от же код инициализации для многих разных программ.</p>
<p>Вот и все на сегодня. В заключение ссылки на очень полезную книгу. Она доступна в сети бесплатно (хотя, к сожалению, не переведена на русский):</p>
<p>Miro Samek, Building Bare Metal ARM Systems with GNU – как указывает название, эта книга как раз про то, о чем мы сегодня говорили, хотя изложение в ней начинается сразу с вещей гораздо более сложных.</p>
<p>В следующих статьях этого цикла я расскажу как собирать программы для ARM-микроконтроллеров, загружать их в устройства и запускать на исполнение.</p>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/524/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Наконец-то</title>
		<link>http://hsnews.symmetrica.net/archives/520</link>
		<comments>http://hsnews.symmetrica.net/archives/520#comments</comments>
		<pubDate>Tue, 10 Jan 2012 10:50:47 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[Qt]]></category>
		<category><![CDATA[мои решения]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=520</guid>
		<description><![CDATA[Получил от издательства крупный вариант обложки моей книги. &#160;]]></description>
			<content:encoded><![CDATA[<p>Получил от издательства крупный вариант обложки моей книги.</p>
<div id="attachment_517" class="wp-caption aligncenter" style="width: 570px"><a href="http://hsnews.symmetrica.net/wp-content/uploads/2012/01/oblb.png"><img class=" wp-image-517 " title="Qt 4.7+ Практическое программирование на С++" src="http://hsnews.symmetrica.net/wp-content/uploads/2012/01/oblb.png" alt="Qt 4.7+ Практическое программирование на С++" width="560" height="372" /></a><p class="wp-caption-text">Qt 4.7+ Практическое программирование на С++</p></div>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/520/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Classical Computer Science Papers Every Programmer Should Read</title>
		<link>http://hsnews.symmetrica.net/archives/494</link>
		<comments>http://hsnews.symmetrica.net/archives/494#comments</comments>
		<pubDate>Sat, 24 Dec 2011 11:08:23 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[Без рубрики]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=494</guid>
		<description><![CDATA[Here is the list of papers on computing which I consider the Golden Hall of Classics of Computer Science.  We have already read most of these things in our textbooks and heard them on lectures. But I think it is still refreshing and broadening the mind to see the original publications that grounded many fields of CS. The text are not [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://hsnews.symmetrica.net/wp-content/uploads/2011/12/cslike2.gif"><img class="alignright size-full wp-image-497" title="cslike" src="http://hsnews.symmetrica.net/wp-content/uploads/2011/12/cslike2.gif" alt="" width="200" height="164" /></a>Here is the list of papers on computing which I consider the Golden Hall of Classics of Computer Science.  We have already read most of these things in our textbooks and heard them on lectures. But I think it is still refreshing and broadening the mind to see the original publications that grounded many fields of CS. The text are not sorted in any way. The list is going to be updated and you are welcome to send the links to the texts you consider as important as those below.<br />
A note about copyrights: while all these papers are freely available online (i.e. not pay-walled), I don&#8217;t store the files on my server. Following are only the links that point elsewhere.</p>
<p><a href="http://hsnews.symmetrica.net/archives/494#more-494">Read more&#8230;</a></p>
<p><span id="more-494"></span></p>
<h4></h4>
<h4><a href="https://dl.dropbox.com/u/54427875/acmhoare69.pdf">An Axiomatic Basis for Computer Programming</a>, C. A. R. HOARE, 1969.</h4>
<p>While Mr. Hoare is well known for quite many things, including the QuickSort algorithm, this article is an excellent insight into the logical foundations of computer programming.</p>
<p>&nbsp;</p>
<h4><a href="https://dl.dropbox.com/u/54427875/dispatching-ecoop98.pdf">Predicate Dispatching: A Unied Theory of Dispatch</a>, Michael Ernst, <em>et al</em>., 1998.</h4>
<p>Describes a method for dispatching functions based not on a static set of rules, but instead as the traversal of a decision tree that could be built at compile-time and extended incrementally at runtime.</p>
<p>&nbsp;</p>
<h4><a href="https://dl.dropbox.com/u/54427875/EWD123.pdf">Cooperating sequential processes</a>, E.W.Dijkstra, 1965</h4>
<p>While Dijkctra&#8217;s is quite famous for many CS discoveries and sarcastic remarks, this article describes the methods of synchronization which gained much of importance with the growth of multi-threaded programming. The sheer weight of the heady topics assembled in one place is stunning to observe.</p>
<p>&nbsp;</p>
<h4><a href="https://dl.dropbox.com/u/54427875/fundamental-1967.pdf">Fundamental Concepts in Programming Languages</a>, <strong>Christopher Strachey</strong>, 1967</h4>
<p>L-values, R-values, parameter passing, variable binding, functions as data, parametric polymorphism, ad hoc polymorphism&#8230; All these concepts are explained in this classical text with crystal clarity.</p>
<p>&nbsp;</p>
<h4><a href="https://dl.dropbox.com/u/54427875/OnUnderstanding.pdf">On Understanding Types, Data Abstraction, and Polymorphism</a>, <strong>Luca Cardelli</strong>, Peter Wegner, 1985</h4>
<p>An excellent article on the foundations of types theory and OOP.</p>
<p>&nbsp;</p>
<h4><a href="https://dl.dropbox.com/u/54427875/time-clocks.pdf">Time, Clocks, and the Ordering o f Events in a Distributed System</a>, <strong>Leslie Lamport</strong>, 1978</h4>
<p>This paper presents a single-handed definitions of the two branches of study in distributed computing: the reasoning of event ordering in distributed systems and protocols, and the state machine approach to redundancy</p>
<p>&nbsp;</p>
<h4><a href="https://dl.dropbox.com/u/54427875/time-clocks.pdf">Sketchpad: A Man-Machine Graphical Communication System</a>, <strong>I. E. Sutheland</strong>, 1963</h4>
<p>The pioneering work on computer graphics</p>
<p>&nbsp;</p>
<p><em>To be updated&#8230;</em></p>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/494/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>YAGF 0.8.9</title>
		<link>http://hsnews.symmetrica.net/archives/485</link>
		<comments>http://hsnews.symmetrica.net/archives/485#comments</comments>
		<pubDate>Sun, 18 Dec 2011 15:21:57 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[news]]></category>
		<category><![CDATA[soft]]></category>
		<category><![CDATA[YAGF]]></category>
		<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[мои решения]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=485</guid>
		<description><![CDATA[Очередной релиз. Основные новшества: функция автоматического исправления наклона страницы (deskew) и улучшенный пользовательский интерфейс. Страница проекта:  http://symmetrica.net/cuneiform-linux/yagf-ru.html Страница YAGF на Goole+ Пара видеороликов про YAGF: Сканирование и распознавание &#160; Исправление наклона страницы и распознавание &#160;]]></description>
			<content:encoded><![CDATA[<p>Очередной релиз. Основные новшества: функция автоматического исправления наклона страницы (deskew) и улучшенный пользовательский интерфейс.</p>
<p>Страница проекта:  <a href="http://symmetrica.net/cuneiform-linux/yagf-ru.html">http://symmetrica.net/cuneiform-linux/yagf-ru.html</a></p>
<p><img class="aligncenter" title="YAGF 0.8.9" src="http://symmetrica.net/cuneiform-linux/yagf.jpg" alt="YAGF 0.8.9" width="640" height="488" /></p>
<p><span id="more-485"></span></p>
<p><a href="https://plus.google.com/u/0/b/109307158531695849158/">Страница YAGF на Goole+</a></p>
<p>Пара видеороликов про YAGF:</p>
<p>Сканирование и распознавание</p>
<p><iframe width="500" height="375" src="http://www.youtube.com/embed/u3SmEvf1xaw?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>&nbsp;</p>
<p>Исправление наклона страницы и распознавание</p>
<p><iframe width="500" height="375" src="http://www.youtube.com/embed/pTwz9VlqBNg?fs=1&#038;feature=oembed" frameborder="0" allowfullscreen></iframe></p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/485/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Безопасный запуск Linux на устройстве ARM (часть II)</title>
		<link>http://hsnews.symmetrica.net/archives/478</link>
		<comments>http://hsnews.symmetrica.net/archives/478#comments</comments>
		<pubDate>Wed, 16 Nov 2011 12:33:04 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[Android]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=478</guid>
		<description><![CDATA[Продолжаем обживаться в системе ARM Linux, установленной на флешку. Первая часть Одно из первых действий после установки системы – создание нового пользователя. После создания пользователя с обычными правами вы обнаружите, что он не может выходить в сеть. Вызов любой сетевой программы заканчивается сообщением об отсутствии разрешений. Для того чтобы пользователь получил разрешение на выход в [...]]]></description>
			<content:encoded><![CDATA[<p>Продолжаем обживаться в системе ARM Linux, установленной на флешку.</p>
<p><a href="http://hsnews.symmetrica.net/archives/466">Первая часть</a></p>
<p><span id="more-478"></span>Одно из первых действий после установки системы – создание нового пользователя. После создания пользователя с обычными правами вы обнаружите, что он не может выходить в сеть. Вызов любой сетевой программы заканчивается сообщением об отсутствии разрешений. Для того чтобы пользователь получил разрешение на выход в сеть, необходимо создать группу sockets и добавить пользователя в эту группу:</p>
<pre>adduser newuser
addgroup --gid 3003 sockets
usermod -G sockets -a newuser</pre>
<p>Другой полезной программой, которую следует установить в систему – демон SSH. Для того чтобы запустить сервер sshd необходимо настроить файл /etc/ssh/sshd_config. Вот один из вариантов конфига:</p>
<pre>Port 22
Protocol 2
HostKey /etc/ssh/ssh_host_rsa_key
HostKey /etc/ssh/ssh_host_dsa_key
UsePrivilegeSeparation no
KeyRegenerationInterval 3600
ServerKeyBits 768
SyslogFacility AUTH
LogLevel INFO
LoginGraceTime 120
PermitRootLogin yes
StrictModes yes
RSAAuthentication yes
PubkeyAuthentication yes
IgnoreRhosts yes
RhostsRSAAuthentication no
HostbasedAuthentication no
PermitEmptyPasswords yes
ChallengeResponseAuthentication no
X11Forwarding yes
X11DisplayOffset 10
PrintMotd no
PrintLastLog yes
TCPKeepAlive yes
AcceptEnv LANG LC_*
Subsystem sftp /usr/lib/openssh/sftp-server
UsePAM yes</pre>
<p>Эта конфигурация разрешает доступ пользователю root по SSH. Если вы опасаетесь за безопасность системы, замените в строке</p>
<pre>PermitRootLogin yes</pre>
<p>параметр yes на no. Теперь мы можем подключаться к системе на мобильном устройстве с компьютера, обладающего полноценной клавиатурой. Дополнительное удобство SSH – возможность обмениваться файлами с мобильной системой с помощью SFTP.</p>
<p>Работа с графическими приложениями возможна в двух вариантах:</p>
<ol start="1">
<li>Можно подключаться к системе с ПК через SSH и использовать X forwarding.</li>
<li>Можно установить сервер tightvnc и подключаться через VNC. Этот вариант хорош тем, что клиент VNC может быть установлен на само мобильное устройство (например, на устройство Android). Впрочем, работать с десктопными графическими программами с устройства, которое рассчитано в основном на ввод не с клавиатуры, не очень удобно.</li>
</ol>
<p>&nbsp;</p>
<p>Итак, что же мы имеем? Мы имеем систему, которая способна запускаться с любого мобильного устройства на базе ARM, где есть Linux с подходящим ядром и хост USB. При этом в нашей системе нам доступно все, что предоставляет в наше распоряжение ядро Linux, в том числе директория /dev/.</p>
<p>Иначе говоря, мы получили неплохой полигон для программирования под ARM Linux и изучения периферии мобильного девайса.</p>
<p style="text-align: center;"><a href="http://hsnews.symmetrica.net/wp-content/uploads/2011/11/armx2.jpg"><img class="size-full wp-image-479 aligncenter" title="ARM  Linux" src="http://hsnews.symmetrica.net/wp-content/uploads/2011/11/armx2.jpg" alt="ARM  Linux" width="512" height="385" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/478/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Безопасный запуск Linux на устройстве ARM</title>
		<link>http://hsnews.symmetrica.net/archives/466</link>
		<comments>http://hsnews.symmetrica.net/archives/466#comments</comments>
		<pubDate>Mon, 07 Nov 2011 14:26:02 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[soft]]></category>
		<category><![CDATA[Без рубрики]]></category>
		<category><![CDATA[железо]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[Железо]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=466</guid>
		<description><![CDATA[Речь пойдет о запуске полноценного дистрибутива Linux на устройствах, на которых уже установлен урезанный Linux. Проще говоря, на устройствах с Android и Angstrom. Этот способ установки является на сегодняшний день самым безболезненным для девайса, что хорошо подходит тем, кто хочет по-прежнему пользоваться устройством по назначению, а не только как площадкой для тестирования Linux. При использовании [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://hsnews.symmetrica.net/wp-content/uploads/2011/11/linside.jpg"><img class="alignright size-full wp-image-475" title="Linux inside" src="http://hsnews.symmetrica.net/wp-content/uploads/2011/11/linside.jpg" alt="" width="125" height="128" /></a>Речь пойдет о запуске полноценного дистрибутива Linux на устройствах, на которых уже установлен урезанный Linux. Проще говоря, на устройствах с Android и Angstrom.</p>
<p>Этот способ установки является на сегодняшний день самым безболезненным для девайса, что хорошо подходит тем, кто хочет по-прежнему пользоваться устройством по назначению, а не только как площадкой для тестирования Linux. При использовании этого способа файлы Linux вообще не будут устанавливаться на устройство с Андроидом. Вместо этого мы установим их на USB-флешку.<span id="more-466"></span></p>
<p>Что требуется?</p>
<ol start="1">
<li>Обычный компьютер c Linux Ubuntu (у меня Ubuntu 10.10) или Debian. Можно использовать и другие дистрибутивы Linux, нужно только чтобы в них были установлены утилиты Ubuntu: пакет dpkg и его друзья, и скрипт debootstrap.</li>
<li>Собственно устройство с ОС Android (или другой ОС, основанной на Linux), которое умеет работать с флешкой. Я использовал Toshiba AC100 и еще один мобильный девайс, который работает под Linux Angstrom, но ничего специфического для этих устройств не применял, так что советы должны сгодиться и для других девайсов.</li>
<li>Если у вас устройство Android или другое устройство, на котором нет доступа к Linux root, необходимо выполнить рутинг устройства и установить на него набор утилит BusyBox. Стараниями хакеров и то, и другое теперь можно сделать из-под самого Андроида, без всяких перепрошивок. Тем не менее, рутование Андроида остается потенциально опасной операцией. Будем радоваться тому, что это единственное серьезное вмешательство в саму ОС Андроид, которое нам понадобится.</li>
</ol>
<p><strong>Шаг 1</strong>, необходимый, если у вас на устройстве не рутованный Андроид.<br />
Рутование Андроида стало уже неприлично простым благодаря программе z4root. Эта программа устанавливается как и любая программа Android. После запуска программы и выполнения ей всех операций достаточно перезагрузить устройства и все готово – ваш Андроид порутан. Более подробные инструкции можно найти на сайтах, посвященных программе z4root. Далее устанавливаем BusyBox. Для этого тоже есть специальная программа – BusyBox for Android. Как и z4root, BusyBox устанавливается из-под Андроида. На моем девайсе программа установки BusyBox сообщила, что утилита установить не удалось, но они, тем не менее, были установлены. Ну и последнее, это установка программы-эмулятора терминала для Android. Без такой программы работать с Линуксом будет трудно и неинтересно.</p>
<p><strong>Шаг 2</strong>. Подготовка флешки.<br />
Задача этого этапа – отформатировать флешку в Ext3 и записать на нее файлы базовой установки Ubunu Linux. Допустим, флешка, приговоренная к установке Убунты, опознана системой как /dev/sda1. Тогда сначала ее нужно размонтировать, а затем скомандовать:</p>
<pre>mkfs.ext3 –L linux /dev/sda1</pre>
<p>Опция -L устанавливает метку диска. Если ваш вариант mkfs.ext3 не поддерживает эту опцию, метку можно установить после выполнения mkfs.ext3 с помощью e2label:</p>
<pre>e2label /dev/sda1 linux</pre>
<p>Теперь смонтируйте флешку снова (Linux может смонтировать ее автоматически, например, в директорию /media/linux) и запишите на нее файлы Linux. Флешка должна быть смонтирована (перемонтирована) с опциями dev,suid,exec. На всякий случай, команда ручного монтирования выглядит так:</p>
<pre>mount -t ext3 -o exec,suid,dev /dev/sda1 /media/linux/</pre>
<p>Для создания базовой системы Ubuntu ARM на флешке хорошо подходит утилита debootstrap.<br />
Командуем:</p>
<pre>debootstrap --foreign --arch=armel maverick /media/linux</pre>
<p>Здесь «maverick» – название дистрибутива Ubuntu. Ключ &#8212;foreign указывает на то, что базовая система Linux собирается для другой архитектуры (в данном случае – ARMEL). Информацию об установке различных версий Ubuntu скрипт debootstrap читает из файлов в директории</p>
<pre>/usr/share/debootstrap/scripts/</pre>
<p>Вы можете посмотреть содержимое этой директории, чтобы узнать, какие версии Ubuntu сконфигурированы для debootstrap. Если такой директории у вас нет, или в ней нет файлов конфигурации maverick или natty, это значит, что у вас установлена старая версия debootstrap, которая не сможет сделать все правильно. Необходимо обновиться.</p>
<p>После того как утилита debootstrap запишет на флешку все необходимые файлы Linux, размонтируйте флешку и и подключите к целевому устройству.</p>
<p><strong>Шаг 3.</strong> запуск Linux на целевом устройстве.<br />
Флешка может быть распознана устройством автоматически, а может и не быть. Откройте эмулятор терминала (или подключитесь к терминалу другим способом) и в режиме root найдите устройство, соответствующее флешке, в директории /dev. У меня оно нашлось как /dev/block/sda1. Лучше всего создать для монтирования раздела с Ubuntu Linux специальную директорию. Я перемонтировал файловую систему /system в режиме rw и создал директорию /system/linux, но подойдет и любая другая. Монтируем флешку:</p>
<pre>mount –t ext3 /dev/block/sda1 /system/linux</pre>
<p>Мы почти у цели. Осталось совсем немного, выполнить последовательность команд, которая подготовит систему в разделе /system/linux к запуску в режиме chroot. Вот эти команды:</p>
<pre>export PATH=/bin:/usr/bin:/sbin:/usr/sbin:$PATH
export USER=root
export HOME=/root
export TERM=xterm
busybox mount -o remount,exec,suid /system/linux
cd /system/linux
busybox mount -o bind /proc proc
busybox mount -o bind /sys sys
busybox mount -o bind /dev dev
busybox mount -o bind /dev/pts dev/pts
busybox chroot . bash</pre>
<p>Для удобства эти команды можно записать в файл скрипта, например, startlinux.sh.<br />
Выполнив файл startlinux.sh, вы должны увидеть нечто вроде:</p>
<pre>I have no name!@localhost#</pre>
<p>Это означает, что Ubutu на устройстве ARM запущена (Ура!), но не настроена. Для завершения установки необходимо, уже в Ubuntu, скомандовать:</p>
<pre>/debootstrap/debootstrap --second-stage</pre>
<p>что и завершит установку. Теперь выходите из Ubutu в «родную систему» устройства с помощью exit и снова запустите файл startlinux.sh. На этот раз приглашение командной строки в Ubuntu выглядит как</p>
<pre>root@localhost#</pre>
<p>или наподобие. Это значит, что система настроена. Осталось настроить apt-get. Для этого в файл /etc/apt/sources.list добавьте строку</p>
<pre>deb http://ports.ubuntu.com/ubuntu-ports/ maverick main</pre>
<p>где «maverick», опять же, нужно заменить именем установленной версии Ubuntu. На этом предварительная установка Ubuntu для ARM закончена. Можете приступать к закачке дополнительного софта.<br />
<a href="http://hsnews.symmetrica.net/archives/478"> Продолжение следует</a>.</p>
<div id="attachment_473" class="wp-caption aligncenter" style="width: 460px"><a href="http://hsnews.symmetrica.net/wp-content/uploads/2011/11/armlin.png"><img class="size-full wp-image-473" title="ARM Linux" src="http://hsnews.symmetrica.net/wp-content/uploads/2011/11/armlin.png" alt="" width="450" height="334" /></a><p class="wp-caption-text">ARM Linux</p></div>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/466/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Системные вызовы ARM Linux</title>
		<link>http://hsnews.symmetrica.net/archives/461</link>
		<comments>http://hsnews.symmetrica.net/archives/461#comments</comments>
		<pubDate>Mon, 31 Oct 2011 06:51:34 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[soft]]></category>
		<category><![CDATA[ARM]]></category>
		<category><![CDATA[Linux]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=461</guid>
		<description><![CDATA[Номера и порядок передачи аргументов системных вызовов ARM Linux соответствуют таковым на платформе Intel, и это очень хорошо и правильно. Существует два режима системных вызовов – старый и новый (новый является частью стандарта EABI). Нынешние ядра ARM Linux поддерживают оба режима, но использовать режим EABI, разумеется, предпочтительнее. У двух режимов много общего: аргументы вызова передаются [...]]]></description>
			<content:encoded><![CDATA[<p>Номера и порядок передачи аргументов системных вызовов ARM Linux соответствуют таковым на платформе Intel, и это очень хорошо и правильно. Существует два режима системных вызовов – старый и новый (новый является частью стандарта EABI). Нынешние ядра ARM Linux поддерживают оба режима, но использовать режим EABI, разумеется, предпочтительнее. У двух режимов много общего: аргументы вызова передаются в регистрах r0-r6, а сам вызов выполняется с помощью инструкции SWI.<br />
В старом режиме номер вызова является частью операнда инструкции SWI. Операнд инструкции выглядит так:</p>
<pre>MOV r0, дескриптор_файла;
MOV r1, адрес_буфера;
MOV r2, длина_буфера;
SWI 0x900004;</pre>
<p>В режиме EABI номер вызова передается в регистре r7, а операндом SWI всегда является значение 0&#215;0. Еще одно отличие связано с передачей 64-битных аргументов. В обоих режимах их передают в паре 32-битных регистров, но в старом режиме это просто два следующих не занятых регистра, а в режиме EABI – следующая пара регистров, в которой первый регистр имеет четный номер. Тот же вызов _write() в режиме EABI будет выглядеть так:</p>
<pre>MOV r0, дескриптор_файла;
MOV r1, адрес_буфера;
MOV r2, длина_буфера;
MOV r7, #4;
SWI 0x0;</pre>
<p>Помимо прочего, между двумя режимами существует одно, не сразу заметное, различие: режим EABI может использовать как в режиме ARM MODE (32-битные инструкции), так и в более компактном THUMB MODE. Старый режим не может использоваться в THUMB MODE просто потому, что число 0&#215;900000 не поместится в 16-битном операнде инструкции SWI режима THUMB.<br />
Ну и напоследок, описания нескольких системных вызовов ARM Linux. Зная общий принцип, остальные описания легко «конвертировать» из описаний аналогичных вызовов для Intel.</p>
<table border="1" cellspacing="0" cellpadding="0">
<tbody>
<tr>
<td valign="top" width="103">Номер</td>
<td valign="top" width="144">Обозначение</td>
<td valign="top" width="192">Используемые регистры</td>
</tr>
<tr>
<td valign="top" width="103">1</td>
<td valign="top" width="144">sys_exit()</td>
<td valign="top" width="192">r0</td>
</tr>
<tr>
<td valign="top" width="103">3</td>
<td valign="top" width="144">sys_read()</td>
<td valign="top" width="192">r0, r1, r2</td>
</tr>
<tr>
<td valign="top" width="103">4</td>
<td valign="top" width="144">sys_write()</td>
<td valign="top" width="192">r0, r1, r2</td>
</tr>
<tr>
<td valign="top" width="103">5</td>
<td valign="top" width="144">sys_open()</td>
<td valign="top" width="192">r0, r1, r2</td>
</tr>
<tr>
<td valign="top" width="103">6</td>
<td valign="top" width="144">sys_close()</td>
<td valign="top" width="192">r0</td>
</tr>
</tbody>
</table>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/461/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Самый компактный исполнимый файл для Linux</title>
		<link>http://hsnews.symmetrica.net/archives/448</link>
		<comments>http://hsnews.symmetrica.net/archives/448#comments</comments>
		<pubDate>Thu, 27 Oct 2011 06:36:34 +0000</pubDate>
		<dc:creator>Андрей Боровский</dc:creator>
				<category><![CDATA[soft]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[софт]]></category>

		<guid isPermaLink="false">http://hsnews.symmetrica.net/?p=448</guid>
		<description><![CDATA[Размер исполнимого файла обычной программы Hello World при сборке в моей системе (X86-64, Linux) после выполнения strip составляет  6208 байтов. Для ARM Linux (ARMv9) &#8212; 2720 байтов. Можно ли улучшить эти результаты? #include &#60;stdio.h&#62; int main(int argc, char ** argv) { printf("Hello!\n"); return 0; } Очевидно, что свой вклад в размер исполнимого файла вносит библиотека glibc, [...]]]></description>
			<content:encoded><![CDATA[<p>Размер исполнимого файла обычной программы Hello World при сборке в моей системе (X86-64, Linux) после выполнения strip составляет  6208 байтов. Для ARM Linux (ARMv9) &#8212; 2720 байтов. Можно ли улучшить эти результаты?<span id="more-448"></span></p>
<pre>#include &lt;stdio.h&gt;
 int main(int argc, char ** argv)
 {
  printf("Hello!\n");
  return 0;
 }</pre>
<p>Очевидно, что свой вклад в размер исполнимого файла вносит библиотека glibc, из которой мы берем функцию printf(). Попробуем обойтись без нее:</p>
<pre>int main(int argc, char ** argv)
{
	char * s = "Hello!\n";
	__asm__ ("movl $4, %%eax; movl $0, %%ebx; movl $7, %%edx; int $0x80"
	:
	: "c"(s)
	: "%eax", "%ebx", "%edx");
	return 0;
}</pre>
<p>Последовательность ассемблерных команд в этом примере выполняет системный вызов syscall_write с аргументами 0 (стандартный поток вывода), s и 7 (длина строки s без конечного 0). Однако после компиляции этого варианта программы мы обнаруживаем, что размер исполнимого файла не изменился. Проблема в том, что библиотека glibc по-прежнему присутствует в нашей программе. Схематически структуру программы Linux можно представить так:</p>
<pre>void _start() 
{
// подготовка к вызову main()
int retval = main();
// Вежливое завершение
_exit(retval);
}</pre>
<p>Точкой входа в программу является функция _start(), которая готовит программу к вызову main(), а после выхода из этой функции завершает программу системным вызовом exit(). Мы можем сами написать функцию _start:</p>
<pre>void _start()
{
	char * s = "Hello!\n";
	__asm__ ("movl $4, %%eax; movl $0, %%ebx; movl  $8, %%edx; int $0x80"
	:
	: "c"(s)
	: "%eax", "%ebx", "%edx");
	__asm__ ("movl $1, %eax; xorl %ebx, %ebx; int $0x80"); // Вызов, эквивалентный _exit(0)
}</pre>
<p>Теперь наша программа не использует функций glibc, но при попытке ее скомпилировать компоновщик пожалуется, что у нас определено две функции _start(). Исправить это можно, вызвав gcc с ключом  -nostdlib. В результате (при компиляции с ключом -O2 и после обработки strip&#8217;ом) получим исполнимый файл программы размером 1082 байта. Чуть больше одного килобайта! Вряд ли на 64-битном процессоре можно добиться более компактного результата. ;)</p>
<p><a href="http://learningpearls.blogspot.com/2011/02/start-function-inside-c.html">Полезная ссылка по теме</a></p>
<p>А вот, например, та же программа для ARM Linux. Программа написана для ARM mode (32-битные инструкции)</p>
<pre>void _start()
{
char * s = "Hello\n";
__asm__ ("mov r0, #0; mov r1, %[sptr]; mov r2, #7; swi 0x900004" // _write(0, s, 7);
:
: [sptr] "r" (s)
: "r0", "r1", "r2");
__asm__ ("mov r0, #0; swi 0x900001"); // _exit(0);
}</pre>
<p>Программу, естественно, тоже нужно собирать с ключом -nostdlib. Получается исполнимый файл длиной 538 байтов, что и не удивительно, если учесть, что плотность кода ARM выше, чем плотность кода X86-64.</p>
]]></content:encoded>
			<wfw:commentRss>http://hsnews.symmetrica.net/archives/448/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>

