aboutsummaryrefslogtreecommitdiff
path: root/documentation/content/ru/books/developers-handbook/x86/_index.po
diff options
context:
space:
mode:
Diffstat (limited to 'documentation/content/ru/books/developers-handbook/x86/_index.po')
-rw-r--r--documentation/content/ru/books/developers-handbook/x86/_index.po11158
1 files changed, 11158 insertions, 0 deletions
diff --git a/documentation/content/ru/books/developers-handbook/x86/_index.po b/documentation/content/ru/books/developers-handbook/x86/_index.po
new file mode 100644
index 0000000000..893f016bad
--- /dev/null
+++ b/documentation/content/ru/books/developers-handbook/x86/_index.po
@@ -0,0 +1,11158 @@
+# SOME DESCRIPTIVE TITLE
+# Copyright (C) YEAR The FreeBSD Project
+# This file is distributed under the same license as the FreeBSD Documentation package.
+# Vladlen Popolitov <vladlenpopolitov@list.ru>, 2025.
+msgid ""
+msgstr ""
+"Project-Id-Version: FreeBSD Documentation VERSION\n"
+"POT-Creation-Date: 2025-11-08 16:17+0000\n"
+"PO-Revision-Date: 2025-11-11 04:45+0000\n"
+"Last-Translator: Vladlen Popolitov <vladlenpopolitov@list.ru>\n"
+"Language-Team: Russian <https://translate-dev.freebsd.org/projects/"
+"documentation/booksdevelopers-handbookx86_index/ru/>\n"
+"Language: ru\n"
+"MIME-Version: 1.0\n"
+"Content-Type: text/plain; charset=UTF-8\n"
+"Content-Transfer-Encoding: 8bit\n"
+"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && "
+"n%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n"
+"X-Generator: Weblate 4.17\n"
+
+#. type: Title =
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:15
+#, no-wrap
+msgid "x86 Assembly Language Programming"
+msgstr "Программирование на ассемблере x86"
+
+#. type: YAML Front Matter: title
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1
+#, no-wrap
+msgid "Chapter 11. x86 Assembly Language Programming"
+msgstr "Глава 11. Программирование на языке ассемблера для x86"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:53
+msgid "_This chapter was written by {stanislav}._"
+msgstr "_Эта глава была написана {stanislav}._"
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:55
+#, no-wrap
+msgid "Synopsis"
+msgstr "Обзор"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:59
+msgid ""
+"Assembly language programming under UNIX(R) is highly undocumented. It is "
+"generally assumed that no one would ever want to use it because various "
+"UNIX(R) systems run on different microprocessors, so everything should be "
+"written in C for portability."
+msgstr ""
+"Программирование на ассемблере в UNIX(R) крайне плохо документировано. "
+"Обычно предполагается, что никто не захочет его использовать, поскольку "
+"различные системы UNIX(R) работают на разных микропроцессорах, и поэтому всё "
+"должно быть написано на C для обеспечения переносимости."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:63
+msgid ""
+"In reality, C portability is quite a myth. Even C programs need to be "
+"modified when ported from one UNIX(R) to another, regardless of what "
+"processor each runs on. Typically, such a program is full of conditional "
+"statements depending on the system it is compiled for."
+msgstr ""
+"В действительности переносимость программ на C — это скорее миф. Даже "
+"программы на C требуют изменений при переносе с одной UNIX(R)-системы на "
+"другую, независимо от процессора, на котором они работают. Обычно такая "
+"программа содержит множество условных операторов, зависящих от системы, для "
+"которой она компилируется."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:65
+msgid ""
+"Even if we believe that all of UNIX(R) software should be written in C, or "
+"some other high-level language, we still need assembly language programmers: "
+"Who else would write the section of C library that accesses the kernel?"
+msgstr ""
+"Даже если мы считаем, что всё программное обеспечение UNIX(R) должно быть "
+"написано на C или другом языке высокого уровня, нам всё равно нужны "
+"программисты на ассемблере: кто же ещё напишет часть библиотеки C, которая "
+"обращается к ядру?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:67
+msgid ""
+"In this chapter I will attempt to show you how you can use assembly language "
+"writing UNIX(R) programs, specifically under FreeBSD."
+msgstr ""
+"В этой главе я попытаюсь показать вам, как можно использовать язык "
+"ассемблера для написания программ под UNIX(R), в частности под FreeBSD."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:72
+msgid ""
+"This chapter does not explain the basics of assembly language. There are "
+"enough resources about that (for a complete online course in assembly "
+"language, see Randall Hyde's http://webster.cs.ucr.edu/[Art of Assembly "
+"Language]; or if you prefer a printed book, take a look at Jeff Duntemann's "
+"Assembly Language Step-by-Step (ISBN: 0471375233). However, once the "
+"chapter is finished, any assembly language programmer will be able to write "
+"programs for FreeBSD quickly and efficiently."
+msgstr ""
+"В этой главе не объясняются основы языка ассемблера. Существует достаточно "
+"ресурсов на эту тему (например, полный онлайн-курс по языку ассемблера можно "
+"найти в http://webster.cs.ucr.edu/[Искусстве языка ассемблера] Рэндалла "
+"Хайда; если вы предпочитаете печатные книги, обратите внимание на «Язык "
+"ассемблера шаг за шагом» Джеффа Дантемана (ISBN: 0471375233)). Однако после "
+"прочтения этой главы любой программист на языке ассемблера сможет писать "
+"программы для FreeBSD быстро и эффективно."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:74
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4311
+msgid "Copyright (R) 2000-2001 G. Adam Stanislav. All rights reserved."
+msgstr "Copyright (R) 2000-2001 G. Adam Stanislav. All rights reserved."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:76
+#, no-wrap
+msgid "The Tools"
+msgstr "Инструменты"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:79
+#, no-wrap
+msgid "The Assembler"
+msgstr "Ассемблер"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:82
+msgid ""
+"The most important tool for assembly language programming is the assembler, "
+"the software that converts assembly language code into machine language."
+msgstr ""
+"Важнейшим инструментом для программирования на языке ассемблера является "
+"ассемблер — программа, преобразующая код на языке ассемблера в машинный код."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:85
+msgid ""
+"Three very different assemblers are available for FreeBSD. Both man:llvm-"
+"as[1] (included in package:devel/llvm[]) and man:as[1] (included in package:"
+"devel/binutils[]) use the traditional UNIX(R) assembly language syntax."
+msgstr ""
+"Три очень разных ассемблера доступны для FreeBSD. И man:llvm-as[1] (включён "
+"в package:devel/llvm[]), и man:as[1] (включён в package:devel/binutils[]) "
+"используют традиционный синтаксис ассемблера UNIX(R)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:88
+msgid ""
+"On the other hand, man:nasm[1] (installed through package:devel/nasm[]) uses "
+"the Intel syntax. Its main advantage is that it can assemble code for many "
+"operating systems."
+msgstr ""
+"С другой стороны, man:nasm[1] (устанавливаемый через package:devel/nasm[]) "
+"использует синтаксис Intel. Его основное преимущество в том, что он может "
+"ассемблировать код для многих операционных систем."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:91
+msgid ""
+"This chapter uses nasm syntax because most assembly language programmers "
+"coming to FreeBSD from other operating systems will find it easier to "
+"understand. And, because, quite frankly, that is what I am used to."
+msgstr ""
+"В этой главе используется синтаксис nasm, потому что большинство "
+"программистов на ассемблере, приходящих в FreeBSD из других операционных "
+"систем, найдут его более понятным. Кроме того, если честно, это то, к чему я "
+"привык."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:93
+#, no-wrap
+msgid "The Linker"
+msgstr "Компоновщик"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:96
+msgid ""
+"The output of the assembler, like that of any compiler, needs to be linked "
+"to form an executable file."
+msgstr ""
+"Результат работы ассемблера, как и любого компилятора, необходимо связать, "
+"чтобы получить исполняемый файл."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:99
+msgid ""
+"The standard man:ld[1] linker comes with FreeBSD. It works with the code "
+"assembled with either assembler."
+msgstr ""
+"Стандартный компоновщик man:ld[1] поставляется с FreeBSD. Он работает с "
+"кодом, собранным любым из ассемблеров."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:101
+#, no-wrap
+msgid "System Calls"
+msgstr "Системные вызовы"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:104
+#, no-wrap
+msgid "Default Calling Convention"
+msgstr "Стандартное соглашение о вызовах"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:108
+msgid ""
+"By default, the FreeBSD kernel uses the C calling convention. Further, "
+"although the kernel is accessed using `int 80h`, it is assumed the program "
+"will call a function that issues `int 80h`, rather than issuing `int 80h` "
+"directly."
+msgstr ""
+"По умолчанию ядро FreeBSD использует соглашение о вызовах C. Кроме того, "
+"хотя доступ к ядру осуществляется с помощью `int 80h`, предполагается, что "
+"программа вызовет функцию, которая выполняет `int 80h`, а не будет выполнять "
+"`int 80h` напрямую."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:111
+msgid ""
+"This convention is very convenient, and quite superior to the Microsoft(R) "
+"convention used by MS-DOS(R). Why? Because the UNIX(R) convention allows "
+"any program written in any language to access the kernel."
+msgstr ""
+"Эта традиция очень удобна и значительно превосходит соглашение Microsoft(R), "
+"используемое в MS-DOS(R). Почему? Потому что соглашение UNIX(R) позволяет "
+"любой программе, написанной на любом языке, обращаться к ядру."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:114
+msgid ""
+"An assembly language program can do that as well. For example, we could "
+"open a file:"
+msgstr ""
+"Программа на ассемблере также может это сделать. Например, мы могли бы "
+"открыть файл:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:120
+#, no-wrap
+msgid ""
+"kernel:\n"
+"\tint\t80h\t; Call kernel\n"
+"\tret\n"
+msgstr ""
+"kernel:\n"
+"\tint\t80h\t; Call kernel\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:129
+#, no-wrap
+msgid ""
+"open:\n"
+"\tpush\tdword mode\n"
+"\tpush\tdword flags\n"
+"\tpush\tdword path\n"
+"\tmov\teax, 5\n"
+"\tcall\tkernel\n"
+"\tadd\tesp, byte 12\n"
+"\tret\n"
+msgstr ""
+"open:\n"
+"\tpush\tdword mode\n"
+"\tpush\tdword flags\n"
+"\tpush\tdword path\n"
+"\tmov\teax, 5\n"
+"\tcall\tkernel\n"
+"\tadd\tesp, byte 12\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:133
+msgid ""
+"This is a very clean and portable way of coding. If you need to port the "
+"code to a UNIX(R) system which uses a different interrupt, or a different "
+"way of passing parameters, all you need to change is the kernel procedure."
+msgstr ""
+"Это очень понятный и переносимый способ написания кода. Если вам нужно "
+"перенести код на UNIX(R)-систему, которая использует другое прерывание или "
+"другой способ передачи параметров, все, что вам нужно изменить, это "
+"процедуру kernel."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:137
+msgid ""
+"But assembly language programmers like to shave off cycles. The above "
+"example requires a `call/ret` combination. We can eliminate it by "
+"``push``ing an extra dword:"
+msgstr ""
+"Но программисты на ассемблере любят экономить такты. Приведённый выше пример "
+"требует комбинации `call/ret`. Мы можем исключить её, сделав ``push`` "
+"дополнительного двойного слова:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:148
+#, no-wrap
+msgid ""
+"open:\n"
+"\tpush\tdword mode\n"
+"\tpush\tdword flags\n"
+"\tpush\tdword path\n"
+"\tmov\teax, 5\n"
+"\tpush\teax\t\t; Or any other dword\n"
+"\tint\t80h\n"
+"\tadd\tesp, byte 16\n"
+msgstr ""
+"open:\n"
+"\tpush\tdword mode\n"
+"\tpush\tdword flags\n"
+"\tpush\tdword path\n"
+"\tmov\teax, 5\n"
+"\tpush\teax\t\t; Or any other dword\n"
+"\tint\t80h\n"
+"\tadd\tesp, byte 16\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:151
+msgid ""
+"The `5` that we have placed in `EAX` identifies the kernel function, in this "
+"case `open`."
+msgstr ""
+"Помещённое в `EAX` значение `5` идентифицирует функцию ядра, в данном случае "
+"`open`."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:153
+#, no-wrap
+msgid "Alternate Calling Convention"
+msgstr "Альтернативное соглашение о вызовах"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:158
+msgid ""
+"FreeBSD is an extremely flexible system. It offers other ways of calling "
+"the kernel. For it to work, however, the system must have Linux emulation "
+"installed."
+msgstr ""
+"FreeBSD — это чрезвычайно гибкая система. Она предлагает другие способы "
+"вызова ядра. Однако для работы необходимо, чтобы в системе была установлена "
+"эмуляция Linux."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:163
+msgid ""
+"Linux is a UNIX(R) like system. However, its kernel uses the same system-"
+"call convention of passing parameters in registers MS-DOS(R) does. As with "
+"the UNIX(R) convention, the function number is placed in `EAX`. The "
+"parameters, however, are not passed on the stack but in `EBX, ECX, EDX, ESI, "
+"EDI, EBP`:"
+msgstr ""
+"Linux — это система, подобная UNIX(R). Однако ее ядро использует то же "
+"соглашение о системных вызовов для передачи параметров в регистрах, что и MS-"
+"DOS(R). Как и в соглашении UNIX(R), номер функции помещается в `EAX`. Однако "
+"параметры передаются не в стеке, а в регистрах `EBX, ECX, EDX, ESI, EDI, "
+"EBP`:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:172
+#, no-wrap
+msgid ""
+"open:\n"
+"\tmov\teax, 5\n"
+"\tmov\tebx, path\n"
+"\tmov\tecx, flags\n"
+"\tmov\tedx, mode\n"
+"\tint\t80h\n"
+msgstr ""
+"open:\n"
+"\tmov\teax, 5\n"
+"\tmov\tebx, path\n"
+"\tmov\tecx, flags\n"
+"\tmov\tedx, mode\n"
+"\tint\t80h\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:178
+msgid ""
+"This convention has a great disadvantage over the UNIX(R) way, at least as "
+"far as assembly language programming is concerned: Every time you make a "
+"kernel call you must `push` the registers, then `pop` them later. This "
+"makes your code bulkier and slower. Nevertheless, FreeBSD gives you a "
+"choice."
+msgstr ""
+"Этот подход имеет значительный недостаток по сравнению с UNIX(R), по крайней "
+"мере, в контексте программирования на ассемблере: каждый раз при вызове ядра "
+"необходимо сохранять регистры с помощью `push`, а затем восстанавливать их с "
+"помощью `pop`. Это делает ваш код более громоздким и медленным. Тем не "
+"менее, FreeBSD предоставляет вам выбор."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:181
+msgid ""
+"If you do choose the Linux convention, you must let the system know about "
+"it. After your program is assembled and linked, you need to brand the "
+"executable:"
+msgstr ""
+"Если вы решите использовать соглашение Linux, вы должны сообщить об этом "
+"системе. После того как ваша программа будет ассемблирована и слинкована, "
+"вам нужно пометить исполняемый файл:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:185
+#, no-wrap
+msgid "% brandelf -t Linux filename\n"
+msgstr "% brandelf -t Linux filename\n"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:188
+#, no-wrap
+msgid "Which Convention Should You Use?"
+msgstr "Какое соглашение следует использовать?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:193
+msgid ""
+"If you are coding specifically for FreeBSD, you should always use the "
+"UNIX(R) convention: It is faster, you can store global variables in "
+"registers, you do not have to brand the executable, and you do not impose "
+"the installation of the Linux emulation package on the target system."
+msgstr ""
+"Если вы разрабатываете код специально для FreeBSD, всегда следует "
+"использовать соглашение UNIX(R): это быстрее, вы можете хранить глобальные "
+"переменные в регистрах, вам не нужно маркировать исполняемый файл, и вы не "
+"требуете установки пакета эмуляции Linux на целевой системе."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:196
+msgid ""
+"If you want to create portable code that can also run on Linux, you will "
+"probably still want to give the FreeBSD users as efficient a code as "
+"possible. I will show you how you can accomplish that after I have "
+"explained the basics."
+msgstr ""
+"Хотя вы можете хотеть создать переносимый код, который также работает на "
+"Linux, вам, вероятно, по-прежнему будет нужен максимально эффективный код "
+"для пользователей FreeBSD. Я покажу вам, как этого добиться, после того как "
+"объясню основы."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:198
+#, no-wrap
+msgid "Call Numbers"
+msgstr "Номера вызовов"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:202
+msgid ""
+"To tell the kernel which system service you are calling, place its number in "
+"`EAX`. Of course, you need to know what the number is."
+msgstr ""
+"Чтобы сообщить ядру, какую системную службу вы вызываете, поместите её номер "
+"в `EAX`. Разумеется, вам необходимо знать, что это за номер."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:204
+#, no-wrap
+msgid "The [.filename]#syscalls# File"
+msgstr "Файл [.filename]#syscalls#"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:208
+msgid ""
+"The numbers are listed in [.filename]#syscalls#. `locate syscalls` finds "
+"this file in several different formats, all produced automatically from [."
+"filename]#syscalls.master#."
+msgstr ""
+"Номера перечислены в [.filename]#syscalls#. Команда `locate syscalls` "
+"находит этот файл в нескольких различных форматах, все они создаются "
+"автоматически из [.filename]#syscalls.master#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:211
+msgid ""
+"You can find the master file for the default UNIX(R) calling convention in [."
+"filename]#/usr/src/sys/kern/syscalls.master#. If you need to use the other "
+"convention implemented in the Linux emulation mode, read [.filename]#/usr/"
+"src/sys/i386/linux/syscalls.master#."
+msgstr ""
+"Основной файл для стандартного соглашения о вызовах UNIX(R) можно найти в [."
+"filename]#/usr/src/sys/kern/syscalls.master#. Если вам необходимо "
+"использовать другое соглашение, реализованное в режиме эмуляции Linux, "
+"обратитесь к [.filename]#/usr/src/sys/i386/linux/syscalls.master#."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:215
+msgid ""
+"Not only do FreeBSD and Linux use different calling conventions, they "
+"sometimes use different numbers for the same functions."
+msgstr ""
+"Не только FreeBSD и Linux используют разные соглашения о вызовах, но иногда "
+"они используют разные номера для одних и тех же функций."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:218
+msgid "[.filename]#syscalls.master# describes how the call is to be made:"
+msgstr ""
+"[.filename]#syscalls.master# описывает, как должен быть выполнен вызов:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:229
+#, no-wrap
+msgid ""
+"0\tSTD\tNOHIDE\t{ int nosys(void); } syscall nosys_args int\n"
+"1\tSTD\tNOHIDE\t{ void exit(int rval); } exit rexit_args void\n"
+"2\tSTD\tPOSIX\t{ int fork(void); }\n"
+"3\tSTD\tPOSIX\t{ ssize_t read(int fd, void *buf, size_t nbyte); }\n"
+"4\tSTD\tPOSIX\t{ ssize_t write(int fd, const void *buf, size_t nbyte); }\n"
+"5\tSTD\tPOSIX\t{ int open(char *path, int flags, int mode); }\n"
+"6\tSTD\tPOSIX\t{ int close(int fd); }\n"
+"etc...\n"
+msgstr ""
+"0\tSTD\tNOHIDE\t{ int nosys(void); } syscall nosys_args int\n"
+"1\tSTD\tNOHIDE\t{ void exit(int rval); } exit rexit_args void\n"
+"2\tSTD\tPOSIX\t{ int fork(void); }\n"
+"3\tSTD\tPOSIX\t{ ssize_t read(int fd, void *buf, size_t nbyte); }\n"
+"4\tSTD\tPOSIX\t{ ssize_t write(int fd, const void *buf, size_t nbyte); }\n"
+"5\tSTD\tPOSIX\t{ int open(char *path, int flags, int mode); }\n"
+"6\tSTD\tPOSIX\t{ int close(int fd); }\n"
+"etc...\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:232
+msgid "It is the leftmost column that tells us the number to place in `EAX`."
+msgstr ""
+"Это крайний левый столбец, который указывает число, которое нужно поместить "
+"в `EAX`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:235
+msgid ""
+"The rightmost column tells us what parameters to `push`. They are "
+"``push``ed _from right to left_."
+msgstr ""
+"Самый правый столбец указывает, какие параметры нужно `втолкнуть` в стек "
+"командой push. Они `вталкиваются` _справа налево_."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:237
+msgid ""
+"For example, to `open` a file, we need to `push` the `mode` first, then "
+"`flags`, then the address at which the `path` is stored."
+msgstr ""
+"Например, чтобы `открыть` файл, нам сначала нужно сделать `push` для `mode`, "
+"затем `flags`, а затем адрес, по которому хранится `path`."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:239
+#, no-wrap
+msgid "Return Values"
+msgstr "Возвращаемые значения"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:243
+msgid ""
+"A system call would not be useful most of the time if it did not return some "
+"kind of a value: The file descriptor of an open file, the number of bytes "
+"read to a buffer, the system time, etc."
+msgstr ""
+"От системных вызовов не было бы никакой пользы, если бы они не возвращали "
+"какое-либо значение: дескриптор открытого файла, количество байтов, "
+"прочитанных в буфер, системное время и т.д."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:246
+msgid ""
+"Additionally, the system needs to inform us if an error occurs: A file does "
+"not exist, system resources are exhausted, we passed an invalid parameter, "
+"etc."
+msgstr ""
+"Кроме того, система должна уведомлять нас, если возникает ошибка: файл не "
+"существует, системные ресурсы исчерпаны, передан недопустимый параметр и т. "
+"д."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:248
+#, no-wrap
+msgid "Man Pages"
+msgstr "Страницы Справочника"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:252
+msgid ""
+"The traditional place to look for information about various system calls "
+"under UNIX(R) systems are the manual pages. FreeBSD describes its system "
+"calls in section 2, sometimes in section 3."
+msgstr ""
+"Традиционным источником информации о различных системных вызовах в UNIX(R)-"
+"системах являются страницы Справочника. В FreeBSD системные вызовы описаны в "
+"разделе 2, иногда в разделе 3."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:254
+msgid "For example, man:open[2] says:"
+msgstr "Например, man:open[2] говорит:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:258
+msgid ""
+"If successful, `open()` returns a non-negative integer, termed a file "
+"descriptor. It returns `-1` on failure, and sets `errno` to indicate the "
+"error."
+msgstr ""
+"В случае успеха `open()` возвращает неотрицательное целое число, называемое "
+"файловым дескриптором. В случае ошибки возвращается `-1`, а переменной "
+"`errno` присваивается код ошибки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:260
+msgid ""
+"The assembly language programmer new to UNIX(R) and FreeBSD will immediately "
+"ask the puzzling question: Where is `errno` and how do I get to it?"
+msgstr ""
+"Программист на ассемблере, впервые столкнувшийся с UNIX(R) и FreeBSD, сразу "
+"же задастся вопросом: где находится `errno` и как к ней обратиться?"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:265
+msgid ""
+"The information presented in the manual pages applies to C programs. The "
+"assembly language programmer needs additional information."
+msgstr ""
+"Информация, представленная в руководствах, применима к программам на языке "
+"C. Программистам на языке ассемблера требуется дополнительная информация."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:268
+#, no-wrap
+msgid "Where Are the Return Values?"
+msgstr "Где возвращаемые значения?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:273
+msgid ""
+"Unfortunately, it depends... For most system calls it is in `EAX`, but not "
+"for all. A good rule of thumb, when working with a system call for the "
+"first time, is to look for the return value in `EAX`. If it is not there, "
+"you need further research."
+msgstr ""
+"К сожалению, это зависит от ситуации... Для большинства системных вызовов "
+"возвращаемое значение находится в `EAX`, но не для всех. Хорошее правило при "
+"первой работе с системным вызовом — искать возвращаемое значение в `EAX`. "
+"Если его там нет, потребуется дополнительное исследование."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:279
+msgid ""
+"I am aware of one system call that returns the value in `EDX`: `SYS_fork`. "
+"All others I have worked with use `EAX`. But I have not worked with them "
+"all yet."
+msgstr ""
+"Я знаю о одном системном вызове, который возвращает значение в `EDX`: "
+"`SYS_fork`. Все остальные, с которыми я работал, используют `EAX`. Но я еще "
+"не работал со всеми из них."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:284
+msgid ""
+"If you cannot find the answer here or anywhere else, study libc source code "
+"and see how it interfaces with the kernel."
+msgstr ""
+"Если вы не можете найти ответ здесь или где-либо ещё, изучите исходный код "
+"libc и посмотрите, как он взаимодействует с ядром."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:287
+#, no-wrap
+msgid "Where Is `errno`?"
+msgstr "Где находится `errno`?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:290
+msgid "Actually, nowhere..."
+msgstr "Фактически, нигде..."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:293
+msgid ""
+"`errno` is part of the C language, not the UNIX(R) kernel. When accessing "
+"kernel services directly, the error code is returned in `EAX`, the same "
+"register the proper return value generally ends up in."
+msgstr ""
+"`errno` является частью языка C, а не ядра UNIX(R). При прямом доступе к "
+"сервисам ядра код ошибки возвращается в регистре `EAX` — том же регистре, в "
+"котором обычно оказывается корректное возвращаемое значение."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:297
+msgid ""
+"This makes perfect sense. If there is no error, there is no error code. If "
+"there is an error, there is no return value. One register can contain "
+"either."
+msgstr ""
+"Это совершенно логично. Если нет ошибки, то нет и кода ошибки. Если есть "
+"ошибка, то нет возвращаемого значения. Один регистр может содержать либо то, "
+"либо другое."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:299
+#, no-wrap
+msgid "Determining an Error Occurred"
+msgstr "Определение возникновения ошибки"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:302
+msgid ""
+"When using the standard FreeBSD calling convention, the `carry flag` is "
+"cleared upon success, set upon failure."
+msgstr ""
+"При использовании стандартного соглашения о вызовах FreeBSD флаг `carry "
+"flag` сбрасывается при успехе и устанавливается при неудаче."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:305
+msgid ""
+"When using the Linux emulation mode, the signed value in `EAX` is non-"
+"negative upon success, and contains the return value. In case of an error, "
+"the value is negative, i.e., `-errno`."
+msgstr ""
+"При использовании режима эмуляции Linux знаковое значение в `EAX` "
+"неотрицательно в случае успеха и содержит возвращаемое значение. В случае "
+"ошибки значение отрицательное, т.е. `-errno`."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:307
+#, no-wrap
+msgid "Creating Portable Code"
+msgstr "Создание переносимого кода"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:312
+msgid ""
+"Portability is generally not one of the strengths of assembly language. "
+"Yet, writing assembly language programs for different platforms is possible, "
+"especially with nasm. I have written assembly language libraries that can "
+"be assembled for such different operating systems as Windows(R) and FreeBSD."
+msgstr ""
+"Портативность обычно не является сильной стороной языка ассемблера. Тем не "
+"менее, написание программ на ассемблере для разных платформ возможно, "
+"особенно с использованием nasm. Я создавал библиотеки на ассемблере, которые "
+"можно было собрать для таких разных операционных систем, как Windows(R) и "
+"FreeBSD."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:314
+msgid ""
+"It is all the more possible when you want your code to run on two platforms "
+"which, while different, are based on similar architectures."
+msgstr ""
+"Это становится еще более возможным, когда вы хотите, чтобы ваш код работал "
+"на двух платформах, которые, хотя и различны, основаны на схожих "
+"архитектурах."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:318
+msgid ""
+"For example, FreeBSD is UNIX(R), Linux is UNIX(R) like. I only mentioned "
+"three differences between them (from an assembly language programmer's "
+"perspective): The calling convention, the function numbers, and the way of "
+"returning values."
+msgstr ""
+"Например, FreeBSD — это UNIX(R), а Linux — UNIX(R)-подобная система. Я "
+"упомянул лишь три различия между ними (с точки зрения программиста на "
+"ассемблере): соглашение о вызовах, номера функций и способ возврата значений."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:320
+#, no-wrap
+msgid "Dealing with Function Numbers"
+msgstr "Работа с номерами функций"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:325
+msgid ""
+"In many cases the function numbers are the same. However, even when they "
+"are not, the problem is easy to deal with: Instead of using numbers in your "
+"code, use constants which you have declared differently depending on the "
+"target architecture:"
+msgstr ""
+"Во многих случаях номера функций совпадают. Однако, даже если это не так, "
+"проблему легко решить: вместо использования чисел в коде применяйте "
+"константы, объявленные по-разному в зависимости от целевой архитектуры:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:333
+#, no-wrap
+msgid ""
+"%ifdef\tLINUX\n"
+"%define\tSYS_execve\t11\n"
+"%else\n"
+"%define\tSYS_execve\t59\n"
+"%endif\n"
+msgstr ""
+"%ifdef\tLINUX\n"
+"%define\tSYS_execve\t11\n"
+"%else\n"
+"%define\tSYS_execve\t59\n"
+"%endif\n"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:336
+#, no-wrap
+msgid "Dealing with Conventions"
+msgstr "Работа с соглашениями"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:339
+msgid ""
+"Both, the calling convention, and the return value (the `errno` problem) can "
+"be resolved with macros:"
+msgstr ""
+"Оба, соглашение о вызовах и возвращаемое значение (проблема `errno`) могут "
+"быть решены с помощью макросов:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:343
+#, no-wrap
+msgid "%ifdef\tLINUX\n"
+msgstr "%ifdef\tLINUX\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:347
+#, no-wrap
+msgid ""
+"%macro\tsystem\t0\n"
+"\tcall\tkernel\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsystem\t0\n"
+"\tcall\tkernel\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:356
+#, no-wrap
+msgid ""
+"align 4\n"
+"kernel:\n"
+"\tpush\tebx\n"
+"\tpush\tecx\n"
+"\tpush\tedx\n"
+"\tpush\tesi\n"
+"\tpush\tedi\n"
+"\tpush\tebp\n"
+msgstr ""
+"align 4\n"
+"kernel:\n"
+"\tpush\tebx\n"
+"\tpush\tecx\n"
+"\tpush\tedx\n"
+"\tpush\tesi\n"
+"\tpush\tedi\n"
+"\tpush\tebp\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:363
+#, no-wrap
+msgid ""
+"\tmov\tebx, [esp+32]\n"
+"\tmov\tecx, [esp+36]\n"
+"\tmov\tedx, [esp+40]\n"
+"\tmov\tesi, [esp+44]\n"
+"\tmov\tebp, [esp+48]\n"
+"\tint\t80h\n"
+msgstr ""
+"\tmov\tebx, [esp+32]\n"
+"\tmov\tecx, [esp+36]\n"
+"\tmov\tedx, [esp+40]\n"
+"\tmov\tesi, [esp+44]\n"
+"\tmov\tebp, [esp+48]\n"
+"\tint\t80h\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:370
+#, no-wrap
+msgid ""
+"\tpop\tebp\n"
+"\tpop\tedi\n"
+"\tpop\tesi\n"
+"\tpop\tedx\n"
+"\tpop\tecx\n"
+"\tpop\tebx\n"
+msgstr ""
+"\tpop\tebp\n"
+"\tpop\tedi\n"
+"\tpop\tesi\n"
+"\tpop\tedx\n"
+"\tpop\tecx\n"
+"\tpop\tebx\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:375
+#, no-wrap
+msgid ""
+"\tor\teax, eax\n"
+"\tjs\t.errno\n"
+"\tclc\n"
+"\tret\n"
+msgstr ""
+"\tor\teax, eax\n"
+"\tjs\t.errno\n"
+"\tclc\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:380
+#, no-wrap
+msgid ""
+".errno:\n"
+"\tneg\teax\n"
+"\tstc\n"
+"\tret\n"
+msgstr ""
+".errno:\n"
+"\tneg\teax\n"
+"\tstc\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:382
+#, no-wrap
+msgid "%else\n"
+msgstr "%else\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:386
+#, no-wrap
+msgid ""
+"%macro\tsystem\t0\n"
+"\tint\t80h\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsystem\t0\n"
+"\tint\t80h\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:388
+#, no-wrap
+msgid "%endif\n"
+msgstr "%endif\n"
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:391
+#, no-wrap
+msgid "Dealing with Other Portability Issues"
+msgstr "Устранение прочих проблем с переносимостью"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:395
+msgid ""
+"The above solutions can handle most cases of writing code portable between "
+"FreeBSD and Linux. Nevertheless, with some kernel services the differences "
+"are deeper."
+msgstr ""
+"Приведённые выше решения могут помочь в большинстве случаев написания кода, "
+"переносимого между FreeBSD и Linux. Тем не менее, с некоторыми сервисами "
+"ядра различия более глубокие."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:398
+msgid ""
+"In that case, you need to write two different handlers for those particular "
+"system calls, and use conditional assembly. Luckily, most of your code does "
+"something other than calling the kernel, so usually you will only need a few "
+"such conditional sections in your code."
+msgstr ""
+"В таком случае необходимо написать два разных обработчика для этих "
+"конкретных системных вызовов и использовать условную компиляцию. К счастью, "
+"большая часть вашего кода выполняет действия, отличные от вызовов ядра, "
+"поэтому обычно потребуется лишь несколько таких условных секций в коде."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:400
+#, no-wrap
+msgid "Using a Library"
+msgstr "Использование библиотеки"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:404
+msgid ""
+"You can avoid portability issues in your main code altogether by writing a "
+"library of system calls. Create a separate library for FreeBSD, a different "
+"one for Linux, and yet other libraries for more operating systems."
+msgstr ""
+"Вы можете полностью избежать проблем с переносимостью в основном коде, "
+"написав библиотеку системных вызовов. Создайте отдельную библиотеку для "
+"FreeBSD, другую для Linux и ещё другие библиотеки для дополнительных "
+"операционных систем."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:409
+msgid ""
+"In your library, write a separate function (or procedure, if you prefer the "
+"traditional assembly language terminology) for each system call. Use the C "
+"calling convention of passing parameters. But still use `EAX` to pass the "
+"call number in. In that case, your FreeBSD library can be very simple, as "
+"many seemingly different functions can be just labels to the same code:"
+msgstr ""
+"В вашей библиотеке напишите отдельную функцию (или процедуру, если вы "
+"предпочитаете традиционную терминологию ассемблера) для каждого системного "
+"вызова. Используйте соглашение о вызовах C для передачи параметров. Однако "
+"по-прежнему передавайте номер вызова через `EAX`. В таком случае ваша "
+"библиотека FreeBSD может быть очень простой, так как множество внешне "
+"различных функций могут быть просто метками одного и того же кода:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:417
+#, no-wrap
+msgid ""
+"sys.open:\n"
+"sys.close:\n"
+"[etc...]\n"
+"\tint\t80h\n"
+"\tret\n"
+msgstr ""
+"sys.open:\n"
+"sys.close:\n"
+"[etc...]\n"
+"\tint\t80h\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:421
+msgid ""
+"Your Linux library will require more different functions. But even here you "
+"can group system calls using the same number of parameters:"
+msgstr ""
+"Ваша библиотека Linux потребует больше различных функций. Но даже здесь вы "
+"можете группировать системные вызовы, используя одинаковое количество "
+"параметров:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:432
+#, no-wrap
+msgid ""
+"sys.exit:\n"
+"sys.close:\n"
+"[etc... one-parameter functions]\n"
+"\tpush\tebx\n"
+"\tmov\tebx, [esp+12]\n"
+"\tint\t80h\n"
+"\tpop\tebx\n"
+"\tjmp\tsys.return\n"
+msgstr ""
+"sys.exit:\n"
+"sys.close:\n"
+"[etc... one-parameter functions]\n"
+"\tpush\tebx\n"
+"\tmov\tebx, [esp+12]\n"
+"\tint\t80h\n"
+"\tpop\tebx\n"
+"\tjmp\tsys.return\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:434
+#, no-wrap
+msgid "...\n"
+msgstr "...\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:440
+#, no-wrap
+msgid ""
+"sys.return:\n"
+"\tor\teax, eax\n"
+"\tjs\tsys.err\n"
+"\tclc\n"
+"\tret\n"
+msgstr ""
+"sys.return:\n"
+"\tor\teax, eax\n"
+"\tjs\tsys.err\n"
+"\tclc\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:445
+#, no-wrap
+msgid ""
+"sys.err:\n"
+"\tneg\teax\n"
+"\tstc\n"
+"\tret\n"
+msgstr ""
+"sys.err:\n"
+"\tneg\teax\n"
+"\tstc\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:452
+msgid ""
+"The library approach may seem inconvenient at first because it requires you "
+"to produce a separate file your code depends on. But it has many "
+"advantages: For one, you only need to write it once and can use it for all "
+"your programs. You can even let other assembly language programmers use it, "
+"or perhaps use one written by someone else. But perhaps the greatest "
+"advantage of the library is that your code can be ported to other systems, "
+"even by other programmers, by simply writing a new library without any "
+"changes to your code."
+msgstr ""
+"Подход с использованием библиотек может показаться неудобным на первый "
+"взгляд, так как требует создания отдельного файла, от которого зависит ваш "
+"код. Однако у него есть множество преимуществ: во-первых, вам нужно написать "
+"его лишь один раз, и затем вы можете использовать его во всех своих "
+"программах. Вы даже можете позволить другим программистам на ассемблере "
+"использовать его или, возможно, воспользоваться библиотекой, написанной кем-"
+"то другим. Но, пожалуй, самое большое преимущество библиотеки заключается в "
+"том, что ваш код может быть перенесён на другие системы, даже другими "
+"программистами, просто путём написания новой библиотеки без каких-либо "
+"изменений в вашем коде."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:454
+msgid ""
+"If you do not like the idea of having a library, you can at least place all "
+"your system calls in a separate assembly language file and link it with your "
+"main program. Here, again, all porters have to do is create a new object "
+"file to link with your main program."
+msgstr ""
+"Если вам не нравится идея использования библиотеки, вы можете хотя бы "
+"разместить все системные вызовы в отдельном файле на ассемблере и "
+"скомпоновать его с основной программой. Здесь, опять же, все, что нужно "
+"сделать переносчикам, — это создать новый объектный файл для компоновки с "
+"основной программой."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:456
+#, no-wrap
+msgid "Using an Include File"
+msgstr "Использование включаемого файла"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:459
+msgid ""
+"If you are releasing your software as (or with) source code, you can use "
+"macros and place them in a separate file, which you include in your code."
+msgstr ""
+"Если вы выпускаете своё программное обеспечение в виде исходного кода (или "
+"вместе с ним), вы можете использовать макросы и размещать их в отдельном "
+"файле, который включается в ваш код."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:462
+msgid ""
+"Porters of your software will simply write a new include file. No library "
+"or external object file is necessary, yet your code is portable without any "
+"need to edit the code."
+msgstr ""
+"Портеры вашего программного обеспечения просто напишут новый include-файл. "
+"Никакая библиотека или внешний объектный файл не требуются, и ваш код "
+"остается переносимым без необходимости редактирования."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:467
+msgid ""
+"This is the approach we will use throughout this chapter. We will name our "
+"include file [.filename]#system.inc#, and add to it whenever we deal with a "
+"new system call."
+msgstr ""
+"Это подход, который мы будем использовать на протяжении всей главы. Мы "
+"назовем наш включаемый файл [.filename]#system.inc# и будем добавлять в него "
+"новые системные вызовы по мере их рассмотрения."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:470
+msgid ""
+"We can start our [.filename]#system.inc# by declaring the standard file "
+"descriptors:"
+msgstr ""
+"Мы можем начать наш [.filename]#system.inc# с объявления стандартных "
+"файловых дескрипторов:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:476
+#, no-wrap
+msgid ""
+"%define\tstdin\t0\n"
+"%define\tstdout\t1\n"
+"%define\tstderr\t2\n"
+msgstr ""
+"%define\tstdin\t0\n"
+"%define\tstdout\t1\n"
+"%define\tstderr\t2\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:479
+msgid "Next, we create a symbolic name for each system call:"
+msgstr "Далее мы создаем символическое имя для каждого системного вызова:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:488
+#, no-wrap
+msgid ""
+"%define\tSYS_nosys\t0\n"
+"%define\tSYS_exit\t1\n"
+"%define\tSYS_fork\t2\n"
+"%define\tSYS_read\t3\n"
+"%define\tSYS_write\t4\n"
+"; [etc...]\n"
+msgstr ""
+"%define\tSYS_nosys\t0\n"
+"%define\tSYS_exit\t1\n"
+"%define\tSYS_fork\t2\n"
+"%define\tSYS_read\t3\n"
+"%define\tSYS_write\t4\n"
+"; [etc...]\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:491
+msgid ""
+"We add a short, non-global procedure with a long name, so we do not "
+"accidentally reuse the name in our code:"
+msgstr ""
+"Добавляем короткую, неглобальную процедуру с длинным именем, чтобы случайно "
+"не использовать это имя в нашем коде:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:499
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"align 4\n"
+"access.the.bsd.kernel:\n"
+"\tint\t80h\n"
+"\tret\n"
+msgstr ""
+"section\t.text\n"
+"align 4\n"
+"access.the.bsd.kernel:\n"
+"\tint\t80h\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:502
+msgid "We create a macro which takes one argument, the syscall number:"
+msgstr ""
+"Мы создаем макрос, который принимает один аргумент — номер системного вызова:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:509
+#, no-wrap
+msgid ""
+"%macro\tsystem\t1\n"
+"\tmov\teax, %1\n"
+"\tcall\taccess.the.bsd.kernel\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsystem\t1\n"
+"\tmov\teax, %1\n"
+"\tcall\taccess.the.bsd.kernel\n"
+"%endmacro\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:513
+msgid ""
+"Finally, we create macros for each syscall. These macros take no arguments."
+msgstr ""
+"Наконец, мы создаем макросы для каждого системного вызова. Эти макросы не "
+"принимают аргументов."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:519
+#, no-wrap
+msgid ""
+"%macro\tsys.exit\t0\n"
+"\tsystem\tSYS_exit\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.exit\t0\n"
+"\tsystem\tSYS_exit\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:523
+#, no-wrap
+msgid ""
+"%macro\tsys.fork\t0\n"
+"\tsystem\tSYS_fork\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.fork\t0\n"
+"\tsystem\tSYS_fork\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:527
+#, no-wrap
+msgid ""
+"%macro\tsys.read\t0\n"
+"\tsystem\tSYS_read\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.read\t0\n"
+"\tsystem\tSYS_read\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:531
+#, no-wrap
+msgid ""
+"%macro\tsys.write\t0\n"
+"\tsystem\tSYS_write\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.write\t0\n"
+"\tsystem\tSYS_write\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:533
+#, no-wrap
+msgid "; [etc...]\n"
+msgstr "; [etc...]\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:537
+msgid ""
+"Go ahead, enter it into your editor and save it as [.filename]#system.inc#. "
+"We will add more to it as we discuss more syscalls."
+msgstr ""
+"Продолжайте, введите это в ваш редактор и сохраните как [.filename]#system."
+"inc#. Мы добавим больше по мере обсуждения дополнительных системных вызовов."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:539
+#, no-wrap
+msgid "Our First Program"
+msgstr "Наша первая программа"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:542
+msgid "We are now ready for our first program, the mandatory Hello, World!"
+msgstr "Мы готовы к нашей первой обязательной программе — Hello, World!"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:546
+#, no-wrap
+msgid "\t%include\t'system.inc'\n"
+msgstr "\t%include\t'system.inc'\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:550
+#, no-wrap
+msgid ""
+"\tsection\t.data\n"
+"\thello\tdb\t'Hello, World!', 0Ah\n"
+"\thbytes\tequ\t$-hello\n"
+msgstr ""
+"\tsection\t.data\n"
+"\thello\tdb\t'Hello, World!', 0Ah\n"
+"\thbytes\tequ\t$-hello\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:558
+#, no-wrap
+msgid ""
+"\tsection\t.text\n"
+"\tglobal\t_start\n"
+"_start:\n"
+"\tpush\tdword hbytes\n"
+"\tpush\tdword hello\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+"\tsection\t.text\n"
+"\tglobal\t_start\n"
+"_start:\n"
+"\tpush\tdword hbytes\n"
+"\tpush\tdword hello\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:561
+#, no-wrap
+msgid ""
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:564
+msgid ""
+"Here is what it does: Line 1 includes the defines, the macros, and the code "
+"from [.filename]#system.inc#."
+msgstr ""
+"Вот что он делает: Строка 1 включает определения, макросы и код из файла [."
+"filename]#system.inc#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:568
+msgid ""
+"Lines 3-5 are the data: Line 3 starts the data section/segment. Line 4 "
+"contains the string \"Hello, World!\" followed by a new line (`0Ah`). Line "
+"5 creates a constant that contains the length of the string from line 4 in "
+"bytes."
+msgstr ""
+"Строки 3-5 содержат данные: строка 3 начинает раздел/сегмент данных. Строка "
+"4 содержит строку \"Hello, World!\", за которой следует новая строка "
+"(`0Ah`). Строка 5 создает константу, содержащую длину строки из строки 4 в "
+"байтах."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:572
+msgid ""
+"Lines 7-16 contain the code. Note that FreeBSD uses the _elf_ file format "
+"for its executables, which requires every program to start at the point "
+"labeled `_start` (or, more precisely, the linker expects that). This label "
+"has to be global."
+msgstr ""
+"Строки 7-16 содержат код. Обратите внимание, что FreeBSD использует формат "
+"файлов _elf_ для исполняемых файлов, который требует, чтобы каждая программа "
+"запускается с адреса, помеченного как `_start` (или, точнее, компоновщик "
+"ожидает этого). Эта метка должна быть глобальной."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:574
+msgid ""
+"Lines 10-13 ask the system to write `hbytes` bytes of the `hello` string to "
+"`stdout`."
+msgstr ""
+"Строки 10-13 указывают системе записать `hbytes` байтов строки `hello` в "
+"`stdout`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:577
+msgid ""
+"Lines 15-16 ask the system to end the program with the return value of `0`. "
+"The `SYS_exit` syscall never returns, so the code ends there."
+msgstr ""
+"Строки 15-16 указывают системе завершить программу с возвращаемым значением "
+"`0`. Системный вызов `SYS_exit` никогда не возвращает управление, поэтому "
+"код завершается в этой точке."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:585
+msgid ""
+"If you have come to UNIX(R) from MS-DOS(R) assembly language background, you "
+"may be used to writing directly to the video hardware. You will never have "
+"to worry about this in FreeBSD, or any other flavor of UNIX(R). As far as "
+"you are concerned, you are writing to a file known as [.filename]#stdout#. "
+"This can be the video screen, or a telnet terminal, or an actual file, or "
+"even the input of another program. Which one it is, is for the system to "
+"figure out."
+msgstr ""
+"Если вы перешли на UNIX(R) с опытом программирования на ассемблере для MS-"
+"DOS(R), вы, возможно, привыкли писать напрямую в видеопамять. В FreeBSD или "
+"любой другой разновидности UNIX(R) вам не придётся об этом беспокоиться. С "
+"вашей точки зрения, вы записываете данные в файл под названием [."
+"filename]#stdout#. Это может быть экран, терминал telnet, обычный файл или "
+"даже входные данные другой программы. Определять, что именно это будет, — "
+"задача системы."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:588
+#, no-wrap
+msgid "Assembling the Code"
+msgstr "Ассемблирование кода"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:592
+msgid ""
+"Type the code in an editor, and save it in a file named [.filename]#hello."
+"asm#. You need nasm to assemble it."
+msgstr ""
+"Наберите код в редакторе и сохраните его в файле с именем [.filename]#hello."
+"asm#. Для сборки вам понадобится nasm."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:594
+#, no-wrap
+msgid "Installing nasm"
+msgstr "Установка nasm"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:597
+msgid "If you do not have nasm, type:"
+msgstr "Если у вас нет nasm, введите:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:606
+#, no-wrap
+msgid ""
+"% su\n"
+"Password:your root password\n"
+"# cd /usr/ports/devel/nasm\n"
+"# make install\n"
+"# exit\n"
+"%\n"
+msgstr ""
+"% su\n"
+"Password:your root password\n"
+"# cd /usr/ports/devel/nasm\n"
+"# make install\n"
+"# exit\n"
+"%\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:609
+msgid ""
+"You may type `make install clean` instead of just `make install` if you do "
+"not want to keep nasm source code."
+msgstr ""
+"Вы можете ввести `make install clean` вместо просто `make install`, если не "
+"хотите сохранять исходный код nasm."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:611
+msgid ""
+"Either way, FreeBSD will automatically download nasm from the Internet, "
+"compile it, and install it on your system."
+msgstr ""
+"В любом случае FreeBSD автоматически загрузит nasm из интернета, "
+"скомпилирует его и установит в вашу систему."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:616
+msgid ""
+"If your system is not FreeBSD, you need to get nasm from its https://"
+"sourceforge.net/projects/nasm[home page]. You can still use it to assemble "
+"FreeBSD code."
+msgstr ""
+"Если ваша система не FreeBSD, вам нужно получить nasm с его https://"
+"sourceforge.net/projects/nasm[домашней страницы]. Вы по-прежнему можете "
+"использовать его для ассемблирования кода FreeBSD."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:619
+msgid "Now you can assemble, link, and run the code:"
+msgstr "Теперь вы можете собрать, скомпоновать и запустить код:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:627
+#, no-wrap
+msgid ""
+"% nasm -f elf hello.asm\n"
+"% ld -s -o hello hello.o\n"
+"% ./hello\n"
+"Hello, World!\n"
+"%\n"
+msgstr ""
+"% nasm -f elf hello.asm\n"
+"% ld -s -o hello hello.o\n"
+"% ./hello\n"
+"Hello, World!\n"
+"%\n"
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:630
+#, no-wrap
+msgid "Writing UNIX(R) Filters"
+msgstr "Написание фильтров UNIX(R)"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:633
+msgid ""
+"A common type of UNIX(R) application is a filter-a program that reads data "
+"from the [.filename]#stdin#, processes it somehow, then writes the result to "
+"[.filename]#stdout#."
+msgstr ""
+"Распространённым типом приложений в UNIX(R) являются фильтры — программы, "
+"которые читают данные из [.filename]#stdin#, обрабатывают их определённым "
+"образом, а затем записывают результат в [.filename]#stdout#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:636
+msgid ""
+"In this chapter, we shall develop a simple filter, and learn how to read "
+"from [.filename]#stdin# and write to [.filename]#stdout#. This filter will "
+"convert each byte of its input into a hexadecimal number followed by a blank "
+"space."
+msgstr ""
+"В этой главе мы разработаем простой фильтр и научимся читать из [."
+"filename]#stdin# и писать в [.filename]#stdout#. Этот фильтр будет "
+"преобразовывать каждый байт входных данных в шестнадцатеричное число, за "
+"которым следует пробел."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:640
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:734
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:824
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:952
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1219
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2337
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3335
+#, no-wrap
+msgid "%include\t'system.inc'\n"
+msgstr "%include\t'system.inc'\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:644
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:738
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"hex\tdb\t'0123456789ABCDEF'\n"
+"buffer\tdb\t0, 0, ' '\n"
+msgstr ""
+"section\t.data\n"
+"hex\tdb\t'0123456789ABCDEF'\n"
+"buffer\tdb\t0, 0, ' '\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:656
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"global\t_start\n"
+"_start:\n"
+"\t; read a byte from stdin\n"
+"\tpush\tdword 1\n"
+"\tpush\tdword buffer\n"
+"\tpush\tdword stdin\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+msgstr ""
+"section\t.text\n"
+"global\t_start\n"
+"_start:\n"
+"\t; read a byte from stdin\n"
+"\tpush\tdword 1\n"
+"\tpush\tdword buffer\n"
+"\tpush\tdword stdin\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:666
+#, no-wrap
+msgid ""
+"\t; convert it to hex\n"
+"\tmovzx\teax, byte [buffer]\n"
+"\tmov\tedx, eax\n"
+"\tshr\tdl, 4\n"
+"\tmov\tdl, [hex+edx]\n"
+"\tmov\t[buffer], dl\n"
+"\tand\tal, 0Fh\n"
+"\tmov\tal, [hex+eax]\n"
+"\tmov\t[buffer+1], al\n"
+msgstr ""
+"\t; convert it to hex\n"
+"\tmovzx\teax, byte [buffer]\n"
+"\tmov\tedx, eax\n"
+"\tshr\tdl, 4\n"
+"\tmov\tdl, [hex+edx]\n"
+"\tmov\t[buffer], dl\n"
+"\tand\tal, 0Fh\n"
+"\tmov\tal, [hex+eax]\n"
+"\tmov\t[buffer+1], al\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:674
+#, no-wrap
+msgid ""
+"\t; print it\n"
+"\tpush\tdword 3\n"
+"\tpush\tdword buffer\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tjmp\tshort _start\n"
+msgstr ""
+"\t; print it\n"
+"\tpush\tdword 3\n"
+"\tpush\tdword buffer\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tjmp\tshort _start\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:678
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:781
+#, no-wrap
+msgid ""
+".done:\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+".done:\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:686
+msgid ""
+"In the data section we create an array called `hex`. It contains the 16 "
+"hexadecimal digits in ascending order. The array is followed by a buffer "
+"which we will use for both input and output. The first two bytes of the "
+"buffer are initially set to `0`. This is where we will write the two "
+"hexadecimal digits (the first byte also is where we will read the input). "
+"The third byte is a space."
+msgstr ""
+"В разделе данных мы создаем массив с именем `hex`. Он содержит 16 "
+"шестнадцатеричных цифр в порядке возрастания. За массивом следует буфер, "
+"который мы будем использовать как для ввода, так и для вывода. Первые два "
+"байта буфера изначально установлены в `0`. Именно сюда мы будем записывать "
+"две шестнадцатеричные цифры (первый байт также является местом, откуда мы "
+"будем считывать ввод). Третий байт — это пробел."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:688
+msgid ""
+"The code section consists of four parts: Reading the byte, converting it to "
+"a hexadecimal number, writing the result, and eventually exiting the program."
+msgstr ""
+"Фрагмент кода состоит из четырех частей: чтение байта, преобразование его в "
+"шестнадцатеричное число, запись результата и завершение программы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:694
+msgid ""
+"To read the byte, we ask the system to read one byte from [."
+"filename]#stdin#, and store it in the first byte of the `buffer`. The "
+"system returns the number of bytes read in `EAX`. This will be `1` while "
+"data is coming, or `0`, when no more input data is available. Therefore, we "
+"check the value of `EAX`. If it is `0`, we jump to `.done`, otherwise we "
+"continue."
+msgstr ""
+"Для чтения байта мы просим систему прочитать один байт из [.filename]#stdin# "
+"и сохранить его в первом байте `buffer`. Система возвращает количество "
+"прочитанных байтов в `EAX`. Это значение будет `1`, пока поступают данные, "
+"или `0`, если больше нет доступных входных данных. Поэтому мы проверяем "
+"значение `EAX`. Если оно равно `0`, мы переходим к метке `.done`, в "
+"противном случае продолжаем выполнение."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:698
+msgid ""
+"For simplicity sake, we are ignoring the possibility of an error condition "
+"at this time."
+msgstr "Для простоты мы пока игнорируем возможность возникновения ошибки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:703
+msgid ""
+"The hexadecimal conversion reads the byte from the `buffer` into `EAX`, or "
+"actually just `AL`, while clearing the remaining bits of `EAX` to zeros. We "
+"also copy the byte to `EDX` because we need to convert the upper four bits "
+"(nibble) separately from the lower four bits. We store the result in the "
+"first two bytes of the buffer."
+msgstr ""
+"Шестнадцатеричное преобразование считывает байт из `buffer` в `EAX`, а "
+"точнее только в `AL`, обнуляя остальные биты `EAX`. Мы также копируем байт в "
+"`EDX`, потому что нам нужно преобразовать верхние четыре бита (ниббл) "
+"отдельно от нижних четырех битов. Результат сохраняется в первых двух байтах "
+"буфера."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:706
+msgid ""
+"Next, we ask the system to write the three bytes of the buffer, i.e., the "
+"two hexadecimal digits and the blank space, to [.filename]#stdout#. We then "
+"jump back to the beginning of the program and process the next byte."
+msgstr ""
+"Далее мы просим систему записать три байта буфера, то есть две "
+"шестнадцатеричные цифры и пробел, в [.filename]#stdout#. Затем мы "
+"возвращаемся к началу программы и обрабатываем следующий байт."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:708
+msgid ""
+"Once there is no more input left, we ask the system to exit our program, "
+"returning a zero, which is the traditional value meaning the program was "
+"successful."
+msgstr ""
+"Когда ввод больше не остаётся, мы просим систему завершить нашу программу, "
+"возвращая ноль, что традиционно означает успешное выполнение программы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:710
+msgid ""
+"Go ahead, and save the code in a file named [.filename]#hex.asm#, then type "
+"the following (the `^D` means press the control key and type `D` while "
+"holding the control key down):"
+msgstr ""
+"Продолжайте и сохраните код в файле с именем [.filename]#hex.asm#, затем "
+"введите следующее (символ `^D` означает, что нужно нажать клавишу управления "
+"и, удерживая её, ввести `D`):"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:719
+#, no-wrap
+msgid ""
+"% nasm -f elf hex.asm\n"
+"% ld -s -o hex hex.o\n"
+"% ./hex\n"
+"Hello, World!\n"
+"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A Here I come!\n"
+"48 65 72 65 20 49 20 63 6F 6D 65 21 0A ^D %\n"
+msgstr ""
+"% nasm -f elf hex.asm\n"
+"% ld -s -o hex hex.o\n"
+"% ./hex\n"
+"Hello, World!\n"
+"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A Here I come!\n"
+"48 65 72 65 20 49 20 63 6F 6D 65 21 0A ^D %\n"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:725
+msgid ""
+"If you are migrating to UNIX(R) from MS-DOS(R), you may be wondering why "
+"each line ends with `0A` instead of `0D 0A`. This is because UNIX(R) does "
+"not use the cr/lf convention, but a \"new line\" convention, which is `0A` "
+"in hexadecimal."
+msgstr ""
+"Если вы переходите на UNIX(R) с MS-DOS(R), вам может быть интересно, почему "
+"каждая строка заканчивается на `0A` вместо `0D 0A`. Это связано с тем, что "
+"UNIX(R) не использует соглашение cr/lf, а использует соглашение \"новая "
+"строка\", которое в шестнадцатеричном виде представлено как `0A`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:730
+msgid ""
+"Can we improve this? Well, for one, it is a bit confusing because once we "
+"have converted a line of text, our input no longer starts at the beginning "
+"of the line. We can modify it to print a new line instead of a space after "
+"each `0A`:"
+msgstr ""
+"Можем ли мы это улучшить? Что ж, во-первых, это немного запутанно, потому "
+"что после преобразования строки текста наш ввод больше не начинается с "
+"начала строки. Мы можем изменить это, чтобы после каждого `0A` выводилась "
+"новая строка вместо пробела:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:743
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"global\t_start\n"
+"_start:\n"
+"\tmov\tcl, ' '\n"
+msgstr ""
+"section\t.text\n"
+"global\t_start\n"
+"_start:\n"
+"\tmov\tcl, ' '\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:753
+#, no-wrap
+msgid ""
+".loop:\n"
+"\t; read a byte from stdin\n"
+"\tpush\tdword 1\n"
+"\tpush\tdword buffer\n"
+"\tpush\tdword stdin\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+msgstr ""
+".loop:\n"
+"\t; read a byte from stdin\n"
+"\tpush\tdword 1\n"
+"\tpush\tdword buffer\n"
+"\tpush\tdword stdin\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:760
+#, no-wrap
+msgid ""
+"\t; convert it to hex\n"
+"\tmovzx\teax, byte [buffer]\n"
+"\tmov\t[buffer+2], cl\n"
+"\tcmp\tal, 0Ah\n"
+"\tjne\t.hex\n"
+"\tmov\t[buffer+2], al\n"
+msgstr ""
+"\t; convert it to hex\n"
+"\tmovzx\teax, byte [buffer]\n"
+"\tmov\t[buffer+2], cl\n"
+"\tcmp\tal, 0Ah\n"
+"\tjne\t.hex\n"
+"\tmov\t[buffer+2], al\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:769
+#, no-wrap
+msgid ""
+".hex:\n"
+"\tmov\tedx, eax\n"
+"\tshr\tdl, 4\n"
+"\tmov\tdl, [hex+edx]\n"
+"\tmov\t[buffer], dl\n"
+"\tand\tal, 0Fh\n"
+"\tmov\tal, [hex+eax]\n"
+"\tmov\t[buffer+1], al\n"
+msgstr ""
+".hex:\n"
+"\tmov\tedx, eax\n"
+"\tshr\tdl, 4\n"
+"\tmov\tdl, [hex+edx]\n"
+"\tmov\t[buffer], dl\n"
+"\tand\tal, 0Fh\n"
+"\tmov\tal, [hex+eax]\n"
+"\tmov\t[buffer+1], al\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:777
+#, no-wrap
+msgid ""
+"\t; print it\n"
+"\tpush\tdword 3\n"
+"\tpush\tdword buffer\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tjmp\tshort .loop\n"
+msgstr ""
+"\t; print it\n"
+"\tpush\tdword 3\n"
+"\tpush\tdword buffer\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tjmp\tshort .loop\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:785
+msgid ""
+"We have stored the space in the `CL` register. We can do this safely "
+"because, unlike Microsoft(R) Windows(R), UNIX(R) system calls do not modify "
+"the value of any register they do not use to return a value in."
+msgstr ""
+"Мы сохранили пробел в регистре `CL`. Это безопасно, потому что, в отличие от "
+"Microsoft(R) Windows(R), вызовы системы UNIX(R) не изменяют значение "
+"регистров, которые не используются для возврата значения."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:789
+msgid ""
+"That means we only need to set `CL` once. We have, therefore, added a new "
+"label `.loop` and jump to it for the next byte instead of jumping at "
+"`_start`. We have also added the `.hex` label so we can either have a blank "
+"space or a new line as the third byte of the `buffer`."
+msgstr ""
+"Это означает, что нам нужно установить `CL` только один раз. Поэтому мы "
+"добавили новую метку `.loop` и переходим к ней для следующего байта вместо "
+"перехода к `_start`. Мы также добавили метку `.hex`, чтобы третий байт "
+"`buffer` мог быть либо пробелом, либо новой строкой."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:791
+msgid ""
+"Once you have changed [.filename]#hex.asm# to reflect these changes, type:"
+msgstr "После внесения изменений в файл [.filename]#hex.asm# введите:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:802
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1061
+#, no-wrap
+msgid ""
+"% nasm -f elf hex.asm\n"
+"% ld -s -o hex hex.o\n"
+"% ./hex\n"
+"Hello, World!\n"
+"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A\n"
+"Here I come!\n"
+"48 65 72 65 20 49 20 63 6F 6D 65 21 0A\n"
+"^D %\n"
+msgstr ""
+"% nasm -f elf hex.asm\n"
+"% ld -s -o hex hex.o\n"
+"% ./hex\n"
+"Hello, World!\n"
+"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A\n"
+"Here I come!\n"
+"48 65 72 65 20 49 20 63 6F 6D 65 21 0A\n"
+"^D %\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:806
+msgid ""
+"That looks better. But this code is quite inefficient! We are making a "
+"system call for every single byte twice (once to read it, another time to "
+"write the output)."
+msgstr ""
+"Выглядит лучше. Но этот код довольно неэффективен! Мы выполняем системный "
+"вызов для каждого отдельного байта дважды (один раз для чтения и ещё один "
+"для записи вывода)."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:808
+#, no-wrap
+msgid "Buffered Input and Output"
+msgstr "Буферизованный ввод и вывод"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:813
+msgid ""
+"We can improve the efficiency of our code by buffering our input and "
+"output. We create an input buffer and read a whole sequence of bytes at one "
+"time. Then we fetch them one by one from the buffer."
+msgstr ""
+"Мы можем повысить эффективность нашего кода, буферизуя ввод и вывод. Мы "
+"создаём входной буфер и читаем сразу целую последовательность байтов. Затем "
+"мы извлекаем их по одному из буфера."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:816
+msgid ""
+"We also create an output buffer. We store our output in it until it is "
+"full. At that time we ask the kernel to write the contents of the buffer to "
+"[.filename]#stdout#."
+msgstr ""
+"Мы также создаем выходной буфер. Мы сохраняем наш вывод в нем, пока он не "
+"заполнится. В этот момент мы просим ядро записать содержимое буфера в [."
+"filename]#stdout#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:820
+msgid ""
+"The program ends when there is no more input. But we still need to ask the "
+"kernel to write the contents of our output buffer to [.filename]#stdout# one "
+"last time, otherwise some of our output would make it to the output buffer, "
+"but never be sent out. Do not forget that, or you will be wondering why "
+"some of your output is missing."
+msgstr ""
+"Программа завершается, когда больше нет входных данных. Но нам всё ещё нужно "
+"попросить ядро записать содержимое нашего выходного буфера в [."
+"filename]#stdout# в последний раз, иначе часть нашего вывода попадёт в "
+"буфер, но так и не будет отправлена. Не забудьте об этом, иначе будете "
+"недоумевать, куда пропала часть вывода."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:826
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:954
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1221
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2339
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3337
+#, no-wrap
+msgid "%define\tBUFSIZE\t2048\n"
+msgstr "%define\tBUFSIZE\t2048\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:829
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:957
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"hex\tdb\t'0123456789ABCDEF'\n"
+msgstr ""
+"section\t.data\n"
+"hex\tdb\t'0123456789ABCDEF'\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:833
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:961
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1230
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2353
+#, no-wrap
+msgid ""
+"section .bss\n"
+"ibuffer\tresb\tBUFSIZE\n"
+"obuffer\tresb\tBUFSIZE\n"
+msgstr ""
+"section .bss\n"
+"ibuffer\tresb\tBUFSIZE\n"
+"obuffer\tresb\tBUFSIZE\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:841
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:969
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"global\t_start\n"
+"_start:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tmov\tedi, obuffer\n"
+msgstr ""
+"section\t.text\n"
+"global\t_start\n"
+"_start:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tmov\tedi, obuffer\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:845
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:973
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2501
+#, no-wrap
+msgid ""
+".loop:\n"
+"\t; read a byte from stdin\n"
+"\tcall\tgetchar\n"
+msgstr ""
+".loop:\n"
+"\t; read a byte from stdin\n"
+"\tcall\tgetchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:851
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:979
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1283
+#, no-wrap
+msgid ""
+"\t; convert it to hex\n"
+"\tmov\tdl, al\n"
+"\tshr\tal, 4\n"
+"\tmov\tal, [hex+eax]\n"
+"\tcall\tputchar\n"
+msgstr ""
+"\t; convert it to hex\n"
+"\tmov\tdl, al\n"
+"\tshr\tal, 4\n"
+"\tmov\tal, [hex+eax]\n"
+"\tcall\tputchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:856
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:984
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1288
+#, no-wrap
+msgid ""
+"\tmov\tal, dl\n"
+"\tand\tal, 0Fh\n"
+"\tmov\tal, [hex+eax]\n"
+"\tcall\tputchar\n"
+msgstr ""
+"\tmov\tal, dl\n"
+"\tand\tal, 0Fh\n"
+"\tmov\tal, [hex+eax]\n"
+"\tcall\tputchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:861
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:989
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1293
+#, no-wrap
+msgid ""
+"\tmov\tal, ' '\n"
+"\tcmp\tdl, 0Ah\n"
+"\tjne\t.put\n"
+"\tmov\tal, dl\n"
+msgstr ""
+"\tmov\tal, ' '\n"
+"\tcmp\tdl, 0Ah\n"
+"\tjne\t.put\n"
+"\tmov\tal, dl\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:865
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2512
+#, no-wrap
+msgid ""
+".put:\n"
+"\tcall\tputchar\n"
+"\tjmp\tshort .loop\n"
+msgstr ""
+".put:\n"
+"\tcall\tputchar\n"
+"\tjmp\tshort .loop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:870
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1001
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1305
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2534
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3848
+#, no-wrap
+msgid ""
+"align 4\n"
+"getchar:\n"
+"\tor\tebx, ebx\n"
+"\tjne\t.fetch\n"
+msgstr ""
+"align 4\n"
+"getchar:\n"
+"\tor\tebx, ebx\n"
+"\tjne\t.fetch\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:872
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1003
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1307
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2536
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3850
+#, no-wrap
+msgid "\tcall\tread\n"
+msgstr "\tcall\tread\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:877
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1008
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1312
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2541
+#, no-wrap
+msgid ""
+".fetch:\n"
+"\tlodsb\n"
+"\tdec\tebx\n"
+"\tret\n"
+msgstr ""
+".fetch:\n"
+"\tlodsb\n"
+"\tdec\tebx\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:890
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1021
+#, no-wrap
+msgid ""
+"read:\n"
+"\tpush\tdword BUFSIZE\n"
+"\tmov\tesi, ibuffer\n"
+"\tpush\tesi\n"
+"\tpush\tdword stdin\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tmov\tebx, eax\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+msgstr ""
+"read:\n"
+"\tpush\tdword BUFSIZE\n"
+"\tmov\tesi, ibuffer\n"
+"\tpush\tesi\n"
+"\tpush\tdword stdin\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tmov\tebx, eax\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:896
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1027
+#, no-wrap
+msgid ""
+"align 4\n"
+".done:\n"
+"\tcall\twrite\t\t; flush output buffer\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+"align 4\n"
+".done:\n"
+"\tcall\twrite\t\t; flush output buffer\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:904
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1035
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1348
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2581
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3887
+#, no-wrap
+msgid ""
+"align 4\n"
+"putchar:\n"
+"\tstosb\n"
+"\tinc\tecx\n"
+"\tcmp\tecx, BUFSIZE\n"
+"\tje\twrite\n"
+"\tret\n"
+msgstr ""
+"align 4\n"
+"putchar:\n"
+"\tstosb\n"
+"\tinc\tecx\n"
+"\tcmp\tecx, BUFSIZE\n"
+"\tje\twrite\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:916
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1047
+#, no-wrap
+msgid ""
+"align 4\n"
+"write:\n"
+"\tsub\tedi, ecx\t; start of buffer\n"
+"\tpush\tecx\n"
+"\tpush\tedi\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tsub\teax, eax\n"
+"\tsub\tecx, ecx\t; buffer is empty now\n"
+"\tret\n"
+msgstr ""
+"align 4\n"
+"write:\n"
+"\tsub\tedi, ecx\t; start of buffer\n"
+"\tpush\tecx\n"
+"\tpush\tedi\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tsub\teax, eax\n"
+"\tsub\tecx, ecx\t; buffer is empty now\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:922
+msgid ""
+"We now have a third section in the source code, named `.bss`. This section "
+"is not included in our executable file, and, therefore, cannot be "
+"initialized. We use `resb` instead of `db`. It simply reserves the "
+"requested size of uninitialized memory for our use."
+msgstr ""
+"Теперь у нас есть третий раздел в исходном коде с именем `.bss`. Этот раздел "
+"не включается в исполняемый файл и, следовательно, не может быть "
+"инициализирован. Мы используем `resb` вместо `db`. Это просто резервирует "
+"запрошенный размер неинициализированной памяти для нашего использования."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:926
+msgid ""
+"We take advantage of the fact that the system does not modify the registers: "
+"We use registers for what, otherwise, would have to be global variables "
+"stored in the `.data` section. This is also why the UNIX(R) convention of "
+"passing parameters to system calls on the stack is superior to the Microsoft "
+"convention of passing them in the registers: We can keep the registers for "
+"our own use."
+msgstr ""
+"Мы используем тот факт, что система не изменяет регистры: мы используем "
+"регистры для того, что в противном случае пришлось бы хранить в глобальных "
+"переменных в секции `.data`. Именно поэтому соглашение UNIX(R) о передаче "
+"параметров системных вызовов через стек превосходит соглашение Microsoft о "
+"передаче их в регистрах: мы можем оставить регистры для собственного "
+"использования."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:930
+msgid ""
+"We use `EDI` and `ESI` as pointers to the next byte to be read from or "
+"written to. We use `EBX` and `ECX` to keep count of the number of bytes in "
+"the two buffers, so we know when to dump the output to, or read more input "
+"from, the system."
+msgstr ""
+"Мы используем `EDI` и `ESI` как указатели на следующий байт для чтения или "
+"записи. Мы используем `EBX` и `ECX` для отслеживания количества байтов в "
+"двух буферах, чтобы знать, когда нужно вывести данные в систему или считать "
+"новые данные из системы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:932
+msgid "Let us see how it works now:"
+msgstr "Давайте посмотрим, как это работает сейчас:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:943
+#, no-wrap
+msgid ""
+"% nasm -f elf hex.asm\n"
+"% ld -s -o hex hex.o\n"
+"% ./hex\n"
+"Hello, World!\n"
+"Here I come!\n"
+"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A\n"
+"48 65 72 65 20 49 20 63 6F 6D 65 21 0A\n"
+"^D %\n"
+msgstr ""
+"% nasm -f elf hex.asm\n"
+"% ld -s -o hex hex.o\n"
+"% ./hex\n"
+"Hello, World!\n"
+"Here I come!\n"
+"48 65 6C 6C 6F 2C 20 57 6F 72 6C 64 21 0A\n"
+"48 65 72 65 20 49 20 63 6F 6D 65 21 0A\n"
+"^D %\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:948
+msgid ""
+"Not what you expected? The program did not print the output until we pressed "
+"`^D`. That is easy to fix by inserting three lines of code to write the "
+"output every time we have converted a new line to `0A`. I have marked the "
+"three lines with > (do not copy the > in your [.filename]#hex.asm#)."
+msgstr ""
+"Не то, что вы ожидали? Программа не выводила результат, пока мы не нажали "
+"`^D`. Это легко исправить, добавив три строки кода для вывода результата "
+"каждый раз, когда мы преобразуем новую строку в `0A`. Я пометил эти три "
+"строки символом > (не копируйте > в ваш [.filename]#hex.asm#)."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:996
+#, no-wrap
+msgid ""
+".put:\n"
+"\tcall\tputchar\n"
+">\tcmp\tal, 0Ah\n"
+">\tjne\t.loop\n"
+">\tcall\twrite\n"
+"\tjmp\tshort .loop\n"
+msgstr ""
+".put:\n"
+"\tcall\tputchar\n"
+">\tcmp\tal, 0Ah\n"
+">\tjne\t.loop\n"
+">\tcall\twrite\n"
+"\tjmp\tshort .loop\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1050
+msgid "Now, let us see how it works:"
+msgstr "Теперь давайте посмотрим, как это работает:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1064
+msgid "Not bad for a 644-byte executable, is it!"
+msgstr "Неплохо для исполняемого файла размером 644 байта, не так ли!"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1069
+msgid ""
+"This approach to buffered input/output still contains a hidden danger. I "
+"will discuss-and fix-it later, when I talk about the crossref:x86[x86-"
+"buffered-dark-side,dark side of buffering]."
+msgstr ""
+"Такой подход к буферизированному вводу/выводу всё ещё содержит скрытую "
+"опасность. Я расскажу об этом и исправлю её позже, когда речь пойдёт о "
+"crossref:x86[x86-buffered-dark-side,тёмной стороне буферизации]."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1072
+#, no-wrap
+msgid "How to Unread a Character"
+msgstr "Как отменить чтение символа"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1078
+msgid ""
+"This may be a somewhat advanced topic, mostly of interest to programmers "
+"familiar with the theory of compilers. If you wish, you may crossref:"
+"x86[x86-command-line,skip to the next section], and perhaps read this later."
+msgstr ""
+"Это может быть несколько сложной темой, в основном представляющей интерес "
+"для программистов, знакомых с теорией компиляторов. Если хотите, вы можете "
+"crossref:x86[x86-command-line, перейти к следующему разделу], и, возможно, "
+"прочитаете это позже."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1084
+msgid ""
+"While our sample program does not require it, more sophisticated filters "
+"often need to look ahead. In other words, they may need to see what the "
+"next character is (or even several characters). If the next character is of "
+"a certain value, it is part of the token currently being processed. "
+"Otherwise, it is not."
+msgstr ""
+"Хотя наш пример программы не требует этого, более сложные фильтры часто "
+"нуждаются в предварительном просмотре. Другими словами, им может "
+"потребоваться узнать, какой следующий символ (или даже несколько символов). "
+"Если следующий символ имеет определённое значение, он является частью "
+"текущего обрабатываемого токена. В противном случае — нет."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1088
+msgid ""
+"For example, you may be parsing the input stream for a textual string (e.g., "
+"when implementing a language compiler): If a character is followed by "
+"another character, or perhaps a digit, it is part of the token you are "
+"processing. If it is followed by white space, or some other value, then it "
+"is not part of the current token."
+msgstr ""
+"Например, вы можете анализировать входной поток на наличие текстовой строки "
+"(например, при реализации компилятора языка): если символ следует за другим "
+"символом или, возможно, цифрой, он является частью обрабатываемой лексемы. "
+"Если за ним следует пробел или другое значение, то он не является частью "
+"текущей лексемы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1090
+msgid ""
+"This presents an interesting problem: How to return the next character back "
+"to the input stream, so it can be read again later?"
+msgstr ""
+"Это представляет интересную проблему: как вернуть следующий символ обратно "
+"во входной поток, чтобы его можно было прочитать позже?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1094
+msgid ""
+"One possible solution is to store it in a character variable, then set a "
+"flag. We can modify `getchar` to check the flag, and if it is set, fetch "
+"the byte from that variable instead of the input buffer, and reset the "
+"flag. But, of course, that slows us down."
+msgstr ""
+"Одно из возможных решений — сохранить его в символьной переменной, а затем "
+"установить флаг. Мы можем изменить `getchar`, чтобы он проверял флаг, и если "
+"он установлен, извлекал байт из этой переменной вместо буфера ввода, а затем "
+"сбрасывал флаг. Но, конечно, это замедляет работу."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1099
+msgid ""
+"The C language has an `ungetc()` function, just for that purpose. Is there "
+"a quick way to implement it in our code? I would like you to scroll back up "
+"and take a look at the `getchar` procedure and see if you can find a nice "
+"and fast solution before reading the next paragraph. Then come back here "
+"and see my own solution."
+msgstr ""
+"В языке C есть функция `ungetc()`, как раз для этой цели. Есть ли быстрый "
+"способ реализовать её в нашем коде? Я хочу, чтобы вы пролистали назад и "
+"взглянули на процедуру `getchar`, и попробовали найти красивое и быстрое "
+"решение, прежде чем читать следующий абзац. Затем вернитесь сюда и "
+"посмотрите моё собственное решение."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1101
+msgid ""
+"The key to returning a character back to the stream is in how we are getting "
+"the characters to start with:"
+msgstr ""
+"Ключом к возвращению символа обратно в поток является то, как мы получаем "
+"символы изначально:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1104
+msgid ""
+"First we check if the buffer is empty by testing the value of `EBX`. If it "
+"is zero, we call the `read` procedure."
+msgstr ""
+"Сначала проверяем, пуст ли буфер, проверяя значение `EBX`. Если оно равно "
+"нулю, вызываем процедуру `read`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1107
+msgid ""
+"If we do have a character available, we use `lodsb`, then decrease the value "
+"of `EBX`. The `lodsb` instruction is effectively identical to:"
+msgstr ""
+"Если у нас есть доступный символ, мы используем `lodsb`, затем уменьшаем "
+"значение `EBX`. Инструкция `lodsb` фактически идентична:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1112
+#, no-wrap
+msgid ""
+"mov\tal, [esi]\n"
+"\tinc\tesi\n"
+msgstr ""
+"mov\tal, [esi]\n"
+"\tinc\tesi\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1117
+msgid ""
+"The byte we have fetched remains in the buffer until the next time `read` is "
+"called. We do not know when that happens, but we do know it will not happen "
+"until the next call to `getchar`. Hence, to \"return\" the last-read byte "
+"back to the stream, all we have to do is decrease the value of `ESI` and "
+"increase the value of `EBX`:"
+msgstr ""
+"Байт, который мы извлекли, остается в буфере до следующего вызова `read`. Мы "
+"не знаем, когда это произойдет, но знаем, что этого не случится до "
+"следующего вызова `getchar`. Следовательно, чтобы \"вернуть\" последний "
+"прочитанный байт обратно в поток, нам достаточно уменьшить значение `ESI` и "
+"увеличить значение `EBX`:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1124
+#, no-wrap
+msgid ""
+"ungetc:\n"
+"\tdec\tesi\n"
+"\tinc\tebx\n"
+"\tret\n"
+msgstr ""
+"ungetc:\n"
+"\tdec\tesi\n"
+"\tinc\tebx\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1128
+msgid ""
+"But, be careful! We are perfectly safe doing this if our look-ahead is at "
+"most one character at a time. If we are examining more than one upcoming "
+"character and call `ungetc` several times in a row, it will work most of the "
+"time, but not all the time (and will be tough to debug). Why?"
+msgstr ""
+"Но будьте осторожны! Мы в полной безопасности, если заглядываем вперед "
+"только на один символ за раз. Если же мы проверяем несколько следующих "
+"символов и вызываем `ungetc` несколько раз подряд, это будет работать в "
+"большинстве случаев, но не всегда (и ошибки будет сложно отладить). Почему?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1131
+msgid ""
+"Because as long as `getchar` does not have to call `read`, all of the pre-"
+"read bytes are still in the buffer, and our `ungetc` works without a "
+"glitch. But the moment `getchar` calls `read`, the contents of the buffer "
+"change."
+msgstr ""
+"Потому что пока `getchar` не вызывает `read`, все предварительно прочитанные "
+"байты остаются в буфере, и наш `ungetc` работает без сбоев. Но как только "
+"`getchar` вызывает `read`, содержимое буфера изменяется."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1133
+msgid ""
+"We can always rely on `ungetc` working properly on the last character we "
+"have read with `getchar`, but not on anything we have read before that."
+msgstr ""
+"Мы всегда можем рассчитывать на корректную работу `ungetc` с последним "
+"символом, прочитанным через `getchar`, но не с любым символом, прочитанным "
+"до этого."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1135
+msgid ""
+"If your program reads more than one byte ahead, you have at least two "
+"choices:"
+msgstr ""
+"Если ваша программа читает более одного байта вперед, у вас есть как минимум "
+"два варианта:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1138
+msgid ""
+"If possible, modify the program so it only reads one byte ahead. This is "
+"the simplest solution."
+msgstr ""
+"Если возможно, измените программу так, чтобы она читала только один байт "
+"вперед. Это самое простое решение."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1142
+msgid ""
+"If that option is not available, first of all determine the maximum number "
+"of characters your program needs to return to the input stream at one time. "
+"Increase that number slightly, just to be sure, preferably to a multiple of "
+"16-so it aligns nicely. Then modify the `.bss` section of your code, and "
+"create a small \"spare\" buffer right before your input buffer, something "
+"like this:"
+msgstr ""
+"Если эта опция недоступна, сначала определите максимальное количество "
+"символов, которое вашей программе может потребоваться вернуть во входной "
+"поток за один раз. Увеличьте это число немного, чтобы быть уверенным, "
+"предпочтительно до кратного 16 — так оно будет лучше выровнено. Затем "
+"измените секцию `.bss` в вашем коде и создайте небольшой \"запасной\" буфер "
+"прямо перед вашим входным буфером, примерно так:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1149
+#, no-wrap
+msgid ""
+"section\t.bss\n"
+"\tresb\t16\t; or whatever the value you came up with\n"
+"ibuffer\tresb\tBUFSIZE\n"
+"obuffer\tresb\tBUFSIZE\n"
+msgstr ""
+"section\t.bss\n"
+"\tresb\t16\t; or whatever the value you came up with\n"
+"ibuffer\tresb\tBUFSIZE\n"
+"obuffer\tresb\tBUFSIZE\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1152
+msgid ""
+"You also need to modify your `ungetc` to pass the value of the byte to unget "
+"in `AL`:"
+msgstr ""
+"Вам также необходимо изменить ваш `ungetc`, чтобы передать значение байта "
+"для возврата в `AL`:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1160
+#, no-wrap
+msgid ""
+"ungetc:\n"
+"\tdec\tesi\n"
+"\tinc\tebx\n"
+"\tmov\t[esi], al\n"
+"\tret\n"
+msgstr ""
+"ungetc:\n"
+"\tdec\tesi\n"
+"\tinc\tebx\n"
+"\tmov\t[esi], al\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1163
+msgid ""
+"With this modification, you can call `ungetc` up to 17 times in a row safely "
+"(the first call will still be within the buffer, the remaining 16 may be "
+"either within the buffer or within the \"spare\")."
+msgstr ""
+"С этим изменением вы можете безопасно вызывать `ungetc` до 17 раз подряд "
+"(первый вызов всё ещё будет в пределах буфера, остальные 16 могут быть либо "
+"в пределах буфера, либо в пределах \"запасного\" пространства)."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1165
+#, no-wrap
+msgid "Command Line Arguments"
+msgstr "Аргументы командной строки"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1169
+msgid ""
+"Our hex program will be more useful if it can read the names of an input and "
+"output file from its command line, i.e., if it can process the command line "
+"arguments. But... Where are they?"
+msgstr ""
+"Наша программа hex будет полезнее, если она сможет читать имена входного и "
+"выходного файлов из командной строки, т.е. если она сможет обрабатывать "
+"аргументы командной строки. Но... Где они?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1173
+msgid ""
+"Before a UNIX(R) system starts a program, it ``push``es some data on the "
+"stack, then jumps at the `_start` label of the program. Yes, I said jumps, "
+"not calls. That means the data can be accessed by reading `[esp+offset]`, "
+"or by simply ``pop``ping it."
+msgstr ""
+"Прежде чем UNIX(R) система запустит программу, она делает ``push`` для "
+"некоторых данных, помещая их в стек, затем переходит к метке `_start` "
+"программы. Да, я сказал \"переходит\", а не \"вызывает\". Это означает, что "
+"данные можно прочитать с помощью `[esp+offset]` или просто сделать ``pop`` "
+"для них."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1176
+msgid ""
+"The value at the top of the stack contains the number of command line "
+"arguments. It is traditionally called `argc`, for \"argument count.\""
+msgstr ""
+"Значение на вершине стека содержит количество аргументов командной строки. "
+"Оно традиционно называется `argc`, что означает \"argument count\"."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1181
+msgid ""
+"Command line arguments follow next, all `argc` of them. These are typically "
+"referred to as `argv`, for \"argument value(s).\" That is, we get `argv[0]`, "
+"`argv[1]`, `...`, `argv[argc-1]`. These are not the actual arguments, but "
+"pointers to arguments, i.e., memory addresses of the actual arguments. The "
+"arguments themselves are NUL-terminated character strings."
+msgstr ""
+"Далее следуют аргументы командной строки, все `argc` штук. Обычно их "
+"называют `argv`, что означает \"значение(я) аргумента\". То есть мы получаем "
+"`argv[0]`, `argv[1]`, `...`, `argv[argc-1]`. Это не сами аргументы, а "
+"указатели на аргументы, то есть адреса памяти, где находятся реальные "
+"аргументы. Сами аргументы представляют собой строки символов, завершающиеся "
+"нулевым символом ('\\0')."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1183
+msgid ""
+"The `argv` list is followed by a NULL pointer, which is simply a `0`. There "
+"is more, but this is enough for our purposes right now."
+msgstr ""
+"Список `argv` завершается указателем NULL, который представляет собой просто "
+"`0`. Есть и другие детали, но пока этого достаточно для наших целей."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1188
+msgid ""
+"If you have come from the MS-DOS(R) programming environment, the main "
+"difference is that each argument is in a separate string. The second "
+"difference is that there is no practical limit on how many arguments there "
+"can be."
+msgstr ""
+"Если вы перешли из среды программирования MS-DOS(R), основное различие "
+"заключается в том, что каждый аргумент находится в отдельной строке. Второе "
+"различие состоит в том, что нет практического ограничения на количество "
+"аргументов."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1192
+msgid ""
+"Armed with this knowledge, we are almost ready for the next version of [."
+"filename]#hex.asm#. First, however, we need to add a few lines to [."
+"filename]#system.inc#:"
+msgstr ""
+"Вооружившись этими знаниями, мы почти готовы к следующей версии [."
+"filename]#hex.asm#. Однако сначала нам нужно добавить несколько строк в [."
+"filename]#system.inc#:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1194
+msgid ""
+"First, we need to add two new entries to our list of system call numbers:"
+msgstr ""
+"Сначала нам нужно добавить две новые записи в наш список номеров системных "
+"вызовов:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1199
+#, no-wrap
+msgid ""
+"%define\tSYS_open\t5\n"
+"%define\tSYS_close\t6\n"
+msgstr ""
+"%define\tSYS_open\t5\n"
+"%define\tSYS_close\t6\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1202
+msgid "Then we add two new macros at the end of the file:"
+msgstr "Затем мы добавляем два новых макроса в конце файла:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1208
+#, no-wrap
+msgid ""
+"%macro\tsys.open\t0\n"
+"\tsystem\tSYS_open\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.open\t0\n"
+"\tsystem\tSYS_open\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1212
+#, no-wrap
+msgid ""
+"%macro\tsys.close\t0\n"
+"\tsystem\tSYS_close\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.close\t0\n"
+"\tsystem\tSYS_close\n"
+"%endmacro\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1215
+msgid "Here, then, is our modified source code:"
+msgstr "Вот наш измененный исходный код:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1226
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"fd.in\tdd\tstdin\n"
+"fd.out\tdd\tstdout\n"
+"hex\tdb\t'0123456789ABCDEF'\n"
+msgstr ""
+"section\t.data\n"
+"fd.in\tdd\tstdin\n"
+"fd.out\tdd\tstdout\n"
+"hex\tdb\t'0123456789ABCDEF'\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1236
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"align 4\n"
+"err:\n"
+"\tpush\tdword 1\t\t; return failure\n"
+"\tsys.exit\n"
+msgstr ""
+"section\t.text\n"
+"align 4\n"
+"err:\n"
+"\tpush\tdword 1\t\t; return failure\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1241
+#, no-wrap
+msgid ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
+msgstr ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1244
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1256
+#, no-wrap
+msgid ""
+"\tpop\tecx\n"
+"\tjecxz\t.init\t\t; no more arguments\n"
+msgstr ""
+"\tpop\tecx\n"
+"\tjecxz\t.init\t\t; no more arguments\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1250
+#, no-wrap
+msgid ""
+"\t; ECX contains the path to input file\n"
+"\tpush\tdword 0\t\t; O_RDONLY\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\terr\t\t; open failed\n"
+msgstr ""
+"\t; ECX contains the path to input file\n"
+"\tpush\tdword 0\t\t; O_RDONLY\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\terr\t\t; open failed\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1253
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 8\n"
+"\tmov\t[fd.in], eax\n"
+msgstr ""
+"\tadd\tesp, byte 8\n"
+"\tmov\t[fd.in], eax\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1264
+#, no-wrap
+msgid ""
+"\t; ECX contains the path to output file\n"
+"\tpush\tdword 420\t; file mode (644 octal)\n"
+"\tpush\tdword 0200h | 0400h | 01h\n"
+"\t; O_CREAT | O_TRUNC | O_WRONLY\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\terr\n"
+msgstr ""
+"\t; ECX contains the path to output file\n"
+"\tpush\tdword 420\t; file mode (644 octal)\n"
+"\tpush\tdword 0200h | 0400h | 01h\n"
+"\t; O_CREAT | O_TRUNC | O_WRONLY\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\terr\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1267
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 12\n"
+"\tmov\t[fd.out], eax\n"
+msgstr ""
+"\tadd\tesp, byte 12\n"
+"\tmov\t[fd.out], eax\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1273
+#, no-wrap
+msgid ""
+".init:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tmov\tedi, obuffer\n"
+msgstr ""
+".init:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tmov\tedi, obuffer\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1277
+#, no-wrap
+msgid ""
+".loop:\n"
+"\t; read a byte from input file or stdin\n"
+"\tcall\tgetchar\n"
+msgstr ""
+".loop:\n"
+"\t; read a byte from input file or stdin\n"
+"\tcall\tgetchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1300
+#, no-wrap
+msgid ""
+".put:\n"
+"\tcall\tputchar\n"
+"\tcmp\tal, dl\n"
+"\tjne\t.loop\n"
+"\tcall\twrite\n"
+"\tjmp\tshort .loop\n"
+msgstr ""
+".put:\n"
+"\tcall\tputchar\n"
+"\tcmp\tal, dl\n"
+"\tjne\t.loop\n"
+"\tcall\twrite\n"
+"\tjmp\tshort .loop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1325
+#, no-wrap
+msgid ""
+"read:\n"
+"\tpush\tdword BUFSIZE\n"
+"\tmov\tesi, ibuffer\n"
+"\tpush\tesi\n"
+"\tpush\tdword [fd.in]\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tmov\tebx, eax\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+msgstr ""
+"read:\n"
+"\tpush\tdword BUFSIZE\n"
+"\tmov\tesi, ibuffer\n"
+"\tpush\tesi\n"
+"\tpush\tdword [fd.in]\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tmov\tebx, eax\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1329
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2562
+#, no-wrap
+msgid ""
+"align 4\n"
+".done:\n"
+"\tcall\twrite\t\t; flush output buffer\n"
+msgstr ""
+"align 4\n"
+".done:\n"
+"\tcall\twrite\t\t; flush output buffer\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1333
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2566
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3820
+#, no-wrap
+msgid ""
+"\t; close files\n"
+"\tpush\tdword [fd.in]\n"
+"\tsys.close\n"
+msgstr ""
+"\t; close files\n"
+"\tpush\tdword [fd.in]\n"
+"\tsys.close\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1336
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2569
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3823
+#, no-wrap
+msgid ""
+"\tpush\tdword [fd.out]\n"
+"\tsys.close\n"
+msgstr ""
+"\tpush\tdword [fd.out]\n"
+"\tsys.close\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1340
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2573
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3829
+#, no-wrap
+msgid ""
+"\t; return success\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+"\t; return success\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1360
+#, no-wrap
+msgid ""
+"align 4\n"
+"write:\n"
+"\tsub\tedi, ecx\t; start of buffer\n"
+"\tpush\tecx\n"
+"\tpush\tedi\n"
+"\tpush\tdword [fd.out]\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tsub\teax, eax\n"
+"\tsub\tecx, ecx\t; buffer is empty now\n"
+"\tret\n"
+msgstr ""
+"align 4\n"
+"write:\n"
+"\tsub\tedi, ecx\t; start of buffer\n"
+"\tpush\tecx\n"
+"\tpush\tedi\n"
+"\tpush\tdword [fd.out]\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tsub\teax, eax\n"
+"\tsub\tecx, ecx\t; buffer is empty now\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1364
+msgid ""
+"In our `.data` section we now have two new variables, `fd.in` and `fd.out`. "
+"We store the input and output file descriptors here."
+msgstr ""
+"В нашем разделе `.data` теперь есть две новые переменные, `fd.in` и `fd."
+"out`. Здесь мы сохраняем дескрипторы файлов для ввода и вывода."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1366
+msgid ""
+"In the `.text` section we have replaced the references to `stdin` and "
+"`stdout` with `[fd.in]` and `[fd.out]`."
+msgstr ""
+"В разделе `.text` мы заменили ссылки с `stdin` и `stdout` на `[fd.in]` и "
+"`[fd.out]`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1369
+msgid ""
+"The `.text` section now starts with a simple error handler, which does "
+"nothing but exit the program with a return value of `1`. The error handler "
+"is before `_start` so we are within a short distance from where the errors "
+"occur."
+msgstr ""
+"Раздел `.text` теперь начинается с простого обработчика ошибок, который "
+"просто завершает программу с кодом возврата `1`. Обработчик ошибок "
+"расположен перед `_start`, чтобы находиться вблизи от места возникновения "
+"ошибок."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1372
+msgid ""
+"Naturally, the program execution still begins at `_start`. First, we remove "
+"`argc` and `argv[0]` from the stack: They are of no interest to us (in this "
+"program, that is)."
+msgstr ""
+"Естественно, выполнение программы по-прежнему начинается с `_start`. Сначала "
+"мы удаляем `argc` и `argv[0]` из стека: они не представляют для нас интереса "
+"(по крайней мере, в этой программе)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1378
+msgid ""
+"We pop `argv[1]` to `ECX`. This register is particularly suited for "
+"pointers, as we can handle NULL pointers with `jecxz`. If `argv[1]` is not "
+"NULL, we try to open the file named in the first argument. Otherwise, we "
+"continue the program as before: Reading from `stdin`, writing to `stdout`. "
+"If we fail to open the input file (e.g., it does not exist), we jump to the "
+"error handler and quit."
+msgstr ""
+"Мы помещаем `argv[1]` в `ECX`. Этот регистр особенно подходит для "
+"указателей, так как мы можем обрабатывать NULL-указатели с помощью `jecxz`. "
+"Если `argv[1]` не равен NULL, мы пытаемся открыть файл с именем, указанным в "
+"первом аргументе. В противном случае продолжаем программу как раньше: чтение "
+"из `stdin`, запись в `stdout`. Если нам не удаётся открыть входной файл "
+"(например, он не существует), мы переходим к обработчику ошибок и завершаем "
+"работу."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1383
+msgid ""
+"If all went well, we now check for the second argument. If it is there, we "
+"open the output file. Otherwise, we send the output to `stdout`. If we "
+"fail to open the output file (e.g., it exists and we do not have the write "
+"permission), we, again, jump to the error handler."
+msgstr ""
+"Если всё прошло успешно, мы проверяем второй аргумент. Если он присутствует, "
+"мы открываем выходной файл. В противном случае, мы отправляем вывод в "
+"`stdout`. Если нам не удаётся открыть выходной файл (например, он существует "
+"и у нас нет прав на запись), мы снова переходим к обработчику ошибок."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1385
+msgid ""
+"The rest of the code is the same as before, except we close the input and "
+"output files before exiting, and, as mentioned, we use `[fd.in]` and `[fd."
+"out]`."
+msgstr ""
+"Остальная часть кода остается прежней, за исключением того, что мы закрываем "
+"входной и выходной файлы перед завершением, и, как упоминалось, используем "
+"`[fd.in]` и `[fd.out]`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1387
+msgid "Our executable is now a whopping 768 bytes long."
+msgstr "Наш исполняемый файл теперь имеет внушительный размер в 768 байт."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1390
+msgid ""
+"Can we still improve it? Of course! Every program can be improved. Here are "
+"a few ideas of what we could do:"
+msgstr ""
+"Можем ли мы улучшить его еще? Конечно! Каждую программу можно улучшить. Вот "
+"несколько идей, что мы могли бы сделать:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1392
+msgid "Have our error handler print a message to `stderr`."
+msgstr "Сделать наш обработчик ошибок, выводящий сообщение в `stderr`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1393
+msgid "Add error handlers to the `read` and `write` functions."
+msgstr "Добавить обработчики ошибок в функции `read` и `write`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1394
+msgid ""
+"Close `stdin` when we open an input file, `stdout` when we open an output "
+"file."
+msgstr ""
+"Закрывать `stdin` при открытии входного файла, `stdout` при открытии "
+"выходного файла."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1395
+msgid ""
+"Add command line switches, such as `-i` and `-o`, so we can list the input "
+"and output files in any order, or perhaps read from `stdin` and write to a "
+"file."
+msgstr ""
+"Добавить параметры командной строки, такие как `-i` и `-o`, чтобы можно было "
+"перечислять входные и выходные файлы в любом порядке или, возможно, читать "
+"из `stdin` и записывать в файл."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1396
+msgid "Print a usage message if command line arguments are incorrect."
+msgstr ""
+"Выводить сообщение с подсказкой об использовании программы, если аргументы "
+"командной строки указаны неверно."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1398
+msgid ""
+"I shall leave these enhancements as an exercise to the reader: You already "
+"know everything you need to know to implement them."
+msgstr ""
+"Я оставлю эти улучшения в качестве упражнения для читателя: вы уже знаете "
+"всё необходимое для их реализации."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1400
+#, no-wrap
+msgid "UNIX(R) Environment"
+msgstr "Окружение UNIX(R)"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1404
+msgid ""
+"An important UNIX(R) concept is the environment, which is defined by "
+"_environment variables_. Some are set by the system, others by you, yet "
+"others by the shell, or any program that loads another program."
+msgstr ""
+"Важным концептом UNIX(R) является окружение, которое определяется "
+"_переменными окружения_. Некоторые из них устанавливаются системой, другие — "
+"пользователем, третьи — оболочкой или любой программой, которая загружает "
+"другую программу."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1406
+#, no-wrap
+msgid "How to Find Environment Variables"
+msgstr "Как найти переменные окружения"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1411
+msgid ""
+"I said earlier that when a program starts executing, the stack contains "
+"`argc` followed by the NULL-terminated `argv` array, followed by something "
+"else. The \"something else\" is the _environment_, or, to be more precise, "
+"a NULL-terminated array of pointers to _environment variables_. This is "
+"often referred to as `env`."
+msgstr ""
+"Я говорил ранее, что когда программа начинает выполняться, в стеке находятся "
+"`argc`, за которым следует массив `argv`, завершающийся NULL, а затем что-то "
+"ещё. Это \"что-то ещё\" — это _окружение_, или, если быть точнее, массив "
+"указателей на _переменные окружения_, завершающийся NULL. Это часто называют "
+"`env`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1414
+msgid ""
+"The structure of `env` is the same as that of `argv`, a list of memory "
+"addresses followed by a NULL (`0`). In this case, there is no `\"envc\"`-we "
+"figure out where the array ends by searching for the final NULL."
+msgstr ""
+"Структура `env` такая же, как у `argv` — список адресов памяти, "
+"заканчивающийся NULL (`0`). В данном случае нет `\"envc\"` — конец массива "
+"определяется поиском последнего NULL."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1417
+msgid ""
+"The variables usually come in the `name=value` format, but sometimes the "
+"`=value` part may be missing. We need to account for that possibility."
+msgstr ""
+"Переменные обычно имеют формат `name=value`, но иногда часть `=value` может "
+"отсутствовать. Необходимо учитывать эту вероятность."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1419
+#, no-wrap
+msgid "webvars"
+msgstr "webvars"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1423
+msgid ""
+"I could just show you some code that prints the environment the same way the "
+"UNIX(R) env command does. But I thought it would be more interesting to "
+"write a simple assembly language CGI utility."
+msgstr ""
+"Я мог бы просто показать вам код, который выводит окружение так же, как "
+"команда UNIX(R) env. Но я подумал, что будет интереснее написать простую CGI-"
+"утилиту на ассемблере."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1425
+#, no-wrap
+msgid "CGI: a Quick Overview"
+msgstr "CGI: краткий обзор"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1428
+msgid ""
+"I have a http://www.whizkidtech.redprince.net/cgi-bin/tutorial[detailed CGI "
+"tutorial] on my web site, but here is a very quick overview of CGI:"
+msgstr ""
+"У меня есть http://www.whizkidtech.redprince.net/cgi-bin/tutorial[подробное "
+"руководство по CGI] на моем веб-сайте, но вот очень краткий обзор CGI:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1430
+msgid ""
+"The web server communicates with the CGI program by setting _environment "
+"variables_."
+msgstr ""
+"Веб-сервер взаимодействует с CGI-программой, устанавливая _переменные "
+"окружения_."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1431
+msgid ""
+"The CGI program sends its output to [.filename]#stdout#. The web server "
+"reads it from there."
+msgstr ""
+"Программа CGI отправляет свой вывод в [.filename]#stdout#. Веб-сервер "
+"считывает его оттуда."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1432
+msgid "It must start with an HTTP header followed by two blank lines."
+msgstr ""
+"Он должен начинаться с HTTP-заголовка, за которым следуют две пустые строки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1433
+msgid ""
+"It then prints the HTML code, or whatever other type of data it is producing."
+msgstr ""
+"Затем он выводит HTML-код или любые другие данные, которые он генерирует."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1438
+msgid ""
+"While certain _environment variables_ use standard names, others vary, "
+"depending on the web server. That makes webvars quite a useful diagnostic "
+"tool."
+msgstr ""
+"В то время как некоторые _переменные окружения_ используют стандартные "
+"имена, другие различаются в зависимости от веб-сервера. Это делает программу "
+"webvars весьма полезным инструментом для диагностики."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1441
+#, no-wrap
+msgid "The Code"
+msgstr "Код"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1445
+msgid ""
+"Our webvars program, then, must send out the HTTP header followed by some "
+"HTML mark-up. It then must read the _environment variables_ one by one and "
+"send them out as part of the HTML page."
+msgstr ""
+"Наша программа webvars, таким образом, должна отправить HTTP-заголовок, за "
+"которым следует HTML-разметка. Затем она должна прочитать _переменные "
+"окружения_ одну за другой и отправить их как часть HTML-страницы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1448
+msgid ""
+"The code follows. I placed comments and explanations right inside the code:"
+msgstr "Код приведен ниже. Я разместил комментарии и пояснения прямо в коде:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1485
+#, no-wrap
+msgid ""
+";;;;;;; webvars.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";\n"
+"; Copyright (c) 2000 G. Adam Stanislav\n"
+"; All rights reserved.\n"
+";\n"
+"; Redistribution and use in source and binary forms, with or without\n"
+"; modification, are permitted provided that the following conditions\n"
+"; are met:\n"
+"; 1. Redistributions of source code must retain the above copyright\n"
+"; notice, this list of conditions and the following disclaimer.\n"
+"; 2. Redistributions in binary form must reproduce the above copyright\n"
+"; notice, this list of conditions and the following disclaimer in the\n"
+"; documentation and/or other materials provided with the distribution.\n"
+";\n"
+"; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n"
+"; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"
+"; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
+"; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n"
+"; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
+"; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
+"; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"
+"; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"
+"; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n"
+"; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"
+"; SUCH DAMAGE.\n"
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";\n"
+"; Version 1.0\n"
+";\n"
+"; Started:\t 8-Dec-2000\n"
+"; Updated:\t 8-Dec-2000\n"
+";\n"
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+"%include\t'system.inc'\n"
+msgstr ""
+";;;;;;; webvars.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";\n"
+"; Copyright (c) 2000 G. Adam Stanislav\n"
+"; All rights reserved.\n"
+";\n"
+"; Redistribution and use in source and binary forms, with or without\n"
+"; modification, are permitted provided that the following conditions\n"
+"; are met:\n"
+"; 1. Redistributions of source code must retain the above copyright\n"
+"; notice, this list of conditions and the following disclaimer.\n"
+"; 2. Redistributions in binary form must reproduce the above copyright\n"
+"; notice, this list of conditions and the following disclaimer in the\n"
+"; documentation and/or other materials provided with the distribution.\n"
+";\n"
+"; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND\n"
+"; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE\n"
+"; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE\n"
+"; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE\n"
+"; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL\n"
+"; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS\n"
+"; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)\n"
+"; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT\n"
+"; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY\n"
+"; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF\n"
+"; SUCH DAMAGE.\n"
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";\n"
+"; Version 1.0\n"
+";\n"
+"; Started:\t 8-Dec-2000\n"
+"; Updated:\t 8-Dec-2000\n"
+";\n"
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+"%include\t'system.inc'\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1522
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"http\tdb\t'Content-type: text/html', 0Ah, 0Ah\n"
+"\tdb\t'<?xml version=\"1.0\" encoding=\"utf-8\"?>', 0Ah\n"
+"\tdb\t'<!DOCTYPE html PUBLIC \"-//W3C/DTD XHTML Strict//EN\" '\n"
+"\tdb\t'\"DTD/xhtml1-strict.dtd\">', 0Ah\n"
+"\tdb\t'<html xmlns=\"http://www.w3.org/1999/xhtml\" '\n"
+"\tdb\t'xml.lang=\"en\" lang=\"en\">', 0Ah\n"
+"\tdb\t'<head>', 0Ah\n"
+"\tdb\t'<title>Web Environment</title>', 0Ah\n"
+"\tdb\t'<meta name=\"author\" content=\"G. Adam Stanislav\" />', 0Ah\n"
+"\tdb\t'</head>', 0Ah, 0Ah\n"
+"\tdb\t'<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#0000ff\" '\n"
+"\tdb\t'vlink=\"#840084\" alink=\"#0000ff\">', 0Ah\n"
+"\tdb\t'<div class=\"webvars\">', 0Ah\n"
+"\tdb\t'<h1>Web Environment</h1>', 0Ah\n"
+"\tdb\t'<p>The following <b>environment variables</b> are defined '\n"
+"\tdb\t'on this web server:</p>', 0Ah, 0Ah\n"
+"\tdb\t'<table align=\"center\" width=\"80\" border=\"0\" cellpadding=\"10\" '\n"
+"\tdb\t'cellspacing=\"0\" class=\"webvars\">', 0Ah\n"
+"httplen\tequ\t$-http\n"
+"left\tdb\t'<tr>', 0Ah\n"
+"\tdb\t'<td class=\"name\"><tt>'\n"
+"leftlen\tequ\t$-left\n"
+"middle\tdb\t'</tt></td>', 0Ah\n"
+"\tdb\t'<td class=\"value\"><tt><b>'\n"
+"midlen\tequ\t$-middle\n"
+"undef\tdb\t'<i>(undefined)</i>'\n"
+"undeflen\tequ\t$-undef\n"
+"right\tdb\t'</b></tt></td>', 0Ah\n"
+"\tdb\t'</tr>', 0Ah\n"
+"rightlen\tequ\t$-right\n"
+"wrap\tdb\t'</table>', 0Ah\n"
+"\tdb\t'</div>', 0Ah\n"
+"\tdb\t'</body>', 0Ah\n"
+"\tdb\t'</html>', 0Ah, 0Ah\n"
+"wraplen\tequ\t$-wrap\n"
+msgstr ""
+"section\t.data\n"
+"http\tdb\t'Content-type: text/html', 0Ah, 0Ah\n"
+"\tdb\t'<?xml version=\"1.0\" encoding=\"utf-8\"?>', 0Ah\n"
+"\tdb\t'<!DOCTYPE html PUBLIC \"-//W3C/DTD XHTML Strict//EN\" '\n"
+"\tdb\t'\"DTD/xhtml1-strict.dtd\">', 0Ah\n"
+"\tdb\t'<html xmlns=\"http://www.w3.org/1999/xhtml\" '\n"
+"\tdb\t'xml.lang=\"en\" lang=\"en\">', 0Ah\n"
+"\tdb\t'<head>', 0Ah\n"
+"\tdb\t'<title>Web Environment</title>', 0Ah\n"
+"\tdb\t'<meta name=\"author\" content=\"G. Adam Stanislav\" />', 0Ah\n"
+"\tdb\t'</head>', 0Ah, 0Ah\n"
+"\tdb\t'<body bgcolor=\"#ffffff\" text=\"#000000\" link=\"#0000ff\" '\n"
+"\tdb\t'vlink=\"#840084\" alink=\"#0000ff\">', 0Ah\n"
+"\tdb\t'<div class=\"webvars\">', 0Ah\n"
+"\tdb\t'<h1>Web Environment</h1>', 0Ah\n"
+"\tdb\t'<p>The following <b>environment variables</b> are defined '\n"
+"\tdb\t'on this web server:</p>', 0Ah, 0Ah\n"
+"\tdb\t'<table align=\"center\" width=\"80\" border=\"0\" cellpadding=\"10\" '\n"
+"\tdb\t'cellspacing=\"0\" class=\"webvars\">', 0Ah\n"
+"httplen\tequ\t$-http\n"
+"left\tdb\t'<tr>', 0Ah\n"
+"\tdb\t'<td class=\"name\"><tt>'\n"
+"leftlen\tequ\t$-left\n"
+"middle\tdb\t'</tt></td>', 0Ah\n"
+"\tdb\t'<td class=\"value\"><tt><b>'\n"
+"midlen\tequ\t$-middle\n"
+"undef\tdb\t'<i>(undefined)</i>'\n"
+"undeflen\tequ\t$-undef\n"
+"right\tdb\t'</b></tt></td>', 0Ah\n"
+"\tdb\t'</tr>', 0Ah\n"
+"rightlen\tequ\t$-right\n"
+"wrap\tdb\t'</table>', 0Ah\n"
+"\tdb\t'</div>', 0Ah\n"
+"\tdb\t'</body>', 0Ah\n"
+"\tdb\t'</html>', 0Ah, 0Ah\n"
+"wraplen\tequ\t$-wrap\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1532
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"global\t_start\n"
+"_start:\n"
+"\t; First, send out all the http and xhtml stuff that is\n"
+"\t; needed before we start showing the environment\n"
+"\tpush\tdword httplen\n"
+"\tpush\tdword http\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+"section\t.text\n"
+"global\t_start\n"
+"_start:\n"
+"\t; First, send out all the http and xhtml stuff that is\n"
+"\t; needed before we start showing the environment\n"
+"\tpush\tdword httplen\n"
+"\tpush\tdword http\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1536
+#, no-wrap
+msgid ""
+"\t; Now find how far on the stack the environment pointers\n"
+"\t; are. We have 12 bytes we have pushed before \"argc\"\n"
+"\tmov\teax, [esp+12]\n"
+msgstr ""
+"\t; Now find how far on the stack the environment pointers\n"
+"\t; are. We have 12 bytes we have pushed before \"argc\"\n"
+"\tmov\teax, [esp+12]\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1551
+#, no-wrap
+msgid ""
+"\t; We need to remove the following from the stack:\n"
+"\t;\n"
+"\t;\tThe 12 bytes we pushed for sys.write\n"
+"\t;\tThe 4 bytes of argc\n"
+"\t;\tThe EAX*4 bytes of argv\n"
+"\t;\tThe 4 bytes of the NULL after argv\n"
+"\t;\n"
+"\t; Total:\n"
+"\t;\t20 + eax * 4\n"
+"\t;\n"
+"\t; Because stack grows down, we need to ADD that many bytes\n"
+"\t; to ESP.\n"
+"\tlea\tesp, [esp+20+eax*4]\n"
+"\tcld\t\t; This should already be the case, but let's be sure.\n"
+msgstr ""
+"\t; We need to remove the following from the stack:\n"
+"\t;\n"
+"\t;\tThe 12 bytes we pushed for sys.write\n"
+"\t;\tThe 4 bytes of argc\n"
+"\t;\tThe EAX*4 bytes of argv\n"
+"\t;\tThe 4 bytes of the NULL after argv\n"
+"\t;\n"
+"\t; Total:\n"
+"\t;\t20 + eax * 4\n"
+"\t;\n"
+"\t; Because stack grows down, we need to ADD that many bytes\n"
+"\t; to ESP.\n"
+"\tlea\tesp, [esp+20+eax*4]\n"
+"\tcld\t\t; This should already be the case, but let's be sure.\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1557
+#, no-wrap
+msgid ""
+"\t; Loop through the environment, printing it out\n"
+".loop:\n"
+"\tpop\tedi\n"
+"\tor\tedi, edi\t; Done yet?\n"
+"\tje\tnear .wrap\n"
+msgstr ""
+"\t; Loop through the environment, printing it out\n"
+".loop:\n"
+"\tpop\tedi\n"
+"\tor\tedi, edi\t; Done yet?\n"
+"\tje\tnear .wrap\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1563
+#, no-wrap
+msgid ""
+"\t; Print the left part of HTML\n"
+"\tpush\tdword leftlen\n"
+"\tpush\tdword left\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+"\t; Print the left part of HTML\n"
+"\tpush\tdword leftlen\n"
+"\tpush\tdword left\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1574
+#, no-wrap
+msgid ""
+"\t; It may be tempting to search for the '=' in the env string next.\n"
+"\t; But it is possible there is no '=', so we search for the\n"
+"\t; terminating NUL first.\n"
+"\tmov\tesi, edi\t; Save start of string\n"
+"\tsub\tecx, ecx\n"
+"\tnot\tecx\t\t; ECX = FFFFFFFF\n"
+"\tsub\teax, eax\n"
+"repne\tscasb\n"
+"\tnot\tecx\t\t; ECX = string length + 1\n"
+"\tmov\tebx, ecx\t; Save it in EBX\n"
+msgstr ""
+"\t; It may be tempting to search for the '=' in the env string next.\n"
+"\t; But it is possible there is no '=', so we search for the\n"
+"\t; terminating NUL first.\n"
+"\tmov\tesi, edi\t; Save start of string\n"
+"\tsub\tecx, ecx\n"
+"\tnot\tecx\t\t; ECX = FFFFFFFF\n"
+"\tsub\teax, eax\n"
+"repne\tscasb\n"
+"\tnot\tecx\t\t; ECX = string length + 1\n"
+"\tmov\tebx, ecx\t; Save it in EBX\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1581
+#, no-wrap
+msgid ""
+"\t; Now is the time to find '='\n"
+"\tmov\tedi, esi\t; Start of string\n"
+"\tmov\tal, '='\n"
+"repne\tscasb\n"
+"\tnot\tecx\n"
+"\tadd\tecx, ebx\t; Length of name\n"
+msgstr ""
+"\t; Now is the time to find '='\n"
+"\tmov\tedi, esi\t; Start of string\n"
+"\tmov\tal, '='\n"
+"repne\tscasb\n"
+"\tnot\tecx\n"
+"\tadd\tecx, ebx\t; Length of name\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1586
+#, no-wrap
+msgid ""
+"\tpush\tecx\n"
+"\tpush\tesi\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+"\tpush\tecx\n"
+"\tpush\tesi\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1592
+#, no-wrap
+msgid ""
+"\t; Print the middle part of HTML table code\n"
+"\tpush\tdword midlen\n"
+"\tpush\tdword middle\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+"\t; Print the middle part of HTML table code\n"
+"\tpush\tdword midlen\n"
+"\tpush\tdword middle\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1596
+#, no-wrap
+msgid ""
+"\t; Find the length of the value\n"
+"\tnot\tecx\n"
+"\tlea\tebx, [ebx+ecx-1]\n"
+msgstr ""
+"\t; Find the length of the value\n"
+"\tnot\tecx\n"
+"\tlea\tebx, [ebx+ecx-1]\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1600
+#, no-wrap
+msgid ""
+"\t; Print \"undefined\" if 0\n"
+"\tor\tebx, ebx\n"
+"\tjne\t.value\n"
+msgstr ""
+"\t; Print \"undefined\" if 0\n"
+"\tor\tebx, ebx\n"
+"\tjne\t.value\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1603
+#, no-wrap
+msgid ""
+"\tmov\tebx, undeflen\n"
+"\tmov\tedi, undef\n"
+msgstr ""
+"\tmov\tebx, undeflen\n"
+"\tmov\tedi, undef\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1609
+#, no-wrap
+msgid ""
+".value:\n"
+"\tpush\tebx\n"
+"\tpush\tedi\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+".value:\n"
+"\tpush\tebx\n"
+"\tpush\tedi\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1615
+#, no-wrap
+msgid ""
+"\t; Print the right part of the table row\n"
+"\tpush\tdword rightlen\n"
+"\tpush\tdword right\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+"\t; Print the right part of the table row\n"
+"\tpush\tdword rightlen\n"
+"\tpush\tdword right\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1618
+#, no-wrap
+msgid ""
+"\t; Get rid of the 60 bytes we have pushed\n"
+"\tadd\tesp, byte 60\n"
+msgstr ""
+"\t; Get rid of the 60 bytes we have pushed\n"
+"\tadd\tesp, byte 60\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1621
+#, no-wrap
+msgid ""
+"\t; Get the next variable\n"
+"\tjmp\t.loop\n"
+msgstr ""
+"\t; Get the next variable\n"
+"\tjmp\t.loop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1628
+#, no-wrap
+msgid ""
+".wrap:\n"
+"\t; Print the rest of HTML\n"
+"\tpush\tdword wraplen\n"
+"\tpush\tdword wrap\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+msgstr ""
+".wrap:\n"
+"\t; Print the rest of HTML\n"
+"\tpush\tdword wraplen\n"
+"\tpush\tdword wrap\n"
+"\tpush\tdword stdout\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1632
+#, no-wrap
+msgid ""
+"\t; Return success\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+"\t; Return success\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1636
+msgid ""
+"This code produces a 1,396-byte executable. Most of it is data, i.e., the "
+"HTML mark-up we need to send out."
+msgstr ""
+"Этот код создает исполняемый файл размером 1 396 байт. Большая его часть — "
+"это данные, а именно HTML-разметка, которую нам нужно отправить."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1638
+msgid "Assemble and link it as usual:"
+msgstr "Запустите ассемблер и слинкуйте как обычно:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1643
+#, no-wrap
+msgid ""
+"% nasm -f elf webvars.asm\n"
+"% ld -s -o webvars webvars.o\n"
+msgstr ""
+"% nasm -f elf webvars.asm\n"
+"% ld -s -o webvars webvars.o\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1647
+msgid ""
+"To use it, you need to upload [.filename]#webvars# to your web server. "
+"Depending on how your web server is set up, you may have to store it in a "
+"special [.filename]#cgi-bin# directory, or perhaps rename it with a [."
+"filename]#.cgi# extension."
+msgstr ""
+"Для использования необходимо загрузить [.filename]#webvars# на ваш веб-"
+"сервер. В зависимости от настроек веб-сервера, возможно, потребуется "
+"разместить его в специальном каталоге [.filename]#cgi-bin# или переименовать "
+"с расширением [.filename]#.cgi#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1651
+msgid ""
+"Then you need to use your browser to view its output. To see its output on "
+"my web server, please go to http://www.int80h.org/webvars/[http://www.int80h."
+"org/webvars/]. If curious about the additional environment variables "
+"present in a password protected web directory, go to http://www.int80h.org/"
+"private/[http://www.int80h.org/private/], using the name `asm` and password "
+"`programmer`."
+msgstr ""
+"Затем вам нужно использовать браузер для просмотра вывода. Чтобы увидеть "
+"вывод на моем веб-сервере, перейдите по ссылке http://www.int80h.org/webvars/"
+"[http://www.int80h.org/webvars/]. Если вам интересно узнать о дополнительных "
+"переменных окружения в защищенном паролем веб-каталоге, перейдите по адресу "
+"http://www.int80h.org/private/[http://www.int80h.org/private/], используя "
+"имя `asm` и пароль `programmer`."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1653
+#, no-wrap
+msgid "Working with Files"
+msgstr "Работа с файлами"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1658
+msgid ""
+"We have already done some basic file work: We know how to open and close "
+"them, how to read and write them using buffers. But UNIX(R) offers much "
+"more functionality when it comes to files. We will examine some of it in "
+"this section, and end up with a nice file conversion utility."
+msgstr ""
+"Мы уже выполнили некоторые базовые операции с файлами: мы знаем, как их "
+"открывать и закрывать, как читать и записывать их с использованием буферов. "
+"Однако UNIX(R) предлагает гораздо больше возможностей при работе с файлами. "
+"В этом разделе мы рассмотрим некоторые из них и в итоге создадим удобную "
+"утилиту для преобразования файлов."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1661
+msgid ""
+"Indeed, let us start at the end, that is, with the file conversion utility. "
+"It always makes programming easier when we know from the start what the end "
+"product is supposed to do."
+msgstr ""
+"В самом деле, начнем с конца, то есть с утилиты преобразования файлов. "
+"Всегда легче программировать, когда с самого начала известно, каким должен "
+"быть конечный продукт."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1667
+msgid ""
+"One of the first programs I wrote for UNIX(R) was link:ftp://ftp.int80h.org/"
+"unix/tuc/[tuc], a text-to-UNIX(R) file converter. It converts a text file "
+"from other operating systems to a UNIX(R) text file. In other words, it "
+"changes from different kind of line endings to the newline convention of "
+"UNIX(R). It saves the output in a different file. Optionally, it converts "
+"a UNIX(R) text file to a DOS text file."
+msgstr ""
+"Одной из первых программ, которые я написал для UNIX(R), была link:ftp://ftp."
+"int80h.org/unix/tuc/[tuc] — конвертер текста в файл UNIX(R). Она преобразует "
+"текстовый файл из других операционных систем в текстовый файл UNIX(R). "
+"Другими словами, она изменяет различные виды окончаний строк на стандартные "
+"для UNIX(R). Результат сохраняется в другом файле. По желанию, она может "
+"преобразовать текстовый файл UNIX(R) в текстовый файл DOS."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1671
+msgid ""
+"I have used tuc extensively, but always only to convert from some other OS "
+"to UNIX(R), never the other way. I have always wished it would just "
+"overwrite the file instead of me having to send the output to a different "
+"file. Most of the time, I end up using it like this:"
+msgstr ""
+"Я широко использовал `tuc`, но всегда только для преобразования из какой-"
+"либо другой ОС в UNIX(R), никогда наоборот. Мне всегда хотелось, чтобы он "
+"просто перезаписывал файл, вместо того чтобы мне приходилось отправлять "
+"вывод в другой файл. В большинстве случаев я в итоге использую его так:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1676
+#, no-wrap
+msgid ""
+"% tuc myfile tempfile\n"
+"% mv tempfile myfile\n"
+msgstr ""
+"% tuc myfile tempfile\n"
+"% mv tempfile myfile\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1679
+msgid ""
+"It would be nice to have a ftuc, i.e., _fast tuc_, and use it like this:"
+msgstr ""
+"Было бы здорово иметь ftuc, т.е., _быстрый tuc_, и использовать его вот так:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1683
+#, no-wrap
+msgid "% ftuc myfile\n"
+msgstr "% ftuc myfile\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1686
+msgid ""
+"In this chapter, then, we will write ftuc in assembly language (the original "
+"tuc is in C), and study various file-oriented kernel services in the process."
+msgstr ""
+"В этой главе мы напишем ftuc на языке ассемблера (оригинальный tuc написан "
+"на C) и в процессе изучим различные файловые сервисы ядра."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1688
+msgid ""
+"At first sight, such a file conversion is very simple: All you have to do is "
+"strip the carriage returns, right?"
+msgstr ""
+"На первый взгляд, такое преобразование файла кажется очень простым: нужно "
+"всего лишь удалить символы возврата каретки, верно?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1690
+msgid ""
+"If you answered yes, think again: That approach will work most of the time "
+"(at least with MS DOS text files), but will fail occasionally."
+msgstr ""
+"Если вы ответили «да», подумайте ещё раз: такой подход будет работать в "
+"большинстве случаев (по крайней мере, с текстовыми файлами MS DOS), но "
+"иногда он будет давать сбой."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1695
+msgid ""
+"The problem is that not all non UNIX(R) text files end their line with the "
+"carriage return / line feed sequence. Some use carriage returns without "
+"line feeds. Others combine several blank lines into a single carriage "
+"return followed by several line feeds. And so on."
+msgstr ""
+"Проблема в том, что не все текстовые файлы, не относящиеся к UNIX(R), "
+"завершают строки последовательностью возврата каретки / перевода строки. "
+"Некоторые используют возврат каретки без перевода строки. Другие объединяют "
+"несколько пустых строк в один возврат каретки, за которым следует несколько "
+"переводов строки. И так далее."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1697
+msgid ""
+"A text file converter, then, must be able to handle any possible line "
+"endings:"
+msgstr ""
+"Конвертер текстовых файлов, следовательно, должен уметь обрабатывать любые "
+"возможные окончания строк:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1699
+msgid "carriage return / line feed"
+msgstr "возврат каретки (carriage return) / перевод строки (line feed)"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1700
+msgid "carriage return"
+msgstr "возврат каретки"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1701
+msgid "line feed / carriage return"
+msgstr "перевод строки / возврат каретки"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1702
+msgid "line feed"
+msgstr "перевод строки"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1704
+msgid ""
+"It should also handle files that use some kind of a combination of the above "
+"(e.g., carriage return followed by several line feeds)."
+msgstr ""
+"Это также должно обрабатывать файлы, использующие комбинации вышеуказанного "
+"(например, возврат каретки с последующими несколькими переводами строки)."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1706
+#, no-wrap
+msgid "Finite State Machine"
+msgstr "Конечный автомат"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1713
+msgid ""
+"The problem is easily solved by the use of a technique called _finite state "
+"machine_, originally developed by the designers of digital electronic "
+"circuits. A _finite state machine_ is a digital circuit whose output is "
+"dependent not only on its input but on its previous input, i.e., on its "
+"state. The microprocessor is an example of a _finite state machine_: Our "
+"assembly language code is assembled to machine language in which some "
+"assembly language code produces a single byte of machine language, while "
+"others produce several bytes. As the microprocessor fetches the bytes from "
+"the memory one by one, some of them simply change its state rather than "
+"produce some output. When all the bytes of the op code are fetched, the "
+"microprocessor produces some output, or changes the value of a register, etc."
+msgstr ""
+"Проблема легко решается с использованием техники, называемой _конечный "
+"автомат_, изначально разработанной создателями цифровых электронных схем. "
+"_Конечный автомат_ — это цифровая схема, выход которой зависит не только от "
+"входа, но и от предыдущего входа, то есть от её состояния. Микропроцессор "
+"является примером _конечного автомата_: наш код на языке ассемблера "
+"транслируется в машинный язык, где одни инструкции ассемблера превращаются в "
+"один байт машинного кода, а другие — в несколько байтов. Когда "
+"микропроцессор извлекает байты из памяти один за другим, некоторые из них "
+"просто изменяют его состояние, а не производят какой-либо выходной сигнал. "
+"После извлечения всех байтов кода операции микропроцессор выдает выходной "
+"сигнал, изменяет значение регистра и т. д."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1716
+msgid ""
+"Because of that, all software is essentially a sequence of state "
+"instructions for the microprocessor. Nevertheless, the concept of _finite "
+"state machine_ is useful in software design as well."
+msgstr ""
+"Из-за этого всё программное обеспечение по сути представляет собой "
+"последовательность инструкций состояния для микропроцессора. Тем не менее, "
+"концепция _конечного автомата_ также полезна при проектировании программного "
+"обеспечения."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1719
+msgid ""
+"Our text file converter can be designer as a _finite state machine_ with "
+"three possible states. We could call them states 0-2, but it will make our "
+"life easier if we give them symbolic names:"
+msgstr ""
+"Наш конвертер текстовых файлов можно представить в виде _конечного автомата_ "
+"с тремя возможными состояниями. Мы могли бы назвать их состояниями 0-2, но "
+"будет проще, если дадим им символические имена:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1721
+msgid "ordinary"
+msgstr "ordinary"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1722
+msgid "cr"
+msgstr "cr"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1723
+msgid "lf"
+msgstr "lf"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1725
+msgid ""
+"Our program will start in the ordinary state. During this state, the program "
+"action depends on its input as follows:"
+msgstr ""
+"Наша программа начнёт работу в обычном состоянии. В этом состоянии действие "
+"программы зависит от её входных данных следующим образом:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1728
+msgid ""
+"If the input is anything other than a carriage return or line feed, the "
+"input is simply passed on to the output. The state remains unchanged."
+msgstr ""
+"Если ввод представляет собой что-либо, кроме возврата каретки или перевода "
+"строки, ввод просто передаётся на вывод. Состояние остаётся неизменным."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1730
+msgid ""
+"If the input is a carriage return, the state is changed to cr. The input is "
+"then discarded, i.e., no output is made."
+msgstr ""
+"Если входной символ — возврат каретки, состояние изменяется на cr. Затем "
+"входной символ отбрасывается, т.е. вывод не производится."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1732
+msgid ""
+"If the input is a line feed, the state is changed to lf. The input is then "
+"discarded."
+msgstr ""
+"Если входной символ является переводом строки, состояние изменяется на lf. "
+"Затем входной символ отбрасывается."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1735
+msgid ""
+"Whenever we are in the cr state, it is because the last input was a carriage "
+"return, which was unprocessed. What our software does in this state again "
+"depends on the current input:"
+msgstr ""
+"Всякий раз, когда мы находимся в состоянии `cr`, это означает, что последним "
+"вводом был символ возврата каретки, который не был обработан. Действия "
+"нашего программного обеспечения в этом состоянии снова зависят от текущего "
+"ввода:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1737
+msgid ""
+"If the input is anything other than a carriage return or line feed, output a "
+"line feed, then output the input, then change the state to ordinary."
+msgstr ""
+"Если ввод отличается от возврата каретки или перевода строки, вывести "
+"перевод строки, затем вывести ввод, а затем изменить состояние на обычное."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1738
+msgid ""
+"If the input is a carriage return, we have received two (or more) carriage "
+"returns in a row. We discard the input, we output a line feed, and leave the "
+"state unchanged."
+msgstr ""
+"Если входной символ — возврат каретки, значит, мы получили два (или более) "
+"возврата каретки подряд. Мы отбрасываем ввод, выводим перевод строки и "
+"оставляем состояние неизменным."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1739
+msgid ""
+"If the input is a line feed, we output the line feed and change the state to "
+"ordinary. Note that this is not the same as the first case above - if we "
+"tried to combine them, we would be outputting two line feeds instead of one."
+msgstr ""
+"Если входной символ — это перевод строки, мы выводим перевод строки и меняем "
+"состояние на обычное. Обратите внимание, что это не то же самое, что в "
+"первом случае выше — если бы мы попытались объединить их, мы бы выводили два "
+"перевода строки вместо одного."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1743
+msgid ""
+"Finally, we are in the lf state after we have received a line feed that was "
+"not preceded by a carriage return. This will happen when our file already "
+"is in UNIX(R) format, or whenever several lines in a row are expressed by a "
+"single carriage return followed by several line feeds, or when line ends "
+"with a line feed / carriage return sequence. Here is how we need to handle "
+"our input in this state:"
+msgstr ""
+"Наконец, мы находимся в состоянии `lf` после получения перевода строки, "
+"которому не предшествовал возврат каретки. Это произойдет, если наш файл уже "
+"в формате UNIX(R), или когда несколько строк подряд выражены одним возвратом "
+"каретки, за которым следуют несколько переводов строк, или когда строка "
+"заканчивается последовательностью перевода строки / возврата каретки. Вот "
+"как нам нужно обрабатывать ввод в этом состоянии:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1745
+msgid ""
+"If the input is anything other than a carriage return or line feed, we "
+"output a line feed, then output the input, then change the state to "
+"ordinary. This is exactly the same action as in the cr state upon receiving "
+"the same kind of input."
+msgstr ""
+"Если ввод отличается от возврата каретки или перевода строки, мы выводим "
+"перевод строки, затем выводим ввод и изменяем состояние на обычное. Это "
+"действие полностью совпадает с действием в состоянии `cr` при получении "
+"аналогичного ввода."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1746
+msgid ""
+"If the input is a carriage return, we discard the input, we output a line "
+"feed, then change the state to ordinary."
+msgstr ""
+"Если ввод представляет собой символ возврата каретки, мы отбрасываем ввод, "
+"выводим символ перевода строки, затем изменяем состояние на обычное."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1747
+msgid ""
+"If the input is a line feed, we output the line feed, and leave the state "
+"unchanged."
+msgstr ""
+"Если входной символ — перевод строки, мы выводим перевод строки и оставляем "
+"состояние неизменным."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1749
+#, no-wrap
+msgid "The Final State"
+msgstr "Конечное состояние"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1754
+msgid ""
+"The above _finite state machine_ works for the entire file, but leaves the "
+"possibility that the final line end will be ignored. That will happen "
+"whenever the file ends with a single carriage return or a single line feed. "
+"I did not think of it when I wrote tuc, just to discover that occasionally "
+"it strips the last line ending."
+msgstr ""
+"Приведённый выше _конечный автомат_ работает для всего файла, но оставляет "
+"возможность, что последний конец строки будет проигнорирован. Это "
+"произойдёт, если файл заканчивается одиночным возвратом каретки или "
+"одиночным переводом строки. Я не подумал об этом, когда писал tuc, и лишь "
+"позже обнаружил, что иногда он удаляет последний конец строки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1757
+msgid ""
+"This problem is easily fixed by checking the state after the entire file was "
+"processed. If the state is not ordinary, we simply need to output one last "
+"line feed."
+msgstr ""
+"Эта проблема легко решается проверкой состояния после обработки всего файла. "
+"Если состояние не является обычным, нам просто нужно вывести последний "
+"перевод строки."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1763
+msgid ""
+"Now that we have expressed our algorithm as a _finite state machine_, we "
+"could easily design a dedicated digital electronic circuit (a \"chip\") to "
+"do the conversion for us. Of course, doing so would be considerably more "
+"expensive than writing an assembly language program."
+msgstr ""
+"Теперь, когда мы выразили наш алгоритм в виде _конечного автомата_, мы могли "
+"бы легко разработать специализированную цифровую электронную схему («чип») "
+"для выполнения преобразования. Конечно, это было бы значительно дороже, чем "
+"написание программы на языке ассемблера."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1766
+#, no-wrap
+msgid "The Output Counter"
+msgstr "Счетчик вывода"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1771
+msgid ""
+"Because our file conversion program may be combining two characters into "
+"one, we need to use an output counter. We initialize it to `0`, and "
+"increase it every time we send a character to the output. At the end of the "
+"program, the counter will tell us what size we need to set the file to."
+msgstr ""
+"Поскольку наша программа преобразования файлов может объединять два символа "
+"в один, нам необходимо использовать счётчик вывода. Мы инициализируем его "
+"значением `0` и увеличиваем каждый раз, когда отправляем символ на выход. В "
+"конце программы счётчик укажет, какой размер необходимо установить для файла."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1773
+#, no-wrap
+msgid "Implementing FSM in Software"
+msgstr "Реализация конечного автомата в программном обеспечении"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1777
+msgid ""
+"The hardest part of working with a _finite state machine_ is analyzing the "
+"problem and expressing it as a _finite state machine_. That accomplished, "
+"the software almost writes itself."
+msgstr ""
+"Самая сложная часть работы с _конечным автоматом_ — это анализ задачи и её "
+"представление в виде _конечного автомата_. После этого программное "
+"обеспечение практически пишется само."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1780
+msgid ""
+"In a high-level language, such as C, there are several main approaches. One "
+"is to use a `switch` statement which chooses what function should be run. "
+"For example,"
+msgstr ""
+"На языке высокого уровня, таком как C, существует несколько основных "
+"подходов. Один из них — использование оператора `switch`, который выбирает, "
+"какую функцию следует выполнить. Например,"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1795
+#, no-wrap
+msgid ""
+"switch (state) {\n"
+"\tdefault:\n"
+"\tcase REGULAR:\n"
+"\t\tregular(inputchar);\n"
+"\t\tbreak;\n"
+"\tcase CR:\n"
+"\t\tcr(inputchar);\n"
+"\t\tbreak;\n"
+"\tcase LF:\n"
+"\t\tlf(inputchar);\n"
+"\t\tbreak;\n"
+"\t}\n"
+msgstr ""
+"switch (state) {\n"
+"\tdefault:\n"
+"\tcase REGULAR:\n"
+"\t\tregular(inputchar);\n"
+"\t\tbreak;\n"
+"\tcase CR:\n"
+"\t\tcr(inputchar);\n"
+"\t\tbreak;\n"
+"\tcase LF:\n"
+"\t\tlf(inputchar);\n"
+"\t\tbreak;\n"
+"\t}\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1798
+msgid ""
+"Another approach is by using an array of function pointers, something like "
+"this:"
+msgstr ""
+"Еще один подход заключается в использовании массива указателей на функции, "
+"например:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1802
+#, no-wrap
+msgid "(output[state])(inputchar);\n"
+msgstr "(output[state])(inputchar);\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1805
+msgid ""
+"Yet another is to have `state` be a function pointer, set to point at the "
+"appropriate function:"
+msgstr ""
+"Еще один вариант — сделать `state` указателем на функцию, установив его на "
+"соответствующую функцию:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1809
+#, no-wrap
+msgid "(*state)(inputchar);\n"
+msgstr "(*state)(inputchar);\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1813
+msgid ""
+"This is the approach we will use in our program because it is very easy to "
+"do in assembly language, and very fast, too. We will simply keep the "
+"address of the right procedure in `EBX`, and then just issue:"
+msgstr ""
+"Это подход, который мы будем использовать в нашей программе, потому что его "
+"очень легко реализовать на языке ассемблера, и он также очень быстрый. Мы "
+"просто будем хранить адрес нужной процедуры в `EBX`, а затем выполним:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1817
+#, no-wrap
+msgid "call\tebx\n"
+msgstr "call\tebx\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1821
+msgid ""
+"This is possibly faster than hardcoding the address in the code because the "
+"microprocessor does not have to fetch the address from the memory-it is "
+"already stored in one of its registers. I said _possibly_ because with the "
+"caching modern microprocessors do, either way may be equally fast."
+msgstr ""
+"Это возможно быстрее, чем жестко задавать адрес в коде, потому что "
+"микропроцессору не нужно извлекать адрес из памяти — он уже хранится в одном "
+"из его регистров. Я сказал _возможно_, потому что с учетом кэширования, "
+"которое выполняют современные микропроцессоры, оба варианта могут быть "
+"одинаково быстрыми."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1823
+#, no-wrap
+msgid "Memory Mapped Files"
+msgstr "Отображенные в память файлы"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1827
+msgid ""
+"Because our program works on a single file, we cannot use the approach that "
+"worked for us before, i.e., to read from an input file and to write to an "
+"output file."
+msgstr ""
+"Поскольку наша программа работает с одним файлом, мы не можем использовать "
+"подход, который работал ранее, то есть чтение из входного файла и запись в "
+"выходной файл."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1835
+msgid ""
+"UNIX(R) allows us to map a file, or a section of a file, into memory. To do "
+"that, we first need to open the file with the appropriate read/write flags. "
+"Then we use the `mmap` system call to map it into the memory. One nice "
+"thing about `mmap` is that it automatically works with virtual memory: We "
+"can map more of the file into the memory than we have physical memory "
+"available, yet still access it through regular memory op codes, such as "
+"`mov`, `lods`, and `stos`. Whatever changes we make to the memory image of "
+"the file will be written to the file by the system. We do not even have to "
+"keep the file open: As long as it stays mapped, we can read from it and "
+"write to it."
+msgstr ""
+"UNIX(R) позволяет нам отображать файл или его часть в память. Для этого "
+"сначала необходимо открыть файл с соответствующими флагами чтения/записи. "
+"Затем мы используем системный вызов `mmap`, чтобы отобразить его в память. "
+"Одно из преимуществ `mmap` заключается в том, что он автоматически работает "
+"с виртуальной памятью: мы можем отобразить в память больше файла, чем "
+"имеется физической памяти, и при этом обращаться к нему с помощью обычных "
+"команд работы с памятью, таких как `mov`, `lods` и `stos`. Все изменения, "
+"внесённые в память, отображённую из файла, будут записаны в файл системой. "
+"Нам даже не нужно держать файл открытым: пока он остаётся отображённым, мы "
+"можем читать из него и записывать в него."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1838
+msgid ""
+"The 32-bit Intel microprocessors can access up to four gigabytes of memory - "
+"physical or virtual. The FreeBSD system allows us to use up to a half of it "
+"for file mapping."
+msgstr ""
+"32-разрядные микропроцессоры Intel могут адресовать до четырёх гигабайт "
+"памяти — физической или виртуальной. Система FreeBSD позволяет использовать "
+"до половины этого объёма для отображения файлов."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1842
+msgid ""
+"For simplicity sake, in this tutorial we will only convert files that can be "
+"mapped into the memory in their entirety. There are probably not too many "
+"text files that exceed two gigabytes in size. If our program encounters "
+"one, it will simply display a message suggesting we use the original tuc "
+"instead."
+msgstr ""
+"Для упрощения в этом руководстве мы будем преобразовывать только файлы, "
+"которые могут быть полностью отображены в памяти. Вероятно, не так много "
+"текстовых файлов превышают размер в два гигабайта. Если наша программа "
+"встретит такой файл, она просто выведет сообщение с предложением "
+"использовать оригинальный tuc."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1848
+msgid ""
+"If you examine your copy of [.filename]#syscalls.master#, you will find two "
+"separate syscalls named `mmap`. This is because of evolution of UNIX(R): "
+"There was the traditional BSD `mmap`, syscall 71. That one was superseded "
+"by the POSIX(R) `mmap`, syscall 197. The FreeBSD system supports both "
+"because older programs were written by using the original BSD version. But "
+"new software uses the POSIX(R) version, which is what we will use."
+msgstr ""
+"Если вы изучите свою копию файла [.filename]#syscalls.master#, вы найдёте "
+"два отдельных системных вызова с именем `mmap`. Это связано с эволюцией "
+"UNIX(R): существовал традиционный BSD `mmap`, системный вызов 71. Он был "
+"заменён на POSIX(R) `mmap`, системный вызов 197. Система FreeBSD "
+"поддерживает оба, поскольку старые программы были написаны с использованием "
+"оригинальной BSD-версии. Но новое программное обеспечение использует версию "
+"POSIX(R), которую мы и будем применять."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1850
+msgid "The [.filename]#syscalls.master# lists the POSIX(R) version like this:"
+msgstr ""
+"В [.filename]#syscalls.master# POSIX(R) версия указана следующим образом:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1855
+#, no-wrap
+msgid ""
+"197\tSTD\tBSD\t{ caddr_t mmap(caddr_t addr, size_t len, int prot, \\\n"
+"\t\t\t int flags, int fd, long pad, off_t pos); }\n"
+msgstr ""
+"197\tSTD\tBSD\t{ caddr_t mmap(caddr_t addr, size_t len, int prot, \\\n"
+"\t\t\t int flags, int fd, long pad, off_t pos); }\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1859
+msgid ""
+"This differs slightly from what man:mmap[2] says. That is because man:"
+"mmap[2] describes the C version."
+msgstr ""
+"Это немного отличается от того, что указано в man:mmap[2]. Это связано с "
+"тем, что man:mmap[2] описывает версию на языке C."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1863
+msgid ""
+"The difference is in the `long pad` argument, which is not present in the C "
+"version. However, the FreeBSD syscalls add a 32-bit pad after ``push``ing a "
+"64-bit argument. In this case, `off_t` is a 64-bit value."
+msgstr ""
+"Разница заключается в аргументе `long pad`, который отсутствует в версии на "
+"C. Однако системные вызовы FreeBSD добавляют 32-битный заполнитель после "
+"``push`` 64-битного аргумента. В данном случае `off_t` является 64-битным "
+"значением."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1865
+msgid ""
+"When we are finished working with a memory-mapped file, we unmap it with the "
+"`munmap` syscall:"
+msgstr ""
+"Когда мы завершаем работу с файлом, отображённым в память, мы освобождаем "
+"его с помощью системного вызова `munmap`:"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1869
+msgid ""
+"For an in-depth treatment of `mmap`, see W. Richard Stevens' http://www."
+"int80h.org/cgi-bin/isbn?isbn=0130810819[Unix Network Programming, Volume 2, "
+"Chapter 12]."
+msgstr ""
+"Для подробного изучения `mmap` см. http://www.int80h.org/cgi-bin/isbn?"
+"isbn=0130810819[Unix Network Programming, Volume 2, Chapter 12] У. Ричарда "
+"Стивенса."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1872
+#, no-wrap
+msgid "Determining File Size"
+msgstr "Определение размера файла"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1875
+msgid ""
+"Because we need to tell `mmap` how many bytes of the file to map into the "
+"memory, and because we want to map the entire file, we need to determine the "
+"size of the file."
+msgstr ""
+"Поскольку нам нужно указать `mmap`, сколько байт файла отобразить в памяти, "
+"и поскольку мы хотим отобразить весь файл, нам необходимо определить его "
+"размер."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1878
+msgid ""
+"We can use the `fstat` syscall to get all the information about an open file "
+"that the system can give us. That includes the file size."
+msgstr ""
+"Мы можем использовать системный вызов `fstat` для получения всей информации "
+"об открытом файле, которую система может нам предоставить. Это включает в "
+"себя размер файла."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1881
+msgid ""
+"Again, [.filename]#syscalls.master# lists two versions of `fstat`, a "
+"traditional one (syscall 62), and a POSIX(R) one (syscall 189). Naturally, "
+"we will use the POSIX(R) version:"
+msgstr ""
+"Вновь, в [.filename]#syscalls.master# указаны две версии `fstat`: "
+"традиционная (системный вызов 62) и POSIX(R) (системный вызов 189). "
+"Естественно, мы будем использовать версию POSIX(R):"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1885
+#, no-wrap
+msgid "189\tSTD\tPOSIX\t{ int fstat(int fd, struct stat *sb); }\n"
+msgstr "189\tSTD\tPOSIX\t{ int fstat(int fd, struct stat *sb); }\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1889
+msgid ""
+"This is a very straightforward call: We pass to it the address of a `stat` "
+"structure and the descriptor of an open file. It will fill out the contents "
+"of the `stat` structure."
+msgstr ""
+"Это очень простой вызов: мы передаем ему адрес структуры `stat` и дескриптор "
+"открытого файла. Он заполнит содержимое структуры `stat`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1892
+msgid ""
+"I do, however, have to say that I tried to declare the `stat` structure in "
+"the `.bss` section, and `fstat` did not like it: It set the carry flag "
+"indicating an error. After I changed the code to allocate the structure on "
+"the stack, everything was working fine."
+msgstr ""
+"Однако должен сказать, что я пытался объявить структуру `stat` в секции `."
+"bss`, и `fstat` это не понравилось: был установлен флаг переноса, "
+"указывающий на ошибку. После того как я изменил код, чтобы разместить "
+"структуру в стеке, всё заработало как надо."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1894
+#, no-wrap
+msgid "Changing the File Size"
+msgstr "Изменение размера файла"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1898
+msgid ""
+"Because our program may combine carriage return / line feed sequences into "
+"straight line feeds, our output may be smaller than our input. However, "
+"since we are placing our output into the same file we read the input from, "
+"we may have to change the size of the file."
+msgstr ""
+"Поскольку наша программа может объединять последовательности возврата "
+"каретки / перевода строки в простые переводы строк, наш вывод может быть "
+"меньше, чем ввод. Однако, так как мы помещаем вывод в тот же файл, из "
+"которого читаем ввод, нам может потребоваться изменить размер файла."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1901
+msgid ""
+"The `ftruncate` system call allows us to do just that. Despite its somewhat "
+"misleading name, the `ftruncate` system call can be used to both truncate "
+"the file (make it smaller) and to grow it."
+msgstr ""
+"Системный вызов `ftruncate` позволяет нам сделать именно это. Несмотря на "
+"название , несколько вводящее в заблуждение, системный вызов `ftruncate` "
+"может использоваться как для усечения файла (уменьшения его размера), так и "
+"для его увеличения."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1904
+msgid ""
+"And yes, we will find two versions of `ftruncate` in [.filename]#syscalls."
+"master#, an older one (130), and a newer one (201). We will use the newer "
+"one:"
+msgstr ""
+"И да, мы найдем две версии `ftruncate` в [.filename]#syscalls.master#, "
+"старую (130) и новую (201). Мы будем использовать новую:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1908
+#, no-wrap
+msgid "201\tSTD\tBSD\t{ int ftruncate(int fd, int pad, off_t length); }\n"
+msgstr "201\tSTD\tBSD\t{ int ftruncate(int fd, int pad, off_t length); }\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1911
+msgid "Please note that this one contains a `int pad` again."
+msgstr "Обратите внимание, что здесь снова присутствует `int pad`."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1913
+#, no-wrap
+msgid "ftuc"
+msgstr "ftuc"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1918
+msgid ""
+"We now know everything we need to write ftuc. We start by adding some new "
+"lines in [.filename]#system.inc#. First, we define some constants and "
+"structures, somewhere at or near the beginning of the file:"
+msgstr ""
+"Теперь мы знаем всё, что нужно для написания ftuc. Начнём с добавления "
+"нескольких новых строк в [.filename]#system.inc#. Сначала определим "
+"некоторые константы и структуры, где-нибудь в начале или около начала файла:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1925
+#, no-wrap
+msgid ""
+";;;;;;; open flags\n"
+"%define\tO_RDONLY\t0\n"
+"%define\tO_WRONLY\t1\n"
+"%define\tO_RDWR\t2\n"
+msgstr ""
+";;;;;;; open flags\n"
+"%define\tO_RDONLY\t0\n"
+"%define\tO_WRONLY\t1\n"
+"%define\tO_RDWR\t2\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1934
+#, no-wrap
+msgid ""
+";;;;;;; mmap flags\n"
+"%define\tPROT_NONE\t0\n"
+"%define\tPROT_READ\t1\n"
+"%define\tPROT_WRITE\t2\n"
+"%define\tPROT_EXEC\t4\n"
+";;\n"
+"%define\tMAP_SHARED\t0001h\n"
+"%define\tMAP_PRIVATE\t0002h\n"
+msgstr ""
+";;;;;;; mmap flags\n"
+"%define\tPROT_NONE\t0\n"
+"%define\tPROT_READ\t1\n"
+"%define\tPROT_WRITE\t2\n"
+"%define\tPROT_EXEC\t4\n"
+";;\n"
+"%define\tMAP_SHARED\t0001h\n"
+"%define\tMAP_PRIVATE\t0002h\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1958
+#, no-wrap
+msgid ""
+";;;;;;; stat structure\n"
+"struc\tstat\n"
+"st_dev\t\tresd\t1\t; = 0\n"
+"st_ino\t\tresd\t1\t; = 4\n"
+"st_mode\t\tresw\t1\t; = 8, size is 16 bits\n"
+"st_nlink\tresw\t1\t; = 10, ditto\n"
+"st_uid\t\tresd\t1\t; = 12\n"
+"st_gid\t\tresd\t1\t; = 16\n"
+"st_rdev\t\tresd\t1\t; = 20\n"
+"st_atime\tresd\t1\t; = 24\n"
+"st_atimensec\tresd\t1\t; = 28\n"
+"st_mtime\tresd\t1\t; = 32\n"
+"st_mtimensec\tresd\t1\t; = 36\n"
+"st_ctime\tresd\t1\t; = 40\n"
+"st_ctimensec\tresd\t1\t; = 44\n"
+"st_size\t\tresd\t2\t; = 48, size is 64 bits\n"
+"st_blocks\tresd\t2\t; = 56, ditto\n"
+"st_blksize\tresd\t1\t; = 64\n"
+"st_flags\tresd\t1\t; = 68\n"
+"st_gen\t\tresd\t1\t; = 72\n"
+"st_lspare\tresd\t1\t; = 76\n"
+"st_qspare\tresd\t4\t; = 80\n"
+"endstruc\n"
+msgstr ""
+";;;;;;; stat structure\n"
+"struc\tstat\n"
+"st_dev\t\tresd\t1\t; = 0\n"
+"st_ino\t\tresd\t1\t; = 4\n"
+"st_mode\t\tresw\t1\t; = 8, size is 16 bits\n"
+"st_nlink\tresw\t1\t; = 10, ditto\n"
+"st_uid\t\tresd\t1\t; = 12\n"
+"st_gid\t\tresd\t1\t; = 16\n"
+"st_rdev\t\tresd\t1\t; = 20\n"
+"st_atime\tresd\t1\t; = 24\n"
+"st_atimensec\tresd\t1\t; = 28\n"
+"st_mtime\tresd\t1\t; = 32\n"
+"st_mtimensec\tresd\t1\t; = 36\n"
+"st_ctime\tresd\t1\t; = 40\n"
+"st_ctimensec\tresd\t1\t; = 44\n"
+"st_size\t\tresd\t2\t; = 48, size is 64 bits\n"
+"st_blocks\tresd\t2\t; = 56, ditto\n"
+"st_blksize\tresd\t1\t; = 64\n"
+"st_flags\tresd\t1\t; = 68\n"
+"st_gen\t\tresd\t1\t; = 72\n"
+"st_lspare\tresd\t1\t; = 76\n"
+"st_qspare\tresd\t4\t; = 80\n"
+"endstruc\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1961
+msgid "We define the new syscalls:"
+msgstr "Мы определяем новые системные вызовы:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1968
+#, no-wrap
+msgid ""
+"%define\tSYS_mmap\t197\n"
+"%define\tSYS_munmap\t73\n"
+"%define\tSYS_fstat\t189\n"
+"%define\tSYS_ftruncate\t201\n"
+msgstr ""
+"%define\tSYS_mmap\t197\n"
+"%define\tSYS_munmap\t73\n"
+"%define\tSYS_fstat\t189\n"
+"%define\tSYS_ftruncate\t201\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1971
+msgid "We add the macros for their use:"
+msgstr "Добавляем макросы для их использования:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1977
+#, no-wrap
+msgid ""
+"%macro\tsys.mmap\t0\n"
+"\tsystem\tSYS_mmap\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.mmap\t0\n"
+"\tsystem\tSYS_mmap\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1981
+#, no-wrap
+msgid ""
+"%macro\tsys.munmap\t0\n"
+"\tsystem\tSYS_munmap\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.munmap\t0\n"
+"\tsystem\tSYS_munmap\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1985
+#, no-wrap
+msgid ""
+"%macro\tsys.ftruncate\t0\n"
+"\tsystem\tSYS_ftruncate\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.ftruncate\t0\n"
+"\tsystem\tSYS_ftruncate\n"
+"%endmacro\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1989
+#, no-wrap
+msgid ""
+"%macro\tsys.fstat\t0\n"
+"\tsystem\tSYS_fstat\n"
+"%endmacro\n"
+msgstr ""
+"%macro\tsys.fstat\t0\n"
+"\tsystem\tSYS_fstat\n"
+"%endmacro\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:1992
+msgid "And here is our code:"
+msgstr "И вот наш код:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2005
+#, no-wrap
+msgid ""
+";;;;;;; Fast Text-to-Unix Conversion (ftuc.asm) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";;\n"
+";; Started:\t21-Dec-2000\n"
+";; Updated:\t22-Dec-2000\n"
+";;\n"
+";; Copyright 2000 G. Adam Stanislav.\n"
+";; All rights reserved.\n"
+";;\n"
+";;;;;;; v.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+"%include\t'system.inc'\n"
+msgstr ""
+";;;;;;; Fast Text-to-Unix Conversion (ftuc.asm) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";;\n"
+";; Started:\t21-Dec-2000\n"
+";; Updated:\t22-Dec-2000\n"
+";;\n"
+";; Copyright 2000 G. Adam Stanislav.\n"
+";; All rights reserved.\n"
+";;\n"
+";;;;;;; v.1 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+"%include\t'system.inc'\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2019
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"\tdb\t'Copyright 2000 G. Adam Stanislav.', 0Ah\n"
+"\tdb\t'All rights reserved.', 0Ah\n"
+"usg\tdb\t'Usage: ftuc filename', 0Ah\n"
+"usglen\tequ\t$-usg\n"
+"co\tdb\t\"ftuc: Can't open file.\", 0Ah\n"
+"colen\tequ\t$-co\n"
+"fae\tdb\t'ftuc: File access error.', 0Ah\n"
+"faelen\tequ\t$-fae\n"
+"ftl\tdb\t'ftuc: File too long, use regular tuc instead.', 0Ah\n"
+"ftllen\tequ\t$-ftl\n"
+"mae\tdb\t'ftuc: Memory allocation error.', 0Ah\n"
+"maelen\tequ\t$-mae\n"
+msgstr ""
+"section\t.data\n"
+"\tdb\t'Copyright 2000 G. Adam Stanislav.', 0Ah\n"
+"\tdb\t'All rights reserved.', 0Ah\n"
+"usg\tdb\t'Usage: ftuc filename', 0Ah\n"
+"usglen\tequ\t$-usg\n"
+"co\tdb\t\"ftuc: Can't open file.\", 0Ah\n"
+"colen\tequ\t$-co\n"
+"fae\tdb\t'ftuc: File access error.', 0Ah\n"
+"faelen\tequ\t$-fae\n"
+"ftl\tdb\t'ftuc: File too long, use regular tuc instead.', 0Ah\n"
+"ftllen\tequ\t$-ftl\n"
+"mae\tdb\t'ftuc: Memory allocation error.', 0Ah\n"
+"maelen\tequ\t$-mae\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2021
+#, no-wrap
+msgid "section\t.text\n"
+msgstr "section\t.text\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2027
+#, no-wrap
+msgid ""
+"align 4\n"
+"memerr:\n"
+"\tpush\tdword maelen\n"
+"\tpush\tdword mae\n"
+"\tjmp\tshort error\n"
+msgstr ""
+"align 4\n"
+"memerr:\n"
+"\tpush\tdword maelen\n"
+"\tpush\tdword mae\n"
+"\tjmp\tshort error\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2033
+#, no-wrap
+msgid ""
+"align 4\n"
+"toolong:\n"
+"\tpush\tdword ftllen\n"
+"\tpush\tdword ftl\n"
+"\tjmp\tshort error\n"
+msgstr ""
+"align 4\n"
+"toolong:\n"
+"\tpush\tdword ftllen\n"
+"\tpush\tdword ftl\n"
+"\tjmp\tshort error\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2039
+#, no-wrap
+msgid ""
+"align 4\n"
+"facerr:\n"
+"\tpush\tdword faelen\n"
+"\tpush\tdword fae\n"
+"\tjmp\tshort error\n"
+msgstr ""
+"align 4\n"
+"facerr:\n"
+"\tpush\tdword faelen\n"
+"\tpush\tdword fae\n"
+"\tjmp\tshort error\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2045
+#, no-wrap
+msgid ""
+"align 4\n"
+"cantopen:\n"
+"\tpush\tdword colen\n"
+"\tpush\tdword co\n"
+"\tjmp\tshort error\n"
+msgstr ""
+"align 4\n"
+"cantopen:\n"
+"\tpush\tdword colen\n"
+"\tpush\tdword co\n"
+"\tjmp\tshort error\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2050
+#, no-wrap
+msgid ""
+"align 4\n"
+"usage:\n"
+"\tpush\tdword usglen\n"
+"\tpush\tdword usg\n"
+msgstr ""
+"align 4\n"
+"usage:\n"
+"\tpush\tdword usglen\n"
+"\tpush\tdword usg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2054
+#, no-wrap
+msgid ""
+"error:\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+msgstr ""
+"error:\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2057
+#, no-wrap
+msgid ""
+"\tpush\tdword 1\n"
+"\tsys.exit\n"
+msgstr ""
+"\tpush\tdword 1\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2065
+#, no-wrap
+msgid ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tpop\teax\t\t; argc\n"
+"\tpop\teax\t\t; program name\n"
+"\tpop\tecx\t\t; file to convert\n"
+"\tjecxz\tusage\n"
+msgstr ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tpop\teax\t\t; argc\n"
+"\tpop\teax\t\t; program name\n"
+"\tpop\tecx\t\t; file to convert\n"
+"\tjecxz\tusage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2069
+#, no-wrap
+msgid ""
+"\tpop\teax\n"
+"\tor\teax, eax\t; Too many arguments?\n"
+"\tjne\tusage\n"
+msgstr ""
+"\tpop\teax\n"
+"\tor\teax, eax\t; Too many arguments?\n"
+"\tjne\tusage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2075
+#, no-wrap
+msgid ""
+"\t; Open the file\n"
+"\tpush\tdword O_RDWR\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\tcantopen\n"
+msgstr ""
+"\t; Open the file\n"
+"\tpush\tdword O_RDWR\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\tcantopen\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2077
+#, no-wrap
+msgid "\tmov\tebp, eax\t; Save fd\n"
+msgstr "\tmov\tebp, eax\t; Save fd\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2080
+#, no-wrap
+msgid ""
+"\tsub\tesp, byte stat_size\n"
+"\tmov\tebx, esp\n"
+msgstr ""
+"\tsub\tesp, byte stat_size\n"
+"\tmov\tebx, esp\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2086
+#, no-wrap
+msgid ""
+"\t; Find file size\n"
+"\tpush\tebx\n"
+"\tpush\tebp\t\t; fd\n"
+"\tsys.fstat\n"
+"\tjc\tfacerr\n"
+msgstr ""
+"\t; Find file size\n"
+"\tpush\tebx\n"
+"\tpush\tebp\t\t; fd\n"
+"\tsys.fstat\n"
+"\tjc\tfacerr\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2088
+#, no-wrap
+msgid "\tmov\tedx, [ebx + st_size + 4]\n"
+msgstr "\tmov\tedx, [ebx + st_size + 4]\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2096
+#, no-wrap
+msgid ""
+"\t; File is too long if EDX != 0 ...\n"
+"\tor\tedx, edx\n"
+"\tjne\tnear toolong\n"
+"\tmov\tecx, [ebx + st_size]\n"
+"\t; ... or if it is above 2 GB\n"
+"\tor\tecx, ecx\n"
+"\tjs\tnear toolong\n"
+msgstr ""
+"\t; File is too long if EDX != 0 ...\n"
+"\tor\tedx, edx\n"
+"\tjne\tnear toolong\n"
+"\tmov\tecx, [ebx + st_size]\n"
+"\t; ... or if it is above 2 GB\n"
+"\tor\tecx, ecx\n"
+"\tjs\tnear toolong\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2099
+#, no-wrap
+msgid ""
+"\t; Do nothing if the file is 0 bytes in size\n"
+"\tjecxz\t.quit\n"
+msgstr ""
+"\t; Do nothing if the file is 0 bytes in size\n"
+"\tjecxz\t.quit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2111
+#, no-wrap
+msgid ""
+"\t; Map the entire file in memory\n"
+"\tpush\tedx\n"
+"\tpush\tedx\t\t; starting at offset 0\n"
+"\tpush\tedx\t\t; pad\n"
+"\tpush\tebp\t\t; fd\n"
+"\tpush\tdword MAP_SHARED\n"
+"\tpush\tdword PROT_READ | PROT_WRITE\n"
+"\tpush\tecx\t\t; entire file size\n"
+"\tpush\tedx\t\t; let system decide on the address\n"
+"\tsys.mmap\n"
+"\tjc\tnear memerr\n"
+msgstr ""
+"\t; Map the entire file in memory\n"
+"\tpush\tedx\n"
+"\tpush\tedx\t\t; starting at offset 0\n"
+"\tpush\tedx\t\t; pad\n"
+"\tpush\tebp\t\t; fd\n"
+"\tpush\tdword MAP_SHARED\n"
+"\tpush\tdword PROT_READ | PROT_WRITE\n"
+"\tpush\tecx\t\t; entire file size\n"
+"\tpush\tedx\t\t; let system decide on the address\n"
+"\tsys.mmap\n"
+"\tjc\tnear memerr\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2116
+#, no-wrap
+msgid ""
+"\tmov\tedi, eax\n"
+"\tmov\tesi, eax\n"
+"\tpush\tecx\t\t; for SYS_munmap\n"
+"\tpush\tedi\n"
+msgstr ""
+"\tmov\tedi, eax\n"
+"\tmov\tesi, eax\n"
+"\tpush\tecx\t\t; for SYS_munmap\n"
+"\tpush\tedi\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2121
+#, no-wrap
+msgid ""
+"\t; Use EBX for state machine\n"
+"\tmov\tebx, ordinary\n"
+"\tmov\tah, 0Ah\n"
+"\tcld\n"
+msgstr ""
+"\t; Use EBX for state machine\n"
+"\tmov\tebx, ordinary\n"
+"\tmov\tah, 0Ah\n"
+"\tcld\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2126
+#, no-wrap
+msgid ""
+".loop:\n"
+"\tlodsb\n"
+"\tcall\tebx\n"
+"\tloop\t.loop\n"
+msgstr ""
+".loop:\n"
+"\tlodsb\n"
+"\tcall\tebx\n"
+"\tloop\t.loop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2129
+#, no-wrap
+msgid ""
+"\tcmp\tebx, ordinary\n"
+"\tje\t.filesize\n"
+msgstr ""
+"\tcmp\tebx, ordinary\n"
+"\tje\t.filesize\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2134
+#, no-wrap
+msgid ""
+"\t; Output final lf\n"
+"\tmov\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+msgstr ""
+"\t; Output final lf\n"
+"\tmov\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2142
+#, no-wrap
+msgid ""
+".filesize:\n"
+"\t; truncate file to new size\n"
+"\tpush\tdword 0\t\t; high dword\n"
+"\tpush\tedx\t\t; low dword\n"
+"\tpush\teax\t\t; pad\n"
+"\tpush\tebp\n"
+"\tsys.ftruncate\n"
+msgstr ""
+".filesize:\n"
+"\t; truncate file to new size\n"
+"\tpush\tdword 0\t\t; high dword\n"
+"\tpush\tedx\t\t; low dword\n"
+"\tpush\teax\t\t; pad\n"
+"\tpush\tebp\n"
+"\tsys.ftruncate\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2145
+#, no-wrap
+msgid ""
+"\t; close it (ebp still pushed)\n"
+"\tsys.close\n"
+msgstr ""
+"\t; close it (ebp still pushed)\n"
+"\tsys.close\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2148
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 16\n"
+"\tsys.munmap\n"
+msgstr ""
+"\tadd\tesp, byte 16\n"
+"\tsys.munmap\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2152
+#, no-wrap
+msgid ""
+".quit:\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+msgstr ""
+".quit:\n"
+"\tpush\tdword 0\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2157
+#, no-wrap
+msgid ""
+"align 4\n"
+"ordinary:\n"
+"\tcmp\tal, 0Dh\n"
+"\tje\t.cr\n"
+msgstr ""
+"align 4\n"
+"ordinary:\n"
+"\tcmp\tal, 0Dh\n"
+"\tje\t.cr\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2160
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2182
+#, no-wrap
+msgid ""
+"\tcmp\tal, ah\n"
+"\tje\t.lf\n"
+msgstr ""
+"\tcmp\tal, ah\n"
+"\tje\t.lf\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2164
+#, no-wrap
+msgid ""
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tret\n"
+msgstr ""
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2169
+#, no-wrap
+msgid ""
+"align 4\n"
+".cr:\n"
+"\tmov\tebx, cr\n"
+"\tret\n"
+msgstr ""
+"align 4\n"
+".cr:\n"
+"\tmov\tebx, cr\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2174
+#, no-wrap
+msgid ""
+"align 4\n"
+".lf:\n"
+"\tmov\tebx, lf\n"
+"\tret\n"
+msgstr ""
+"align 4\n"
+".lf:\n"
+"\tmov\tebx, lf\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2179
+#, no-wrap
+msgid ""
+"align 4\n"
+"cr:\n"
+"\tcmp\tal, 0Dh\n"
+"\tje\t.cr\n"
+msgstr ""
+"align 4\n"
+"cr:\n"
+"\tcmp\tal, 0Dh\n"
+"\tje\t.cr\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2186
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2214
+#, no-wrap
+msgid ""
+"\txchg\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+msgstr ""
+"\txchg\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2189
+#, no-wrap
+msgid ""
+"\txchg\tal, ah\n"
+"\t; fall through\n"
+msgstr ""
+"\txchg\tal, ah\n"
+"\t; fall through\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2195
+#, no-wrap
+msgid ""
+".lf:\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tmov\tebx, ordinary\n"
+"\tret\n"
+msgstr ""
+".lf:\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tmov\tebx, ordinary\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2202
+#, no-wrap
+msgid ""
+"align 4\n"
+".cr:\n"
+"\tmov\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tret\n"
+msgstr ""
+"align 4\n"
+".cr:\n"
+"\tmov\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2207
+#, no-wrap
+msgid ""
+"align 4\n"
+"lf:\n"
+"\tcmp\tal, ah\n"
+"\tje\t.lf\n"
+msgstr ""
+"align 4\n"
+"lf:\n"
+"\tcmp\tal, ah\n"
+"\tje\t.lf\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2210
+#, no-wrap
+msgid ""
+"\tcmp\tal, 0Dh\n"
+"\tje\t.cr\n"
+msgstr ""
+"\tcmp\tal, 0Dh\n"
+"\tje\t.cr\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2220
+#, no-wrap
+msgid ""
+"\txchg\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tmov\tebx, ordinary\n"
+"\tret\n"
+msgstr ""
+"\txchg\tal, ah\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tmov\tebx, ordinary\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2226
+#, no-wrap
+msgid ""
+"align 4\n"
+".cr:\n"
+"\tmov\tebx, ordinary\n"
+"\tmov\tal, ah\n"
+"\t; fall through\n"
+msgstr ""
+"align 4\n"
+".cr:\n"
+"\tmov\tebx, ordinary\n"
+"\tmov\tal, ah\n"
+"\t; fall through\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2231
+#, no-wrap
+msgid ""
+".lf:\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tret\n"
+msgstr ""
+".lf:\n"
+"\tstosb\n"
+"\tinc\tedx\n"
+"\tret\n"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2238
+msgid ""
+"Do not use this program on files stored on a disk formatted by MS-DOS(R) or "
+"Windows(R). There seems to be a subtle bug in the FreeBSD code when using "
+"`mmap` on these drives mounted under FreeBSD: If the file is over a certain "
+"size, `mmap` will just fill the memory with zeros, and then copy them to the "
+"file overwriting its contents."
+msgstr ""
+"Не используйте эту программу для файлов, хранящихся на диске, "
+"отформатированном в MS-DOS(R) или Windows(R). В коде FreeBSD присутствует "
+"неочевидная ошибка при использовании `mmap` на таких дисках, смонтированных "
+"в FreeBSD: если размер файла превышает определённое значение, `mmap` "
+"заполнит память нулями, а затем запишет их в файл, перезаписав его "
+"содержимое."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2241
+#, no-wrap
+msgid "One-Pointed Mind"
+msgstr "Спокойствие ума"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2244
+msgid ""
+"As a student of Zen, I like the idea of a one-pointed mind: Do one thing at "
+"a time, and do it well."
+msgstr ""
+"Как ученик дзэн, мне нравится идея спокойствия ума (экаггата): делай одно "
+"дело за раз и делай его хорошо."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2247
+msgid ""
+"This, indeed, is very much how UNIX(R) works as well. While a typical "
+"Windows(R) application is attempting to do everything imaginable (and is, "
+"therefore, riddled with bugs), a typical UNIX(R) program does only one "
+"thing, and it does it well."
+msgstr ""
+"Вот именно так, в большинстве случаев, работает и UNIX(R). В то время как "
+"типичное приложение Windows(R) пытается сделать всё, что только можно (и "
+"поэтому кишит ошибками), типичная программа UNIX(R) делает только одну вещь, "
+"но делает её хорошо."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2249
+msgid ""
+"The typical UNIX(R) user then essentially assembles his own applications by "
+"writing a shell script which combines the various existing programs by "
+"piping the output of one program to the input of another."
+msgstr ""
+"Типичный пользователь UNIX(R) по сути собирает свои собственные приложения, "
+"написав shell-скрипт, который объединяет различные существующие программы, "
+"передавая вывод одной программы на вход другой."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2251
+msgid ""
+"When writing your own UNIX(R) software, it is generally a good idea to see "
+"what parts of the problem you need to solve can be handled by existing "
+"programs, and only write your own programs for that part of the problem that "
+"you do not have an existing solution for."
+msgstr ""
+"При написании собственного программного обеспечения для UNIX(R) обычно "
+"рекомендуется определить, какие части решаемой задачи могут быть обработаны "
+"существующими программами, и создавать собственные программы только для той "
+"части задачи, для которой нет готового решения."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2253
+#, no-wrap
+msgid "CSV"
+msgstr "CSV"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2256
+msgid ""
+"I will illustrate this principle with a specific real-life example I was "
+"faced with recently:"
+msgstr ""
+"Я проиллюстрирую этот принцип конкретным примером из реальной жизни, с "
+"которым недавно столкнулся:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2260
+msgid ""
+"I needed to extract the 11th field of each record from a database I "
+"downloaded from a web site. The database was a CSV file, i.e., a list of "
+"_comma-separated values_. That is quite a standard format for sharing data "
+"among people who may be using different database software."
+msgstr ""
+"Мне нужно было извлечь 11-е поле каждой записи из базы данных, которую я "
+"загрузил с веб-сайта. База данных представляла собой CSV-файл, то есть "
+"список _значений, разделённых запятыми_. Это довольно стандартный формат для "
+"обмена данными между людьми, которые могут использовать разное программное "
+"обеспечение для работы с базами данных."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2263
+msgid ""
+"The first line of the file contains the list of various fields separated by "
+"commas. The rest of the file contains the data listed line by line, with "
+"values separated by commas."
+msgstr ""
+"Первая строка файла содержит список различных полей, разделенных запятыми. "
+"Остальная часть файла содержит данные, перечисленные построчно, со "
+"значениями, разделенными запятыми."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2265
+msgid ""
+"I tried awk, using the comma as a separator. But because several lines "
+"contained a quoted comma, awk was extracting the wrong field from those "
+"lines."
+msgstr ""
+"Я попробовал awk, используя запятую в качестве разделителя. Но поскольку "
+"несколько строк содержали запятую в кавычках, awk извлекал неправильное поле "
+"из этих строк."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2268
+msgid ""
+"Therefore, I needed to write my own software to extract the 11th field from "
+"the CSV file. However, going with the UNIX(R) spirit, I only needed to "
+"write a simple filter that would do the following:"
+msgstr ""
+"Следовательно, мне нужно было написать собственное программное обеспечение "
+"для извлечения 11-го поля из CSV-файла. Однако, следуя духу UNIX(R), мне "
+"нужно было лишь создать простой фильтр, выполняющий следующие действия:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2270
+msgid "Remove the first line from the file;"
+msgstr "Удалить первую строку из файла;"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2271
+msgid "Change all unquoted commas to a different character;"
+msgstr "Заменить все не заключённые в кавычки запятые на другой символ;"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2272
+msgid "Remove all quotation marks."
+msgstr "Удалить все кавычки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2274
+msgid ""
+"Strictly speaking, I could use sed to remove the first line from the file, "
+"but doing so in my own program was very easy, so I decided to do it and "
+"reduce the size of the pipeline."
+msgstr ""
+"Строго говоря, я мог бы использовать sed для удаления первой строки из "
+"файла, но сделать это в моей собственной программе было очень просто, "
+"поэтому я решил так поступить и уменьшить размер конвейера."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2278
+msgid ""
+"At any rate, writing a program like this took me about 20 minutes. Writing "
+"a program that extracts the 11th field from the CSV file would take a lot "
+"longer, and I could not reuse it to extract some other field from some other "
+"database."
+msgstr ""
+"В любом случае, написание подобной программы заняло у меня около 20 минут. "
+"Написание программы, которая извлекает 11-е поле из CSV-файла, заняло бы "
+"гораздо больше времени, и я не смог бы повторно использовать её для "
+"извлечения другого поля из другой базы данных."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2280
+msgid ""
+"This time I decided to let it do a little more work than a typical tutorial "
+"program would:"
+msgstr ""
+"На этот раз я решил позволить ей выполнить немного больше работы, чем "
+"обычная учебная программа:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2282
+msgid "It parses its command line for options;"
+msgstr "Она анализирует свою командную строку на наличие опций;"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2283
+msgid "It displays proper usage if it finds wrong arguments;"
+msgstr "Она отображает подсказку, если обнаруживает неверные аргументы;"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2284
+msgid "It produces meaningful error messages."
+msgstr "Она выдает понятные сообщения об ошибках."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2286
+msgid "Here is its usage message:"
+msgstr "Вот какое сообщение она выводит о том, как ее использовать:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2290
+#, no-wrap
+msgid "Usage: csv [-t<delim>] [-c<comma>] [-p] [-o <outfile>] [-i <infile>]\n"
+msgstr "Usage: csv [-t<delim>] [-c<comma>] [-p] [-o <outfile>] [-i <infile>]\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2293
+msgid "All parameters are optional, and can appear in any order."
+msgstr "Все параметры необязательны и могут располагаться в любом порядке."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2297
+msgid ""
+"The `-t` parameter declares what to replace the commas with. The `tab` is "
+"the default here. For example, `-t;` will replace all unquoted commas with "
+"semicolons."
+msgstr ""
+"Параметр `-t` указывает, на что заменить запятые. По умолчанию используется "
+"`tab`. Например, `-t;` заменит все незакавыченные запятые на точку с запятой."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2301
+msgid ""
+"I did not need the `-c` option, but it may come in handy in the future. It "
+"lets me declare that I want a character other than a comma replaced with "
+"something else. For example, `-c@` will replace all at signs (useful if you "
+"want to split a list of email addresses to their user names and domains)."
+msgstr ""
+"Мне не понадобилась опция `-c`, но в будущем она может пригодиться. Она "
+"позволяет указать, что я хочу заменить символ, отличный от запятой, на что-"
+"то другое. Например, `-c@` заменит все знаки @ (полезно, если нужно "
+"разделить список email-адресов на имена пользователей и домены)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2304
+msgid ""
+"The `-p` option preserves the first line, i.e., it does not delete it. By "
+"default, we delete the first line because in a CSV file it contains the "
+"field names rather than data."
+msgstr ""
+"Опция `-p` сохраняет первую строку, т.е. не удаляет её. По умолчанию мы "
+"удаляем первую строку, потому что в CSV-файле она содержит названия полей, а "
+"не данные."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2307
+msgid ""
+"The `-i` and `-o` options let me specify the input and the output files. "
+"Defaults are [.filename]#stdin# and [.filename]#stdout#, so this is a "
+"regular UNIX(R) filter."
+msgstr ""
+"Опции `-i` и `-o` позволяют указать входной и выходной файлы. По умолчанию "
+"используются [.filename]#stdin# и [.filename]#stdout#, как обычно работает "
+"стандартный фильтр UNIX(R)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2310
+msgid ""
+"I made sure that both `-i filename` and `-ifilename` are accepted. I also "
+"made sure that only one input and one output files may be specified."
+msgstr ""
+"Я убедился, что принимаются как `-i filename`, так и `-ifilename`. Также я "
+"убедился, что может быть указан только один входной и один выходной файл."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2312
+msgid "To get the 11th field of each record, I can now do:"
+msgstr "Чтобы получить 11-е поле каждой записи, теперь я могу сделать:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2316
+#, no-wrap
+msgid "% csv '-t;' data.csv | awk '-F;' '{print $11}'\n"
+msgstr "% csv '-t;' data.csv | awk '-F;' '{print $11}'\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2319
+msgid ""
+"The code stores the options (except for the file descriptors) in `EDX`: The "
+"comma in `DH`, the new separator in `DL`, and the flag for the `-p` option "
+"in the highest bit of `EDX`, so a check for its sign will give us a quick "
+"decision what to do."
+msgstr ""
+"Код сохраняет параметры (за исключением файловых дескрипторов) в `EDX`: "
+"запятая в `DH`, новый разделитель в `DL`, а флаг параметра `-p` в старшем "
+"бите `EDX`, поэтому проверка его знака даст нам быстрое решение о дальнейших "
+"действиях."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2321
+msgid "Here is the code:"
+msgstr "Вот код:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2335
+#, no-wrap
+msgid ""
+";;;;;;; csv.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";\n"
+"; Convert a comma-separated file to a something-else separated file.\n"
+";\n"
+"; Started:\t31-May-2001\n"
+"; Updated:\t 1-Jun-2001\n"
+";\n"
+"; Copyright (c) 2001 G. Adam Stanislav\n"
+"; All rights reserved.\n"
+";\n"
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+msgstr ""
+";;;;;;; csv.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";\n"
+"; Convert a comma-separated file to a something-else separated file.\n"
+";\n"
+"; Started:\t31-May-2001\n"
+"; Updated:\t 1-Jun-2001\n"
+";\n"
+"; Copyright (c) 2001 G. Adam Stanislav\n"
+"; All rights reserved.\n"
+";\n"
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2349
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"fd.in\tdd\tstdin\n"
+"fd.out\tdd\tstdout\n"
+"usg\tdb\t'Usage: csv [-t<delim>] [-c<comma>] [-p] [-o <outfile>] [-i <infile>]', 0Ah\n"
+"usglen\tequ\t$-usg\n"
+"iemsg\tdb\t\"csv: Can't open input file\", 0Ah\n"
+"iemlen\tequ\t$-iemsg\n"
+"oemsg\tdb\t\"csv: Can't create output file\", 0Ah\n"
+"oemlen\tequ\t$-oemsg\n"
+msgstr ""
+"section\t.data\n"
+"fd.in\tdd\tstdin\n"
+"fd.out\tdd\tstdout\n"
+"usg\tdb\t'Usage: csv [-t<delim>] [-c<comma>] [-p] [-o <outfile>] [-i <infile>]', 0Ah\n"
+"usglen\tequ\t$-usg\n"
+"iemsg\tdb\t\"csv: Can't open input file\", 0Ah\n"
+"iemlen\tequ\t$-iemsg\n"
+"oemsg\tdb\t\"csv: Can't create output file\", 0Ah\n"
+"oemlen\tequ\t$-oemsg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2363
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"align 4\n"
+"ierr:\n"
+"\tpush\tdword iemlen\n"
+"\tpush\tdword iemsg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 1\t\t; return failure\n"
+"\tsys.exit\n"
+msgstr ""
+"section\t.text\n"
+"align 4\n"
+"ierr:\n"
+"\tpush\tdword iemlen\n"
+"\tpush\tdword iemsg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 1\t\t; return failure\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2372
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3421
+#, no-wrap
+msgid ""
+"align 4\n"
+"oerr:\n"
+"\tpush\tdword oemlen\n"
+"\tpush\tdword oemsg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 2\n"
+"\tsys.exit\n"
+msgstr ""
+"align 4\n"
+"oerr:\n"
+"\tpush\tdword oemlen\n"
+"\tpush\tdword oemsg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 2\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2381
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3430
+#, no-wrap
+msgid ""
+"align 4\n"
+"usage:\n"
+"\tpush\tdword usglen\n"
+"\tpush\tdword usg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 3\n"
+"\tsys.exit\n"
+msgstr ""
+"align 4\n"
+"usage:\n"
+"\tpush\tdword usglen\n"
+"\tpush\tdword usg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 3\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2387
+#, no-wrap
+msgid ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
+"\tmov\tedx, (',' << 8) | 9\n"
+msgstr ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
+"\tmov\tedx, (',' << 8) | 9\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2392
+#, no-wrap
+msgid ""
+".arg:\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje\tnear .init\t\t; no more arguments\n"
+msgstr ""
+".arg:\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje\tnear .init\t\t; no more arguments\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2396
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3445
+#, no-wrap
+msgid ""
+"\t; ECX contains the pointer to an argument\n"
+"\tcmp\tbyte [ecx], '-'\n"
+"\tjne\tusage\n"
+msgstr ""
+"\t; ECX contains the pointer to an argument\n"
+"\tcmp\tbyte [ecx], '-'\n"
+"\tjne\tusage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2399
+#, no-wrap
+msgid ""
+"\tinc\tecx\n"
+"\tmov\tax, [ecx]\n"
+msgstr ""
+"\tinc\tecx\n"
+"\tmov\tax, [ecx]\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2403
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3453
+#, no-wrap
+msgid ""
+".o:\n"
+"\tcmp\tal, 'o'\n"
+"\tjne\t.i\n"
+msgstr ""
+".o:\n"
+"\tcmp\tal, 'o'\n"
+"\tjne\t.i\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2407
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3457
+#, no-wrap
+msgid ""
+"\t; Make sure we are not asked for the output file twice\n"
+"\tcmp\tdword [fd.out], stdout\n"
+"\tjne\tusage\n"
+msgstr ""
+"\t; Make sure we are not asked for the output file twice\n"
+"\tcmp\tdword [fd.out], stdout\n"
+"\tjne\tusage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2412
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3462
+#, no-wrap
+msgid ""
+"\t; Find the path to output file - it is either at [ECX+1],\n"
+"\t; i.e., -ofile --\n"
+"\t; or in the next argument,\n"
+"\t; i.e., -o file\n"
+msgstr ""
+"\t; Find the path to output file - it is either at [ECX+1],\n"
+"\t; i.e., -ofile --\n"
+"\t; or in the next argument,\n"
+"\t; i.e., -o file\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2418
+#, no-wrap
+msgid ""
+"\tinc\tecx\n"
+"\tor\tah, ah\n"
+"\tjne\t.openoutput\n"
+"\tpop\tecx\n"
+"\tjecxz\tusage\n"
+msgstr ""
+"\tinc\tecx\n"
+"\tor\tah, ah\n"
+"\tjne\t.openoutput\n"
+"\tpop\tecx\n"
+"\tjecxz\tusage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2426
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3475
+#, no-wrap
+msgid ""
+".openoutput:\n"
+"\tpush\tdword 420\t; file mode (644 octal)\n"
+"\tpush\tdword 0200h | 0400h | 01h\n"
+"\t; O_CREAT | O_TRUNC | O_WRONLY\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\tnear oerr\n"
+msgstr ""
+".openoutput:\n"
+"\tpush\tdword 420\t; file mode (644 octal)\n"
+"\tpush\tdword 0200h | 0400h | 01h\n"
+"\t; O_CREAT | O_TRUNC | O_WRONLY\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\tnear oerr\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2430
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3479
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 12\n"
+"\tmov\t[fd.out], eax\n"
+"\tjmp\tshort .arg\n"
+msgstr ""
+"\tadd\tesp, byte 12\n"
+"\tmov\t[fd.out], eax\n"
+"\tjmp\tshort .arg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2434
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3483
+#, no-wrap
+msgid ""
+".i:\n"
+"\tcmp\tal, 'i'\n"
+"\tjne\t.p\n"
+msgstr ""
+".i:\n"
+"\tcmp\tal, 'i'\n"
+"\tjne\t.p\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2438
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3487
+#, no-wrap
+msgid ""
+"\t; Make sure we are not asked twice\n"
+"\tcmp\tdword [fd.in], stdin\n"
+"\tjne\tnear usage\n"
+msgstr ""
+"\t; Make sure we are not asked twice\n"
+"\tcmp\tdword [fd.in], stdin\n"
+"\tjne\tnear usage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2446
+#, no-wrap
+msgid ""
+"\t; Find the path to the input file\n"
+"\tinc\tecx\n"
+"\tor\tah, ah\n"
+"\tjne\t.openinput\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje near usage\n"
+msgstr ""
+"\t; Find the path to the input file\n"
+"\tinc\tecx\n"
+"\tor\tah, ah\n"
+"\tjne\t.openinput\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje near usage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2452
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3500
+#, no-wrap
+msgid ""
+".openinput:\n"
+"\tpush\tdword 0\t\t; O_RDONLY\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\tnear ierr\t\t; open failed\n"
+msgstr ""
+".openinput:\n"
+"\tpush\tdword 0\t\t; O_RDONLY\n"
+"\tpush\tecx\n"
+"\tsys.open\n"
+"\tjc\tnear ierr\t\t; open failed\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2456
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3504
+#, no-wrap
+msgid ""
+"\tadd\tesp, byte 8\n"
+"\tmov\t[fd.in], eax\n"
+"\tjmp\t.arg\n"
+msgstr ""
+"\tadd\tesp, byte 8\n"
+"\tmov\t[fd.in], eax\n"
+"\tjmp\t.arg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2464
+#, no-wrap
+msgid ""
+".p:\n"
+"\tcmp\tal, 'p'\n"
+"\tjne\t.t\n"
+"\tor\tah, ah\n"
+"\tjne\tnear usage\n"
+"\tor\tedx, 1 << 31\n"
+"\tjmp\t.arg\n"
+msgstr ""
+".p:\n"
+"\tcmp\tal, 'p'\n"
+"\tjne\t.t\n"
+"\tor\tah, ah\n"
+"\tjne\tnear usage\n"
+"\tor\tedx, 1 << 31\n"
+"\tjmp\t.arg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2472
+#, no-wrap
+msgid ""
+".t:\n"
+"\tcmp\tal, 't'\t\t; redefine output delimiter\n"
+"\tjne\t.c\n"
+"\tor\tah, ah\n"
+"\tje\tnear usage\n"
+"\tmov\tdl, ah\n"
+"\tjmp\t.arg\n"
+msgstr ""
+".t:\n"
+"\tcmp\tal, 't'\t\t; redefine output delimiter\n"
+"\tjne\t.c\n"
+"\tor\tah, ah\n"
+"\tje\tnear usage\n"
+"\tmov\tdl, ah\n"
+"\tjmp\t.arg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2480
+#, no-wrap
+msgid ""
+".c:\n"
+"\tcmp\tal, 'c'\n"
+"\tjne\tnear usage\n"
+"\tor\tah, ah\n"
+"\tje\tnear usage\n"
+"\tmov\tdh, ah\n"
+"\tjmp\t.arg\n"
+msgstr ""
+".c:\n"
+"\tcmp\tal, 'c'\n"
+"\tjne\tnear usage\n"
+"\tor\tah, ah\n"
+"\tje\tnear usage\n"
+"\tmov\tdh, ah\n"
+"\tjmp\t.arg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2487
+#, no-wrap
+msgid ""
+"align 4\n"
+".init:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tmov\tedi, obuffer\n"
+msgstr ""
+"align 4\n"
+".init:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tmov\tedi, obuffer\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2491
+#, no-wrap
+msgid ""
+"\t; See if we are to preserve the first line\n"
+"\tor\tedx, edx\n"
+"\tjs\t.loop\n"
+msgstr ""
+"\t; See if we are to preserve the first line\n"
+"\tor\tedx, edx\n"
+"\tjs\t.loop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2497
+#, no-wrap
+msgid ""
+".firstline:\n"
+"\t; get rid of the first line\n"
+"\tcall\tgetchar\n"
+"\tcmp\tal, 0Ah\n"
+"\tjne\t.firstline\n"
+msgstr ""
+".firstline:\n"
+"\t; get rid of the first line\n"
+"\tcall\tgetchar\n"
+"\tcmp\tal, 0Ah\n"
+"\tjne\t.firstline\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2505
+#, no-wrap
+msgid ""
+"\t; is it a comma (or whatever the user asked for)?\n"
+"\tcmp\tal, dh\n"
+"\tjne\t.quote\n"
+msgstr ""
+"\t; is it a comma (or whatever the user asked for)?\n"
+"\tcmp\tal, dh\n"
+"\tjne\t.quote\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2508
+#, no-wrap
+msgid ""
+"\t; Replace the comma with a tab (or whatever the user wants)\n"
+"\tmov\tal, dl\n"
+msgstr ""
+"\t; Replace the comma with a tab (or whatever the user wants)\n"
+"\tmov\tal, dl\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2516
+#, no-wrap
+msgid ""
+".quote:\n"
+"\tcmp\tal, '\"'\n"
+"\tjne\t.put\n"
+msgstr ""
+".quote:\n"
+"\tcmp\tal, '\"'\n"
+"\tjne\t.put\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2523
+#, no-wrap
+msgid ""
+"\t; Print everything until you get another quote or EOL. If it\n"
+"\t; is a quote, skip it. If it is EOL, print it.\n"
+".qloop:\n"
+"\tcall\tgetchar\n"
+"\tcmp\tal, '\"'\n"
+"\tje\t.loop\n"
+msgstr ""
+"\t; Print everything until you get another quote or EOL. If it\n"
+"\t; is a quote, skip it. If it is EOL, print it.\n"
+".qloop:\n"
+"\tcall\tgetchar\n"
+"\tcmp\tal, '\"'\n"
+"\tje\t.loop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2526
+#, no-wrap
+msgid ""
+"\tcmp\tal, 0Ah\n"
+"\tje\t.put\n"
+msgstr ""
+"\tcmp\tal, 0Ah\n"
+"\tje\t.put\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2529
+#, no-wrap
+msgid ""
+"\tcall\tputchar\n"
+"\tjmp\tshort .qloop\n"
+msgstr ""
+"\tcall\tputchar\n"
+"\tjmp\tshort .qloop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2545
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3860
+#, no-wrap
+msgid ""
+"read:\n"
+"\tjecxz\t.read\n"
+"\tcall\twrite\n"
+msgstr ""
+"read:\n"
+"\tjecxz\t.read\n"
+"\tcall\twrite\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2558
+#, no-wrap
+msgid ""
+".read:\n"
+"\tpush\tdword BUFSIZE\n"
+"\tmov\tesi, ibuffer\n"
+"\tpush\tesi\n"
+"\tpush\tdword [fd.in]\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tmov\tebx, eax\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+msgstr ""
+".read:\n"
+"\tpush\tdword BUFSIZE\n"
+"\tmov\tesi, ibuffer\n"
+"\tpush\tesi\n"
+"\tpush\tdword [fd.in]\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tmov\tebx, eax\n"
+"\tor\teax, eax\n"
+"\tje\t.done\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2595
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3901
+#, no-wrap
+msgid ""
+"align 4\n"
+"write:\n"
+"\tjecxz\t.ret\t; nothing to write\n"
+"\tsub\tedi, ecx\t; start of buffer\n"
+"\tpush\tecx\n"
+"\tpush\tedi\n"
+"\tpush\tdword [fd.out]\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tsub\teax, eax\n"
+"\tsub\tecx, ecx\t; buffer is empty now\n"
+".ret:\n"
+"\tret\n"
+msgstr ""
+"align 4\n"
+"write:\n"
+"\tjecxz\t.ret\t; nothing to write\n"
+"\tsub\tedi, ecx\t; start of buffer\n"
+"\tpush\tecx\n"
+"\tpush\tedi\n"
+"\tpush\tdword [fd.out]\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tsub\teax, eax\n"
+"\tsub\tecx, ecx\t; buffer is empty now\n"
+".ret:\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2600
+msgid ""
+"Much of it is taken from [.filename]#hex.asm# above. But there is one "
+"important difference: I no longer call `write` whenever I am outputting a "
+"line feed. Yet, the code can be used interactively."
+msgstr ""
+"Большая часть взята из [.filename]#hex.asm# выше. Однако есть одно важное "
+"отличие: я больше не вызываю `write` каждый раз при выводе перевода строки. "
+"Тем не менее, код можно использовать интерактивно."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2604
+msgid ""
+"I have found a better solution for the interactive problem since I first "
+"started writing this chapter. I wanted to make sure each line is printed "
+"out separately only when needed. After all, there is no need to flush out "
+"every line when used non-interactively."
+msgstr ""
+"Я нашел лучшее решение для интерактивной проблемы с тех пор, как начал "
+"писать эту главу. Я хотел убедиться, что каждая строка выводится отдельно "
+"только при необходимости. В конце концов, нет необходимости выводить каждую "
+"строку при неинтерактивном использовании."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2608
+msgid ""
+"The new solution I use now is to call `write` every time I find the input "
+"buffer empty. That way, when running in the interactive mode, the program "
+"reads one line from the user's keyboard, processes it, and sees its input "
+"buffer is empty. It flushes its output and reads the next line."
+msgstr ""
+"Новое решение, которое я использую сейчас, заключается в вызове `write` "
+"каждый раз, когда обнаруживаю, что входной буфер пуст. Таким образом, при "
+"работе в интерактивном режиме программа считывает одну строку с клавиатуры "
+"пользователя, обрабатывает её и видит, что входной буфер пуст. Она "
+"сбрасывает свой вывод и читает следующую строку."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2610
+#, no-wrap
+msgid "The Dark Side of Buffering"
+msgstr "Темная сторона буферизации"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2614
+msgid ""
+"This change prevents a mysterious lockup in a very specific case. I refer "
+"to it as the _dark side of buffering_, mostly because it presents a danger "
+"that is not quite obvious."
+msgstr ""
+"Это изменение предотвращает загадочную блокировку в очень специфическом "
+"случае. Я называю это _тёмной стороной буферизации_, в основном потому, что "
+"это представляет опасность, которая не совсем очевидна."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2618
+msgid ""
+"It is unlikely to happen with a program like the csv above, so let us "
+"consider yet another filter: In this case we expect our input to be raw data "
+"representing color values, such as the _red_, _green_, and _blue_ "
+"intensities of a pixel. Our output will be the negative of our input."
+msgstr ""
+"Маловероятно, что это произойдет с такой программой, как csv выше, поэтому "
+"рассмотрим еще один фильтр: в этом случае мы ожидаем, что наши входные "
+"данные будут представлять собой необработанные данные, описывающие значения "
+"цветов, такие как интенсивности _красного_, _зеленого_ и _синего_ для "
+"пикселя. На выходе мы получим негатив входных данных."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2621
+msgid ""
+"Such a filter would be very simple to write. Most of it would look just "
+"like all the other filters we have written so far, so I am only going to "
+"show you its inner loop:"
+msgstr ""
+"Такой фильтр было бы очень просто написать. Большая его часть выглядела бы "
+"так же, как и все другие фильтры, которые мы уже писали, поэтому я покажу "
+"только его внутренний цикл:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2629
+#, no-wrap
+msgid ""
+".loop:\n"
+"\tcall\tgetchar\n"
+"\tnot\tal\t\t; Create a negative\n"
+"\tcall\tputchar\n"
+"\tjmp\tshort .loop\n"
+msgstr ""
+".loop:\n"
+"\tcall\tgetchar\n"
+"\tnot\tal\t\t; Create a negative\n"
+"\tcall\tputchar\n"
+"\tjmp\tshort .loop\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2632
+msgid ""
+"Because this filter works with raw data, it is unlikely to be used "
+"interactively."
+msgstr ""
+"Поскольку этот фильтр работает с необработанными данными, он вряд ли будет "
+"использоваться интерактивно."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2635
+msgid ""
+"But it could be called by image manipulation software. And, unless it calls "
+"`write` before each call to `read`, chances are it will lock up."
+msgstr ""
+"Но он может вызываться программным обеспечением для обработки изображений. "
+"И, если он не вызывает `write` перед каждым вызовом `read`, высока "
+"вероятность, что он зависнет."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2637
+msgid "Here is what might happen:"
+msgstr "Вот что может произойти:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2640
+msgid "The image editor will load our filter using the C function `popen()`."
+msgstr ""
+"Редактор изображений загрузит наш фильтр, используя функцию `popen()` на "
+"языке C."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2641
+msgid "It will read the first row of pixels from a bitmap or pixmap."
+msgstr ""
+"Он прочитает первый ряд пикселей из битовой карты или пиксельной карты."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2642
+msgid ""
+"It will write the first row of pixels to the _pipe_ leading to the `fd.in` "
+"of our filter."
+msgstr ""
+"Он запишет первую строку пикселей в _канал_, ведущий к `fd.in` нашего "
+"фильтра."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2643
+msgid ""
+"Our filter will read each pixel from its input, turn it to a negative, and "
+"write it to its output buffer."
+msgstr ""
+"Наш фильтр будет читать каждый пиксель из входных данных, преобразовывать "
+"его в негатив и записывать в выходной буфер."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2644
+msgid "Our filter will call `getchar` to fetch the next pixel."
+msgstr "Наш фильтр будет вызывать `getchar` для получения следующего пикселя."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2645
+msgid "`getchar` will find an empty input buffer, so it will call `read`."
+msgstr "`getchar` обнаружит пустой входной буфер, поэтому вызовет `read`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2646
+msgid "`read` will call the `SYS_read` system call."
+msgstr "`read` вызовет системный вызов `SYS_read`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2647
+msgid ""
+"The _kernel_ will suspend our filter until the image editor sends more data "
+"to the pipe."
+msgstr ""
+"_Ядро_ приостановит работу нашего фильтра до тех пор, пока редактор "
+"изображений не отправит больше данных в канал."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2648
+msgid ""
+"The image editor will read from the other pipe, connected to the `fd.out` of "
+"our filter so it can set the first row of the output image _before_ it sends "
+"us the second row of the input."
+msgstr ""
+"Редактор изображений будет читать из другого канала, подключенного к `fd."
+"out` нашего фильтра, чтобы он мог установить первую строку выходного "
+"изображения _до_ того, как отправит нам вторую строку входного."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2649
+msgid ""
+"The _kernel_ suspends the image editor until it receives some output from "
+"our filter, so it can pass it on to the image editor."
+msgstr ""
+"_Ядро_ приостанавливает работу графического редактора до тех пор, пока не "
+"получит какие-либо данные от нашего фильтра, чтобы передать их редактору."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2653
+msgid ""
+"At this point our filter waits for the image editor to send it more data to "
+"process, while the image editor is waiting for our filter to send it the "
+"result of the processing of the first row. But the result sits in our "
+"output buffer."
+msgstr ""
+"На этом этапе наш фильтр ожидает, что редактор изображений отправит ему "
+"больше данных для обработки, в то время как редактор изображений ожидает, "
+"что наш фильтр отправит ему результат обработки первой строки. Однако "
+"результат находится в нашем выходном буфере."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2656
+msgid ""
+"The filter and the image editor will continue waiting for each other forever "
+"(or, at least, until they are killed). Our software has just entered a "
+"crossref:secure[secure-race-conditions,race condition]."
+msgstr ""
+"Фильтр и редактор изображений будут продолжать ждать друг друга вечно (или, "
+"по крайней мере, пока их не завершат командой kill). Наше программное "
+"обеспечение только что вошло в crossref:secure[secure-race-conditions,"
+"состояние гонки]."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2658
+msgid ""
+"This problem does not exist if our filter flushes its output buffer _before_ "
+"asking the _kernel_ for more input data."
+msgstr ""
+"Эта проблема не возникает, если наш фильтр очищает свой выходной буфер "
+"_перед_ запросом к _ядру_ для получения дополнительных входных данных."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2660
+#, no-wrap
+msgid "Using the FPU"
+msgstr "Использование FPU"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2663
+msgid ""
+"Strangely enough, most of assembly language literature does not even mention "
+"the existence of the FPU, or _floating point unit_, let alone discuss "
+"programming it."
+msgstr ""
+"Как ни странно, большая часть литературы по ассемблеру даже не упоминает о "
+"существовании FPU, или _блока обработки чисел с плавающей запятой_, не "
+"говоря уже о программировании для него."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2665
+msgid ""
+"Yet, never does assembly language shine more than when we create highly "
+"optimized FPU code by doing things that can be done _only_ in assembly "
+"language."
+msgstr ""
+"Тем не менее, язык ассемблера проявляет себя наилучшим образом, когда мы "
+"создаем высокооптимизированный код для FPU, выполняя вещи, которые можно "
+"сделать _только_ на языке ассемблера."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2667
+#, no-wrap
+msgid "Organization of the FPU"
+msgstr "Организация FPU"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2671
+msgid ""
+"The FPU consists of 8 80-bit floating-point registers. These are organized "
+"in a stack fashion-you can `push` a value on TOS (_top of stack_) and you "
+"can `pop` it."
+msgstr ""
+"FPU состоит из 8 80-битных регистров с плавающей запятой. Они организованы в "
+"виде стека — вы можете `push` (поместить) значение на TOS (_вершина стека_) "
+"и `pop` (извлечь) его."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2673
+msgid ""
+"That said, the assembly language op codes are not `push` and `pop` because "
+"those are already taken."
+msgstr ""
+"Как бы то ни было, мнемоники ассемблера — не `push` и `pop`, потому что они "
+"уже заняты."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2676
+msgid ""
+"You can `push` a value on TOS by using `fld`, `fild`, and `fbld`. Several "
+"other op codes let you `push` many common _constants_-such as _pi_-on the "
+"TOS."
+msgstr ""
+"Вы можете `push` (положить) значение на вершину стека (TOS), используя "
+"`fld`, `fild` и `fbld`. Несколько других кодов операций позволяют вам `push` "
+"(положить) многие распространённые _константы_ — например, _pi_ — на вершину "
+"стека (TOS)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2679
+msgid ""
+"Similarly, you can `pop` a value by using `fst`, `fstp`, `fist`, `fistp`, "
+"and `fbstp`. Actually, only the op codes that end with a _p_ will literally "
+"`pop` the value, the rest will `store` it somewhere else without removing it "
+"from the TOS."
+msgstr ""
+"Аналогично, вы можете `извлечь` значение с помощью `fst`, `fstp`, `fist`, "
+"`fistp` и `fbstp`. На самом деле только коды операций, оканчивающиеся на "
+"_p_, буквально `извлекают` значение, остальные же `сохраняют` его в другом "
+"месте, не удаляя с вершины стека (TOS)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2681
+msgid ""
+"We can transfer the data between the TOS and the computer memory either as a "
+"32-bit, 64-bit, or 80-bit _real_, a 16-bit, 32-bit, or 64-bit _integer_, or "
+"an 80-bit _packed decimal_."
+msgstr ""
+"Мы можем передавать данные между TOS и памятью компьютера либо как 32-"
+"битное, 64-битное или 80-битное _вещественное_ число, 16-битное, 32-битное "
+"или 64-битное _целое_ число, либо как 80-битное _упакованное десятичное_ "
+"число."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2684
+msgid ""
+"The 80-bit _packed decimal_ is a special case of _binary coded decimal_ "
+"which is very convenient when converting between the ASCII representation of "
+"data and the internal data of the FPU. It allows us to use 18 significant "
+"digits."
+msgstr ""
+"80-битный _упакованный десятичный_ формат является особым случаем _двоично-"
+"десятичного кодирования_, который очень удобен при преобразовании между "
+"ASCII-представлением данных и внутренними данными FPU. Он позволяет "
+"использовать до 18 значащих цифр."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2686
+msgid ""
+"No matter how we represent data in the memory, the FPU always stores it in "
+"the 80-bit _real_ format in its registers."
+msgstr ""
+"Независимо от того, как мы представляем данные в памяти, FPU всегда хранит "
+"их в 80-битном формате _real_ в своих регистрах."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2688
+msgid ""
+"Its internal precision is at least 19 decimal digits, so even if we choose "
+"to display results as ASCII in the full 18-digit precision, we are still "
+"showing correct results."
+msgstr ""
+"Его внутренняя точность составляет не менее 19 десятичных цифр, поэтому даже "
+"если мы решим отображать результаты в формате ASCII с полной 18-значной "
+"точностью, мы всё равно будем показывать корректные результаты."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2690
+msgid ""
+"We can perform mathematical operations on the TOS: We can calculate its "
+"_sine_, we can _scale_ it (i.e., we can multiply or divide it by a power of "
+"2), we can calculate its base-2 _logarithm_, and many other things."
+msgstr ""
+"Мы можем выполнять математические операции над TOS: вычислять его _синус_, "
+"_масштабировать_ (то есть умножать или делить на степень двойки), вычислять "
+"его _логарифм_ по основанию 2 и многое другое."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2692
+msgid ""
+"We can also _multiply_ or _divide_ it by, _add_ it to, or _subtract_ it "
+"from, any of the FPU registers (including itself)."
+msgstr ""
+"Мы также можем _умножить_ или _разделить_ его, _прибавить_ к нему или "
+"_вычесть_ его из любого из регистров FPU (включая его самого)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2695
+msgid ""
+"The official Intel op code for the TOS is `st`, and for the _registers_ "
+"`st(0)`-`st(7)`. `st` and `st(0)`, then, refer to the same register."
+msgstr ""
+"Официальный код операции Intel для TOS — `st`, а для _регистров_ — `st(0)`-"
+"`st(7)`. Таким образом, `st` и `st(0)` ссылаются на один и тот же регистр."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2698
+msgid ""
+"For whatever reasons, the original author of nasm has decided to use "
+"different op codes, namely `st0`-`st7`. In other words, there are no "
+"parentheses, and the TOS is always `st0`, never just `st`."
+msgstr ""
+"По каким-то причинам оригинальный автор nasm решил использовать другие коды "
+"операций, а именно `st0`-`st7`. Другими словами, скобки отсутствуют, а "
+"вершина стека всегда `st0`, но никогда просто `st`."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2700
+#, no-wrap
+msgid "The Packed Decimal Format"
+msgstr "Формат упакованного десятичного числа"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2704
+msgid ""
+"The _packed decimal_ format uses 10 bytes (80 bits) of memory to represent "
+"18 digits. The number represented there is always an _integer_."
+msgstr ""
+"Формат _упакованного десятичного числа_ использует 10 байт (80 бит) памяти "
+"для представления 18 цифр. Представленное число всегда является _целым_."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2708
+msgid ""
+"You can use it to get decimal places by multiplying the TOS by a power of 10 "
+"first."
+msgstr ""
+"Вы можете использовать это для получения десятичных знаков, предварительно "
+"умножив TOS на степень 10."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2712
+msgid ""
+"The highest bit of the highest byte (byte 9) is the _sign bit_: If it is "
+"set, the number is _negative_, otherwise, it is _positive_. The rest of the "
+"bits of this byte are unused/ignored."
+msgstr ""
+"Старший бит старшего байта (байт 9) является _знаковым битом_: если он "
+"установлен, число _отрицательное_, в противном случае — _положительное_. "
+"Остальные биты этого байта не используются/игнорируются."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2714
+msgid ""
+"The remaining 9 bytes store the 18 digits of the number: 2 digits per byte."
+msgstr "Оставшиеся 9 байт хранят 18 цифр числа: 2 цифры на байт."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2716
+msgid ""
+"The _more significant digit_ is stored in the high _nibble_ (4 bits), the "
+"_less significant digit_ in the low _nibble_."
+msgstr ""
+"_Старший разряд_ хранится в старшем _полубайте_ (4 бита), _младший разряд_ — "
+"в младшем _полубайте_."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2718
+msgid ""
+"That said, you might think that `-1234567` would be stored in the memory "
+"like this (using hexadecimal notation):"
+msgstr ""
+"Как бы то ни было, вы можете подумать, что `-1234567` будет храниться в "
+"памяти следующим образом (в шестнадцатеричной записи):"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2722
+#, no-wrap
+msgid "80 00 00 00 00 00 01 23 45 67\n"
+msgstr "80 00 00 00 00 00 01 23 45 67\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2725
+msgid ""
+"Alas it is not! As with everything else of Intel make, even the _packed "
+"decimal_ is _little-endian_."
+msgstr ""
+"Увы, это не так! Как и все остальное, созданное Intel, даже _упакованное "
+"десятичное число_ имеет порядок _от младшего к старшему_."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2727
+msgid "That means our `-1234567` is stored like this:"
+msgstr "Это означает, что наш `-1234567` хранится следующим образом:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2731
+#, no-wrap
+msgid "67 45 23 01 00 00 00 00 00 80\n"
+msgstr "67 45 23 01 00 00 00 00 00 80\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2734
+msgid "Remember that, or you will be pulling your hair out in desperation!"
+msgstr "Помните об этом, иначе вы будете рвать на себе волосы в отчаянии!"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2740
+msgid ""
+"The book to read-if you can find it-is Richard Startz' http://www.amazon.com/"
+"exec/obidos/ASIN/013246604X/whizkidtechnomag[8087/80287/80387 for the IBM PC "
+"& Compatibles]. Though it does seem to take the fact about the little-"
+"endian storage of the _packed decimal_ for granted. I kid you not about the "
+"desperation of trying to figure out what was wrong with the filter I show "
+"below _before_ it occurred to me I should try the little-endian order even "
+"for this type of data."
+msgstr ""
+"Книга, которую стоит прочитать — если сможете её найти — это книга Ричарда "
+"Старца http://www.amazon.com/exec/obidos/ASIN/013246604X/"
+"whizkidtechnomag[8087/80287/80387 для IBM PC и совместимых]. Хотя в ней, "
+"кажется, факт о little-endian хранении _упакованного десятичного числа_ "
+"принимается как данность. Я не шучу насчёт отчаяния, которое испытывал, "
+"пытаясь понять, что не так с фильтром, который я привожу ниже, _прежде_ чем "
+"мне пришло в голову попробовать little-endian порядок даже для этого типа "
+"данных."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2743
+#, no-wrap
+msgid "Excursion to Pinhole Photography"
+msgstr "Экскурсия в фотографию с помощью камеры-обскуры"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2746
+msgid ""
+"To write meaningful software, we must not only understand our programming "
+"tools, but also the field we are creating software for."
+msgstr ""
+"Чтобы создавать полезное программное обеспечение, мы должны понимать не "
+"только наши инструменты программирования, но и область, для которой "
+"разрабатываем ПО."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2748
+msgid ""
+"Our next filter will help us whenever we want to build a _pinhole camera_, "
+"so, we need some background in _pinhole photography_ before we can continue."
+msgstr ""
+"Наш следующий фильтр поможет нам, когда мы захотим создать _камеру-обскуру_, "
+"поэтому нам понадобятся некоторые знания о _фотографии с помощью обскуры_, "
+"прежде чем мы сможем продолжить."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2750
+#, no-wrap
+msgid "The Camera"
+msgstr "Камера"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2753
+msgid ""
+"The easiest way to describe any camera ever built is as some empty space "
+"enclosed in some lightproof material, with a small hole in the enclosure."
+msgstr ""
+"Самый простой способ описать любую когда-либо созданную камеру — это "
+"некоторое пустое пространство, заключённое в светонепроницаемый материал, с "
+"небольшим отверстием в корпусе."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2758
+msgid ""
+"The enclosure is usually sturdy (e.g., a box), though sometimes it is "
+"flexible (the bellows). It is quite dark inside the camera. However, the "
+"hole lets light rays in through a single point (though in some cases there "
+"may be several). These light rays form an image, a representation of "
+"whatever is outside the camera, in front of the hole."
+msgstr ""
+"Корпус обычно прочный (например, коробка), хотя иногда он гибкий "
+"(гофрированная часть). Внутри камеры довольно темно. Однако отверстие "
+"пропускает световые лучи через одну точку (хотя в некоторых случаях их может "
+"быть несколько). Эти световые лучи формируют изображение — представление "
+"того, что находится снаружи камеры, перед отверстием."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2760
+msgid ""
+"If some light sensitive material (such as film) is placed inside the camera, "
+"it can capture the image."
+msgstr ""
+"Если внутрь камеры поместить светочувствительный материал (например, "
+"плёнку), он может зафиксировать изображение."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2762
+msgid ""
+"The hole often contains a _lens_, or a lens assembly, often called the "
+"_objective_."
+msgstr ""
+"Отверстие часто содержит _линзу_ или сборку линз, которую часто называют "
+"_объективом_."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2764
+#, no-wrap
+msgid "The Pinhole"
+msgstr "Игольное ушко"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2768
+msgid ""
+"But, strictly speaking, the lens is not necessary: The original cameras did "
+"not use a lens but a _pinhole_. Even today, _pinholes_ are used, both as a "
+"tool to study how cameras work, and to achieve a special kind of image."
+msgstr ""
+"Но, строго говоря, линза не обязательна: первые камеры использовали не "
+"линзу, а _маленькое отверстие_ размером с игольное ушко. Даже сегодня "
+"_маленькие отверстия_ применяются как инструмент для изучения принципов "
+"работы камер и для создания особого вида изображений."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2772
+msgid ""
+"The image produced by the _pinhole_ is all equally sharp. Or _blurred_. "
+"There is an ideal size for a pinhole: If it is either larger or smaller, the "
+"image loses its sharpness."
+msgstr ""
+"Изображение, создаваемое _маленьким отверстием_, одинаково резкое. Или "
+"_размытое_. Существует идеальный размер для маленького отверстия: если оно "
+"больше или меньше, изображение теряет резкость."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2774
+#, no-wrap
+msgid "Focal Length"
+msgstr "Фокусное расстояние"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2777
+msgid ""
+"This ideal pinhole diameter is a function of the square root of _focal "
+"length_, which is the distance of the pinhole from the film."
+msgstr ""
+"Идеальный диаметр отверстия является функцией квадратного корня из "
+"_фокусного расстояния_, которое представляет собой расстояние от отверстия "
+"до плёнки."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2781
+#, no-wrap
+msgid "D = PC * sqrt(FL)\n"
+msgstr "D = PC * sqrt(FL)\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2787
+msgid ""
+"In here, `D` is the ideal diameter of the pinhole, `FL` is the focal length, "
+"and `PC` is a pinhole constant. According to Jay Bender, its value is "
+"`0.04`, while Kenneth Connors has determined it to be `0.037`. Others have "
+"proposed other values. Plus, this value is for the daylight only: Other "
+"types of light will require a different constant, whose value can only be "
+"determined by experimentation."
+msgstr ""
+"Здесь `D` — идеальный диаметр отверстия, `FL` — фокусное расстояние, а `PC` "
+"— константа отверстия. По данным Джейя Бендера, её значение равно `0,04`, "
+"тогда как Кеннет Коннорс определил его как `0,037`. Другие исследователи "
+"предложили иные значения. Кроме того, это значение справедливо только для "
+"дневного света: другие типы освещения потребуют иной константы, значение "
+"которой можно определить только экспериментальным путём."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2789
+#, no-wrap
+msgid "The F-Number"
+msgstr "Число f (диафрагменное число)"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2793
+msgid ""
+"The f-number is a very useful measure of how much light reaches the film. A "
+"light meter can determine that, for example, to expose a film of specific "
+"sensitivity with f/5.6 may require the exposure to last 1/1000 sec."
+msgstr ""
+"Число f — это очень полезный показатель того, сколько света попадает на "
+"плёнку. Экспонометр может определить, что, например, для экспонирования "
+"плёнки определённой чувствительности при f/5.6 может потребоваться выдержка "
+"1/1000 сек."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2796
+msgid ""
+"It does not matter whether it is a 35-mm camera, or a 6x9cm camera, etc. As "
+"long as we know the f-number, we can determine the proper exposure."
+msgstr ""
+"Не имеет значения, 35-мм это камера или камера 6x9 см и т.д. Достаточно "
+"знать диафрагменное число, чтобы определить правильную экспозицию."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2798
+msgid "The f-number is easy to calculate:"
+msgstr "Число f легко вычислить:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2802
+#, no-wrap
+msgid "F = FL / D\n"
+msgstr "F = FL / D\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2807
+msgid ""
+"In other words, the f-number equals the focal length divided by the diameter "
+"of the pinhole. It also means a higher f-number either implies a smaller "
+"pinhole or a larger focal distance, or both. That, in turn, implies, the "
+"higher the f-number, the longer the exposure has to be."
+msgstr ""
+"Другими словами, число f равно фокусному расстоянию, деленному на диаметр "
+"отверстия. Это также означает, что большее f-число подразумевает либо "
+"меньшее отверстие, либо большее фокусное расстояние, либо и то, и другое. В "
+"свою очередь, это означает, что чем больше число f, тем дольше должна быть "
+"выдержка."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2810
+msgid ""
+"Furthermore, while pinhole diameter and focal distance are one-dimensional "
+"measurements, both, the film and the pinhole, are two-dimensional. That "
+"means that if you have measured the exposure at f-number `A` as `t`, then "
+"the exposure at f-number `B` is:"
+msgstr ""
+"Кроме того, хотя диаметр отверстия и фокусное расстояние являются "
+"одномерными величинами, и плёнка, и отверстие — двумерны. Это означает, что "
+"если вы измерили экспозицию при диафрагменном числе `A` как `t`, то "
+"экспозиция при диафрагменном числе `B` будет:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2814
+#, no-wrap
+msgid "t * (B / A)²\n"
+msgstr "t * (B / A)²\n"
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2817
+#, no-wrap
+msgid "Normalized F-Number"
+msgstr "Нормализованное число f"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2820
+msgid ""
+"While many modern cameras can change the diameter of their pinhole, and thus "
+"their f-number, quite smoothly and gradually, such was not always the case."
+msgstr ""
+"Хотя многие современные камеры могут изменять диаметр своего отверстия, а "
+"следовательно и свое число f, довольно плавно и постепенно, так было не "
+"всегда."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2822
+msgid ""
+"To allow for different f-numbers, cameras typically contained a metal plate "
+"with several holes of different sizes drilled to them."
+msgstr ""
+"Для обеспечения различных значений диафрагмы в камерах обычно использовалась "
+"металлическая пластина с несколькими отверстиями разного размера."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2825
+msgid ""
+"Their sizes were chosen according to the above formula in such a way that "
+"the resultant f-number was one of standard f-numbers used on all cameras "
+"everywhere. For example, a very old Kodak Duaflex IV camera in my "
+"possession has three such holes for f-numbers 8, 11, and 16."
+msgstr ""
+"Их размеры были выбраны в соответствии с приведённой выше формулой таким "
+"образом, чтобы результирующее f-число было одним из стандартных f-чисел, "
+"используемых на всех фотоаппаратах. Например, у моего очень старого "
+"фотоаппарата Kodak Duaflex IV есть три таких отверстия для чисел f — 8, 11 и "
+"16."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2828
+msgid ""
+"A more recently made camera may offer f-numbers of 2.8, 4, 5.6, 8, 11, 16, "
+"22, and 32 (as well as others). These numbers were not chosen arbitrarily: "
+"They all are powers of the square root of 2, though they may be rounded "
+"somewha."
+msgstr ""
+"Более современные камеры могут предлагать значения диафрагменного числа 2.8, "
+"4, 5.6, 8, 11, 16, 22 и 32 (а также другие). Эти числа выбраны не "
+"произвольно: все они являются степенями квадратного корня из 2, хотя могут "
+"быть немного округлены."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2830
+#, no-wrap
+msgid "The F-Stop"
+msgstr "Ступени числа f"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2834
+msgid ""
+"A typical camera is designed in such a way that setting any of the "
+"normalized f-numbers changes the feel of the dial. It will naturally _stop_ "
+"in that position. Because of that, these positions of the dial are called f-"
+"stops."
+msgstr ""
+"Типичная камера устроена так, что установка любого из нормализованных чисел "
+"f изменяет ощущение от регулятора. Он естественным образом _останавливается_ "
+"в этом положении. Из-за этого такие положения регулятора называются f-"
+"ступенями."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2838
+msgid ""
+"Since the f-numbers at each stop are powers of the square root of 2, moving "
+"the dial by 1 stop will double the amount of light required for proper "
+"exposure. Moving it by 2 stops will quadruple the required exposure. "
+"Moving the dial by 3 stops will require the increase in exposure 8 times, "
+"etc."
+msgstr ""
+"Поскольку значения диафрагмы на каждой ступени являются степенями "
+"квадратного корня из 2, поворот диска на 1 ступень удваивает количество "
+"света, необходимое для правильной экспозиции. Поворот на 2 ступени "
+"увеличивает требуемую экспозицию вчетверо. Поворот диска на 3 ступени "
+"требует увеличения экспозиции в 8 раз и так далее."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2840
+#, no-wrap
+msgid "Designing the Pinhole Software"
+msgstr "Проектирование программного обеспечения камеры-обскуры"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2843
+msgid ""
+"We are now ready to decide what exactly we want our pinhole software to do."
+msgstr ""
+"Мы готовы решить, что именно должно делать наше программное обеспечение для "
+"камер-обскур."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2845
+#, no-wrap
+msgid "Processing Program Input"
+msgstr "Обработка ввода программы"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2849
+msgid ""
+"Since its main purpose is to help us design a working pinhole camera, we "
+"will use the _focal length_ as the input to the program. This is something "
+"we can determine without software: Proper focal length is determined by the "
+"size of the film and by the need to shoot \"regular\" pictures, wide angle "
+"pictures, or telephoto pictures."
+msgstr ""
+"Поскольку основная цель — помочь нам разработать работающую камеру-обскуру, "
+"мы будем использовать _фокусное расстояние_ в качестве входных данных для "
+"программы. Это можно определить без программного обеспечения: правильное "
+"фокусное расстояние зависит от размера плёнки и необходимости съёмки "
+"«обычных» изображений, широкоугольных или телефото."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2851
+msgid ""
+"Most of the programs we have written so far worked with individual "
+"characters, or bytes, as their input: The hex program converted individual "
+"bytes into a hexadecimal number, the csv program either let a character "
+"through, or deleted it, or changed it to a different character, etc."
+msgstr ""
+"Большинство написанных нами до сих пор программ работали с отдельными "
+"символами или байтами в качестве входных данных: программа hex "
+"преобразовывала отдельные байты в шестнадцатеричное число, программа csv "
+"либо пропускала символ, либо удаляла его, либо заменяла на другой символ и т."
+"д."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2853
+msgid ""
+"One program, ftuc used the state machine to consider at most two input bytes "
+"at a time."
+msgstr ""
+"Одна программа, `ftuc`, использовала конечный автомат для обработки не более "
+"двух входных байтов за раз."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2855
+msgid ""
+"But our pinhole program cannot just work with individual characters, it has "
+"to deal with larger syntactic units."
+msgstr ""
+"Но наша программа для камеры-обскуры не может работать только с отдельными "
+"символами, ей приходится иметь дело с более крупными синтаксическими "
+"единицами."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2857
+msgid ""
+"For example, if we want the program to calculate the pinhole diameter (and "
+"other values we will discuss later) at the focal lengths of `100 mm`, `150 "
+"mm`, and `210 mm`, we may want to enter something like this:"
+msgstr ""
+"Например, если мы хотим, чтобы программа рассчитала диаметр отверстия (и "
+"другие значения, которые мы обсудим позже) для фокусных расстояний `100 мм`, "
+"`150 мм` и `210 мм`, мы можем ввести что-то вроде этого:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2861
+#, no-wrap
+msgid " 100, 150, 210\n"
+msgstr " 100, 150, 210\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2866
+msgid ""
+"Our program needs to consider more than a single byte of input at a time. "
+"When it sees the first `1`, it must understand it is seeing the first digit "
+"of a decimal number. When it sees the `0` and the other `0`, it must know "
+"it is seeing more digits of the same number."
+msgstr ""
+"Наша программа должна учитывать более одного байта входных данных за раз. "
+"Когда она видит первую `1`, она должна понимать, что это первая цифра "
+"десятичного числа. Когда она видит `0` и другой `0`, она должна знать, что "
+"это следующие цифры того же числа."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2871
+msgid ""
+"When it encounters the first comma, it must know it is no longer receiving "
+"the digits of the first number. It must be able to convert the digits of "
+"the first number into the value of `100`. And the digits of the second "
+"number into the value of `150`. And, of course, the digits of the third "
+"number into the numeric value of `210`."
+msgstr ""
+"Когда он встречает первую запятую, он должен понять, что больше не получает "
+"цифры первого числа. Он должен уметь преобразовать цифры первого числа в "
+"значение `100`. И цифры второго числа в значение `150`. И, конечно же, цифры "
+"третьего числа в числовое значение `210`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2873
+msgid ""
+"We need to decide what delimiters to accept: Do the input numbers have to be "
+"separated by a comma? If so, how do we treat two numbers separated by "
+"something else?"
+msgstr ""
+"Нам нужно определиться с допустимыми разделителями: должны ли входные числа "
+"разделяться запятой? Если да, то как обрабатывать два числа, разделённые чем-"
+"то другим?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2878
+msgid ""
+"Personally, I like to keep it simple. Something either is a number, so I "
+"process it. Or it is not a number, so I discard it. I do not like the "
+"computer complaining about me typing in an extra character when it is "
+"_obvious_ that it is an extra character. Duh!"
+msgstr ""
+"Лично я предпочитаю простоту. Либо что-то является числом — и тогда я его "
+"обрабатываю. Либо не является числом — и тогда я это отбрасываю. Мне не "
+"нравится, когда компьютер жалуется на лишний символ, если _очевидно_, что он "
+"лишний. Да ладно!"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2880
+msgid ""
+"Plus, it allows me to break up the monotony of computing and type in a query "
+"instead of just a number:"
+msgstr ""
+"Плюс, это позволяет мне разбавить монотонность вычислений и ввести запрос "
+"вместо просто числа:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2885
+#, no-wrap
+msgid ""
+"What is the best pinhole diameter for the\n"
+"\t focal length of 150?\n"
+msgstr ""
+"What is the best pinhole diameter for the\n"
+"\t focal length of 150?\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2888
+msgid "There is no reason for the computer to spit out a number of complaints:"
+msgstr "Нет причины, чтобы компьютер выводил множество жалоб:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2895
+#, no-wrap
+msgid ""
+"Syntax error: What\n"
+"Syntax error: is\n"
+"Syntax error: the\n"
+"Syntax error: best\n"
+msgstr ""
+"Syntax error: What\n"
+"Syntax error: is\n"
+"Syntax error: the\n"
+"Syntax error: best\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2898
+msgid "Et cetera, et cetera, et cetera."
+msgstr "И так далее, и так далее, и так далее."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2901
+msgid ""
+"Secondly, I like the `+#+` character to denote the start of a comment which "
+"extends to the end of the line. This does not take too much effort to code, "
+"and lets me treat input files for my software as executable scripts."
+msgstr ""
+"Во-вторых, мне нравится символ `+#+` для обозначения начала комментария, "
+"который продолжается до конца строки. Это не требует больших усилий для "
+"реализации и позволяет мне рассматривать входные файлы для моего "
+"программного обеспечения как исполняемые скрипты."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2903
+msgid ""
+"In our case, we also need to decide what units the input should come in: We "
+"choose _millimeters_ because that is how most photographers measure the "
+"focus length."
+msgstr ""
+"В нашем случае также необходимо определиться с единицами измерения входных "
+"данных: мы выбираем _миллиметры_, так как большинство фотографов измеряют "
+"фокусное расстояние именно в них."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2905
+msgid ""
+"Finally, we need to decide whether to allow the use of the decimal point (in "
+"which case we must also consider the fact that much of the world uses a "
+"decimal _comma_)."
+msgstr ""
+"Наконец, нам нужно решить, разрешать ли использование десятичной точки (в "
+"этом случае мы также должны учитывать тот факт, что во многих странах "
+"используется десятичная _запятая_)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2909
+msgid ""
+"In our case allowing for the decimal point/comma would offer a false sense "
+"of precision: There is little if any noticeable difference between the focus "
+"lengths of `50` and `51`, so allowing the user to input something like "
+"`50.5` is not a good idea. This is my opinion, mind you, but I am the one "
+"writing this program. You can make other choices in yours, of course."
+msgstr ""
+"В нашем случае разрешение десятичной точки/запятой создало бы ложное "
+"ощущение точности: разница между фокусными расстояниями `50` и `51` "
+"практически незаметна, поэтому разрешать пользователю вводить что-то вроде "
+"`50.5` — не лучшая идея. Это моё мнение, конечно, но программу пишу я. В "
+"своей программе вы можете сделать другие выбор, разумеется."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2911
+#, no-wrap
+msgid "Offering Options"
+msgstr "Передача параметров программе"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2916
+msgid ""
+"The most important thing we need to know when building a pinhole camera is "
+"the diameter of the pinhole. Since we want to shoot sharp images, we will "
+"use the above formula to calculate the pinhole diameter from focal length. "
+"As experts are offering several different values for the `PC` constant, we "
+"will need to have the choice."
+msgstr ""
+"Самое важное, что нам нужно знать при создании камеры-обскуры — это диаметр "
+"отверстия. Поскольку мы хотим получать чёткие изображения, мы будем "
+"использовать приведённую выше формулу для расчёта диаметра отверстия от "
+"фокусного расстояния. Поскольку эксперты предлагают несколько различных "
+"значений для константы `PC`, нам нужно будет иметь выбор."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2918
+msgid ""
+"It is traditional in UNIX(R) programming to have two main ways of choosing "
+"program parameters, plus to have a default for the time the user does not "
+"make a choice."
+msgstr ""
+"В традициях программирования в UNIX(R) предусмотрены два основных способа "
+"выбора параметров программы, а также значение по умолчанию на случай, если "
+"пользователь не сделает выбор."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2920
+msgid "Why have two ways of choosing?"
+msgstr "Почему есть два способа выбора?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2922
+msgid ""
+"One is to allow a (relatively) _permanent_ choice that applies automatically "
+"each time the software is run without us having to tell it over and over "
+"what we want it to do."
+msgstr ""
+"Один из способов — это позволить (относительно) _постоянный_ выбор, который "
+"применяется автоматически каждый раз при запуске программы, без "
+"необходимости каждый раз указывать, что мы хотим, чтобы она сделала."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2927
+msgid ""
+"The permanent choices may be stored in a configuration file, typically found "
+"in the user's home directory. The file usually has the same name as the "
+"application but is started with a dot. Often _\"rc\"_ is added to the file "
+"name. So, ours could be [.filename]#~/.pinhole# or [.filename]#~/."
+"pinholerc#. (The [.filename]#~/# means current user's home directory.)"
+msgstr ""
+"Постоянные настройки могут быть сохранены в конфигурационном файле, обычно "
+"расположенном в домашнем каталоге пользователя. Файл обычно имеет то же имя, "
+"что и приложение, но начинается с точки. Часто к имени файла добавляется _"
+"\"rc\"_. Таким образом, наш файл может называться [.filename]#~/.pinhole# "
+"или [.filename]#~/.pinholerc#. (Обозначение [.filename]#~/# означает "
+"домашний каталог текущего пользователя.)"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2932
+msgid ""
+"The configuration file is used mostly by programs that have many "
+"configurable parameters. Those that have only one (or a few) often use a "
+"different method: They expect to find the parameter in an _environment "
+"variable_. In our case, we might look at an environment variable named "
+"`PINHOLE`."
+msgstr ""
+"Файл конфигурации в основном используется программами, у которых много "
+"настраиваемых параметров. Те, у которых он один (или несколько), часто "
+"используют другой метод: они ожидают найти параметр в _переменной "
+"окружения_. В нашем случае, мы можем посмотреть на переменную окружения с "
+"именем `PINHOLE`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2935
+msgid ""
+"Usually, a program uses one or the other of the above methods. Otherwise, "
+"if a configuration file said one thing, but an environment variable another, "
+"the program might get confused (or just too complicated)."
+msgstr ""
+"Обычно программа использует один из вышеуказанных методов. В противном "
+"случае, если в конфигурационном файле указано одно, а в переменной окружения "
+"— другое, программа может запутаться (или стать слишком сложной)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2937
+msgid ""
+"Because we only need to choose _one_ such parameter, we will go with the "
+"second method and search the environment for a variable named `PINHOLE`."
+msgstr ""
+"Поскольку нам нужно выбрать только _один_ такой параметр, мы воспользуемся "
+"вторым методом и поищем в окружении переменную с именем `PINHOLE`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2940
+msgid ""
+"The other way allows us to make _ad hoc_ decisions: _\"Though I usually want "
+"you to use 0.039, this time I want 0.03872.\"_ In other words, it allows us "
+"to _override_ the permanent choice."
+msgstr ""
+"Другой способ позволяет нам принимать _ad hoc_ решения: _\"Хотя обычно я "
+"хочу, чтобы ты использовал 0.039, на этот раз мне нужно 0.03872.\"_ Другими "
+"словами, он позволяет нам _переопределить_ постоянный выбор."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2942
+msgid "This type of choice is usually done with command line parameters."
+msgstr ""
+"Такой выбор обычно осуществляется с помощью параметров командной строки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2950
+msgid ""
+"Finally, a program _always_ needs a _default_. The user may not make any "
+"choices. Perhaps he does not know what to choose. Perhaps he is \"just "
+"browsing.\" Preferably, the default will be the value most users would "
+"choose anyway. That way they do not need to choose. Or, rather, they can "
+"choose the default without an additional effort."
+msgstr ""
+"Наконец, программе _всегда_ необходим _значение по умолчанию_. Пользователь "
+"может не делать никакого выбора. Возможно, он не знает, что выбрать. "
+"Возможно, он «просто просматривает». Предпочтительно, чтобы значением по "
+"умолчанию было то, что выбрало бы большинство пользователей. Таким образом, "
+"им не нужно выбирать. Или, точнее, они могут выбрать значение по умолчанию "
+"без дополнительных усилий."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2952
+msgid ""
+"Given this system, the program may find conflicting options, and handle them "
+"this way:"
+msgstr ""
+"Учитывая эту систему, программа может обнаружить конфликтующие параметры и "
+"обработать их следующим образом:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2955
+msgid ""
+"If it finds an _ad hoc_ choice (e.g., command line parameter), it should "
+"accept that choice. It must ignore any permanent choice and any default."
+msgstr ""
+"Если она находит _специальный_ выбор (например, параметр командной строки), "
+"она должна принять этот выбор. Она должна игнорировать любой постоянный "
+"выбор и значения по умолчанию."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2956
+msgid ""
+"_Otherwise_, if it finds a permanent option (e.g., an environment variable), "
+"it should accept it, and ignore the default."
+msgstr ""
+"_В противном случае_, если будет найден постоянный параметр (например, "
+"переменная окружения), он должен быть принят, а значение по умолчанию — "
+"проигнорировано."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2957
+msgid "_Otherwise_, it should use the default."
+msgstr "_В противном случае_, следует использовать значение по умолчанию."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2959
+msgid "We also need to decide what _format_ our `PC` option should have."
+msgstr ""
+"Нам также необходимо решить, в каком _формате_ должна быть наша опция `PC`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2961
+msgid ""
+"At first site, it seems obvious to use the `PINHOLE=0.04` format for the "
+"environment variable, and `-p0.04` for the command line."
+msgstr ""
+"На первый взгляд кажется очевидным использовать формат `PINHOLE=0.04` для "
+"переменной окружения и `-p0.04` для командной строки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2965
+msgid ""
+"Allowing that is actually a security risk. The `PC` constant is a very small "
+"number. Naturally, we will test our software using various small values of "
+"`PC`. But what will happen if someone runs the program choosing a huge "
+"value?"
+msgstr ""
+"Разрешение этого на самом деле представляет угрозу безопасности. Константа "
+"`PC` — это очень маленькое число. Естественно, мы протестируем наше "
+"программное обеспечение, используя различные небольшие значения `PC`. Но что "
+"произойдёт, если кто-то запустит программу, выбрав огромное значение?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2967
+msgid ""
+"It may crash the program because we have not designed it to handle huge "
+"numbers."
+msgstr ""
+"Это может привести к сбою программы, так как мы не разрабатывали её для "
+"обработки огромных чисел."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2970
+msgid ""
+"Or, we may spend more time on the program so it can handle huge numbers. We "
+"might do that if we were writing commercial software for computer illiterate "
+"audience."
+msgstr ""
+"Или мы можем потратить больше времени на программу, чтобы она могла "
+"обрабатывать огромные числа. Мы могли бы сделать это, если бы писали "
+"коммерческое программное обеспечение для аудитории, не знакомой с "
+"компьютерами."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2972
+msgid "Or, we might say, _\"Tough! The user should know better.\"\"_"
+msgstr ""
+"Или можно сказать: _\"Пусть терпит! Пользователь сам должен был разобраться."
+"\"_"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2975
+msgid ""
+"Or, we just may make it impossible for the user to enter a huge number. "
+"This is the approach we will take: We will use an _implied 0._ prefix."
+msgstr ""
+"Или мы можем просто сделать невозможным ввод пользователем слишком большого "
+"числа. Это подход, который мы выберем: мы будем использовать "
+"_подразумеваемый префикс 0._."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2978
+msgid ""
+"In other words, if the user wants `0.04`, we will expect him to type `-p04`, "
+"or set `PINHOLE=04` in his environment. So, if he says `-p9999999`, we will "
+"interpret it as ``0.9999999``-still ridiculous but at least safer."
+msgstr ""
+"Другими словами, если пользователь хочет `0.04`, мы ожидаем, что он введёт `-"
+"p04` или установит `PINHOLE=04` в своём окружении. Таким образом, если он "
+"укажет `-p9999999`, мы интерпретируем это как ``0.9999999`` — всё ещё "
+"нелепо, но по крайней мере безопаснее."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2981
+msgid ""
+"Secondly, many users will just want to go with either Bender's constant or "
+"Connors' constant. To make it easier on them, we will interpret `-b` as "
+"identical to `-p04`, and `-c` as identical to `-p037`."
+msgstr ""
+"Во-вторых, многие пользователи просто захотят использовать либо константу "
+"Бендера, либо константу Коннорса. Чтобы облегчить им задачу, мы будем "
+"интерпретировать `-b` как идентичное `-p04`, а `-c` как идентичное `-p037`."
+
+#. type: Title ====
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2983
+#, no-wrap
+msgid "The Output"
+msgstr "Вывод результата"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2986
+msgid ""
+"We need to decide what we want our software to send to the output, and in "
+"what format."
+msgstr ""
+"Нам нужно решить, что наше программное обеспечение должно отправлять на "
+"вывод и в каком формате."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2988
+msgid ""
+"Since our input allows for an unspecified number of focal length entries, it "
+"makes sense to use a traditional database-style output of showing the result "
+"of the calculation for each focal length on a separate line, while "
+"separating all values on one line by a `tab` character."
+msgstr ""
+"Поскольку наши входные данные допускают неограниченное количество значений "
+"фокусного расстояния, имеет смысл использовать традиционный вывод в стиле "
+"базы данных, показывая результат вычислений для каждого фокусного расстояния "
+"на отдельной строке, разделяя все значения в строке символом табуляции."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2991
+msgid ""
+"Optionally, we should also allow the user to specify the use of the CSV "
+"format we have studied earlier. In this case, we will print out a line of "
+"comma-separated names describing each field of every line, then show our "
+"results as before, but substituting a `comma` for the `tab`."
+msgstr ""
+"Опционально, мы также должны разрешить пользователю указать использование "
+"формата CSV, который мы изучили ранее. В этом случае мы выведем строку с "
+"разделёнными запятыми названиями, описывающими каждое поле каждой строки, а "
+"затем отобразим результаты как прежде, но заменив `табуляцию` на `запятую`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:2996
+msgid ""
+"We need a command line option for the CSV format. We cannot use `-c` "
+"because that already means _use Connors' constant_. For some strange "
+"reason, many web sites refer to CSV files as _\"Excel spreadsheet\"_ (though "
+"the CSV format predates Excel). We will, therefore, use the `-e` switch to "
+"inform our software we want the output in the CSV format."
+msgstr ""
+"Нам нужна опция командной строки для формата CSV. Мы не можем использовать `-"
+"c`, потому что это уже означает _использовать константу Коннорса_. По какой-"
+"то странной причине многие веб-сайты называют CSV-файлы _\"электронными "
+"таблицами Excel\"_ (хотя формат CSV появился раньше Excel). Поэтому мы будем "
+"использовать переключатель `-e`, чтобы указать нашему программному "
+"обеспечению, что мы хотим получить вывод в формате CSV."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3000
+msgid ""
+"We will start each line of the output with the focal length. This may sound "
+"repetitious at first, especially in the interactive mode: The user types in "
+"the focal length, and we are repeating it."
+msgstr ""
+"Мы начнем каждую строку вывода с фокусного расстояния. Это может показаться "
+"избыточным сначала, особенно в интерактивном режиме: пользователь вводит "
+"фокусное расстояние, а мы его повторяем."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3004
+msgid ""
+"But the user can type several focal lengths on one line. The input can also "
+"come in from a file or from the output of another program. In that case the "
+"user does not see the input at all."
+msgstr ""
+"Но пользователь может ввести несколько фокусных расстояний в одной строке. "
+"Ввод также может поступать из файла или вывода другой программы. В этом "
+"случае пользователь вообще не видит вводимые данные."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3006
+msgid ""
+"By the same token, the output can go to a file which we will want to examine "
+"later, or it could go to the printer, or become the input of another program."
+msgstr ""
+"Таким же образом, вывод может быть направлен в файл, который мы захотим "
+"изучить позже, или на принтер, или стать входными данными для другой "
+"программы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3008
+msgid ""
+"So, it makes perfect sense to start each line with the focal length as "
+"entered by the user."
+msgstr ""
+"Итак, имеет полный смысл начинать каждую строку с фокусного расстояния, "
+"введённого пользователем."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3011
+msgid ""
+"No, wait! Not as entered by the user. What if the user types in something "
+"like this:"
+msgstr ""
+"Нет, подождите! Не так, как ввел пользователь. Что, если пользователь "
+"введет что-то вроде этого:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3015
+#, no-wrap
+msgid " 00000000150\n"
+msgstr " 00000000150\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3018
+msgid "Clearly, we need to strip those leading zeros."
+msgstr "Очевидно, нам нужно удалить ведущие нули."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3020
+msgid ""
+"So, we might consider reading the user input as is, converting it to binary "
+"inside the FPU, and printing it out from there."
+msgstr ""
+"Итак, можно рассмотреть вариант чтения пользовательского ввода как есть, "
+"преобразования его в бинарный вид внутри FPU и последующего вывода оттуда."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3022
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3207
+msgid "But..."
+msgstr "Но..."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3024
+msgid "What if the user types something like this:"
+msgstr "Что делать, если пользователь введёт что-то вроде этого:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3028
+#, no-wrap
+msgid " 17459765723452353453534535353530530534563507309676764423\n"
+msgstr " 17459765723452353453534535353530530534563507309676764423\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3033
+msgid ""
+"Ha! The packed decimal FPU format lets us input 18-digit numbers. But the "
+"user has entered more than 18 digits. How do we handle that?"
+msgstr ""
+"Ха! Упакованный десятичный формат FPU позволяет нам вводить 18-значные "
+"числа. Но пользователь ввёл больше 18 цифр. Как нам обработать это?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3035
+msgid ""
+"Well, we _could_ modify our code to read the first 18 digits, enter it to "
+"the FPU, then read more, multiply what we already have on the TOS by 10 "
+"raised to the number of additional digits, then `add` to it."
+msgstr ""
+"Хорошо, мы _могли бы_ изменить наш код, чтобы он читал первые 18 цифр, "
+"передавал их в FPU, затем читал ещё, умножал уже имеющееся на вершине стека "
+"(TOS) на 10 в степени количества дополнительных цифр, а затем выполнял "
+"`сложение` с этим значением."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3039
+msgid ""
+"Yes, we could do that. But in _this_ program it would be ridiculous (in a "
+"different one it may be just the thing to do): Even the circumference of the "
+"Earth expressed in millimeters only takes 11 digits. Clearly, we cannot "
+"build a camera that large (not yet, anyway)."
+msgstr ""
+"Да, мы могли бы так поступить. Но в _этой_ программе это было бы нелепо (в "
+"другой это могло бы быть как раз тем, что нужно): даже длина окружности "
+"Земли, выраженная в миллиметрах, занимает всего 11 цифр. Очевидно, мы не "
+"можем построить камеру такого размера (по крайней мере, пока)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3041
+msgid ""
+"So, if the user enters such a huge number, he is either bored, or testing "
+"us, or trying to break into the system, or playing games-doing anything but "
+"designing a pinhole camera."
+msgstr ""
+"Итак, если пользователь вводит такое огромное число, он либо скучает, либо "
+"проверяет нас, либо пытается взломать систему, либо играет — делает что "
+"угодно, кроме проектирования камеры-обскуры."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3043
+msgid "What will we do?"
+msgstr "Что мы будем делать?"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3045
+msgid "We will slap him in the face, in a manner of speaking:"
+msgstr "Мы ударим его по лицу, образно говоря:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3049
+#, no-wrap
+msgid "17459765723452353453534535353530530534563507309676764423\t???\t???\t???\t???\t???\n"
+msgstr "17459765723452353453534535353530530534563507309676764423\t???\t???\t???\t???\t???\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3053
+msgid ""
+"To achieve that, we will simply ignore any leading zeros. Once we find a "
+"non-zero digit, we will initialize a counter to `0` and start taking three "
+"steps:"
+msgstr ""
+"Для этого мы просто проигнорируем все ведущие нули. Как только мы найдем "
+"ненулевую цифру, мы инициализируем счетчик значением `0` и начнем выполнять "
+"три шага:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3056
+msgid "Send the digit to the output."
+msgstr "Отправить цифру на выход."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3057
+msgid ""
+"Append the digit to a buffer we will use later to produce the packed decimal "
+"we can send to the FPU."
+msgstr ""
+"Добавить цифру в буфер, который мы позже используем для создания "
+"упакованного десятичного числа, которое можно отправить в FPU."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3058
+msgid "Increase the counter."
+msgstr "Увеличить счетчик."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3060
+msgid ""
+"Now, while we are taking these three steps, we also need to watch out for "
+"one of two conditions:"
+msgstr ""
+"Теперь, пока мы выполняем эти три шага, нам также необходимо следить за "
+"одним из двух условий:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3062
+msgid ""
+"If the counter grows above 18, we stop appending to the buffer. We continue "
+"reading the digits and sending them to the output."
+msgstr ""
+"Если счётчик превышает 18, мы прекращаем добавление в буфер. Мы продолжаем "
+"читать цифры и отправлять их на вывод."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3063
+msgid ""
+"If, or rather _when_, the next input character is not a digit, we are done "
+"inputting for now."
+msgstr ""
+"Если, или скорее _когда_, следующий вводимый символ не является цифрой, мы "
+"завершаем ввод на данный момент."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3066
+msgid ""
+"Incidentally, we can simply discard the non-digit, unless it is a `+#+`, "
+"which we must return to the input stream. It starts a comment, so we must "
+"see it after we are done producing output and start looking for more input."
+msgstr ""
+"Между прочим, мы можем просто отбросить нецифровой символ, если это не `+#"
+"+`, который необходимо вернуть во входной поток. Он начинает комментарий, "
+"поэтому мы должны увидеть его после завершения вывода и начала поиска "
+"следующего ввода."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3068
+msgid ""
+"That still leaves one possibility uncovered: If all the user enters is a "
+"zero (or several zeros), we will never find a non-zero to display."
+msgstr ""
+"Остается одна непокрытая возможность: если пользователь вводит только ноль "
+"(или несколько нулей), мы никогда не найдем ненулевое значение для "
+"отображения."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3071
+msgid ""
+"We can determine this has happened whenever our counter stays at `0`. In "
+"that case we need to send `0` to the output, and perform another \"slap in "
+"the face\":"
+msgstr ""
+"Мы можем определить, что это произошло, когда наш счетчик остается на `0`. В "
+"этом случае нам нужно отправить `0` на выход и выполнить еще один \"удар по "
+"лицу\":"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3075
+#, no-wrap
+msgid "0\t???\t???\t???\t???\t???\n"
+msgstr "0\t???\t???\t???\t???\t???\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3078
+msgid ""
+"Once we have displayed the focal length and determined it is valid (greater "
+"than `0` but not exceeding 18 digits), we can calculate the pinhole diameter."
+msgstr ""
+"Как только мы определили фокусное расстояние и убедились, что оно корректно "
+"(больше `0`, но не превышает 18 цифр), можно рассчитать диаметр отверстия."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3081
+msgid ""
+"It is not by coincidence that _pinhole_ contains the word _pin_. Indeed, "
+"many a pinhole literally is a _pin hole_, a hole carefully punched with the "
+"tip of a pin."
+msgstr ""
+"Не случайно слово _булавочное ушко_ содержит слово _булавка_. Действительно, "
+"многие малые отверстия буквально являются _дырками от булавки_ — "
+"отверстиями, аккуратно проделанными остриём булавки."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3084
+msgid ""
+"That is because a typical pinhole is very small. Our formula gets the result "
+"in millimeters. We will multiply it by `1000`, so we can output the result "
+"in _microns_."
+msgstr ""
+"Вот потому что типичное отверстие очень маленькое. Наша формула дает "
+"результат в миллиметрах. Мы умножим его на `1000`, чтобы вывести результат в "
+"_микронах_."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3086
+msgid "At this point we have yet another trap to face: _Too much precision._"
+msgstr "На этом этапе нас ожидает ещё одна ловушка: _Излишняя точность._"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3090
+msgid ""
+"Yes, the FPU was designed for high precision mathematics. But we are not "
+"dealing with high precision mathematics. We are dealing with physics "
+"(optics, specifically)."
+msgstr ""
+"Да, FPU был разработан для вычислений с высокой точностью. Но мы имеем дело "
+"не с вычислениями высокой точности. Мы имеем дело с физикой (конкретно, с "
+"оптикой)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3094
+msgid ""
+"Suppose we want to convert a truck into a pinhole camera (we would not be "
+"the first ones to do that!). Suppose its box is `12` meters long, so we "
+"have the focal length of `12000`. Well, using Bender's constant, it gives "
+"us square root of `12000` multiplied by `0.04`, which is `4.381780460` "
+"millimeters, or `4381.780460` microns."
+msgstr ""
+"Предположим, мы хотим превратить грузовик в камеру-обскуру (мы будем не "
+"первыми, кто это сделал!). Допустим, его кузов имеет длину `12` метров, "
+"значит, фокусное расстояние равно `12000`. Используя константу Бендера, "
+"получаем квадратный корень из `12000`, умноженный на `0.04`, что составляет "
+"`4.381780460` миллиметра или `4381.780460` микрона."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3099
+msgid ""
+"Put either way, the result is absurdly precise. Our truck is not _exactly_ "
+"`12000` millimeters long. We did not measure its length with such a "
+"precision, so stating we need a pinhole with the diameter of `4.381780460` "
+"millimeters is, well, deceiving. `4.4` millimeters would do just fine."
+msgstr ""
+"Как ни посмотри, результат абсурдно точен. Наш грузовик не имеет _точно_ "
+"`12000` миллиметров в длину. Мы не измеряли его длину с такой точностью, "
+"поэтому утверждение, что нам нужна отверстие диаметром `4,381780460` "
+"миллиметра, мягко говоря, вводит в заблуждение. `4,4` миллиметра будет "
+"вполне достаточно."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3104
+msgid ""
+"I \"only\" used ten digits in the above example. Imagine the absurdity of "
+"going for all 18!"
+msgstr ""
+"Я \"всего лишь\" использовал десять цифр в приведенном выше примере. "
+"Представьте абсурдность попытки использовать все 18!"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3110
+msgid ""
+"We need to limit the number of significant digits of our result. One way of "
+"doing it is by using an integer representing microns. So, our truck would "
+"need a pinhole with the diameter of `4382` microns. Looking at that number, "
+"we still decide that `4400` microns, or `4.4` millimeters is close enough."
+msgstr ""
+"Нам нужно ограничить количество значащих цифр в нашем результате. Один из "
+"способов сделать это — использовать целое число, представляющее микроны. "
+"Таким образом, нашему грузовику потребуется отверстие диаметром `4382` "
+"микрона. Глядя на это число, мы всё же решаем, что `4400` микрон, или `4.4` "
+"миллиметра, достаточно близко."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3113
+msgid ""
+"Additionally, we can decide that no matter how big a result we get, we only "
+"want to display four significant digits (or any other number of them, of "
+"course). Alas, the FPU does not offer rounding to a specific number of "
+"digits (after all, it does not view the numbers as decimal but as binary)."
+msgstr ""
+"Кроме того, мы можем решить, что независимо от размера результата, мы хотим "
+"отображать только четыре значащих цифры (или любое другое их количество, "
+"конечно). Увы, FPU не поддерживает округление до определенного количества "
+"цифр (в конце концов, он воспринимает числа не как десятичные, а как "
+"двоичные)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3115
+msgid ""
+"We, therefore, must devise an algorithm to reduce the number of significant "
+"digits."
+msgstr ""
+"Следовательно, мы должны разработать алгоритм для уменьшения количества "
+"значащих цифр."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3117
+msgid ""
+"Here is mine (I think it is awkward-if you know a better one, _please_, let "
+"me know):"
+msgstr ""
+"Вот мой (я думаю, он неуклюжий — если у вас есть вариант лучше, "
+"_пожалуйста_, дайте мне знать):"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3120
+msgid "Initialize a counter to `0`."
+msgstr "Инициализировать счетчик значением `0`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3121
+msgid ""
+"While the number is greater than or equal to `10000`, divide it by `10` and "
+"increase the counter."
+msgstr ""
+"Пока число больше или равно `10000`, делим его на `10` и увеличиваем счётчик."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3122
+msgid "Output the result."
+msgstr "Вывести результат."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3123
+msgid ""
+"While the counter is greater than `0`, output `0` and decrease the counter."
+msgstr "Пока счетчик больше `0`, выводить `0` и уменьшать счетчик."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3128
+msgid ""
+"The `10000` is only good if you want _four_ significant digits. For any "
+"other number of significant digits, replace `10000` with `10` raised to the "
+"number of significant digits."
+msgstr ""
+"`10000` подходит только если вам нужно _четыре_ значащих цифры. Для любого "
+"другого количества значащих цифр замените `10000` на `10` в степени, равной "
+"количеству значащих цифр."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3131
+msgid ""
+"We will, then, output the pinhole diameter in microns, rounded off to four "
+"significant digits."
+msgstr ""
+"Мы затем выведем диаметр отверстия в микронах, округлённый до четырёх "
+"значащих цифр."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3134
+msgid ""
+"At this point, we know the _focal length_ and the _pinhole diameter_. That "
+"means we have enough information to also calculate the _f-number_."
+msgstr ""
+"На этом этапе нам известны _фокусное расстояние_ и _диаметр отверстия_. Это "
+"означает, что у нас достаточно информации для расчёта _диафрагменного числа_."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3138
+msgid ""
+"We will display the f-number, rounded to four significant digits. Chances "
+"are the f-number will tell us very little. To make it more meaningful, we "
+"can find the nearest _normalized f-number_, i.e., the nearest power of the "
+"square root of 2."
+msgstr ""
+"Мы отобразим число f, округлённое до четырёх значащих цифр. Скорее всего, "
+"само число f мало что нам скажет. Чтобы придать ему больше смысла, мы можем "
+"найти ближайшее _нормализованное число f_, то есть ближайшую степень "
+"квадратного корня из 2."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3144
+msgid ""
+"We do that by multiplying the actual f-number by itself, which, of course, "
+"will give us its `square`. We will then calculate its base-2 logarithm, "
+"which is much easier to do than calculating the base-square-root-of-2 "
+"logarithm! We will round the result to the nearest integer. Next, we will "
+"raise 2 to the result. Actually, the FPU gives us a good shortcut to do "
+"that: We can use the `fscale` op code to \"scale\" 1, which is analogous to "
+"``shift``ing an integer left. Finally, we calculate the square root of it "
+"all, and we have the nearest normalized f-number."
+msgstr ""
+"Мы делаем это, умножая фактическое значение диафрагмы на само себя, что, "
+"конечно же, даст нам его `квадрат`. Затем мы вычислим его логарифм по "
+"основанию 2, что намного проще, чем вычисление логарифма по основанию "
+"квадратного корня из 2! Мы округлим результат до ближайшего целого числа. "
+"Далее мы возведём 2 в полученную степень. На самом деле, FPU предоставляет "
+"нам удобный способ сделать это: мы можем использовать код операции `fscale` "
+"для \"масштабирования\" 1, что аналогично ``сдвигу`` целого числа влево. "
+"Наконец, мы вычисляем квадратный корень из всего этого и получаем ближайшее "
+"нормализованное значение диафрагмы."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3147
+msgid ""
+"If all that sounds overwhelming-or too much work, perhaps-it may become much "
+"clearer if you see the code. It takes 9 op codes altogether:"
+msgstr ""
+"Если всё это звучит ошеломляюще — или, возможно, слишком сложно — всё может "
+"стать гораздо понятнее, если увидеть код. Вместе это занимает всего 9 "
+"инструкций процессора:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3159
+#, no-wrap
+msgid ""
+"fmul\tst0, st0\n"
+"\tfld1\n"
+"\tfld\tst1\n"
+"\tfyl2x\n"
+"\tfrndint\n"
+"\tfld1\n"
+"\tfscale\n"
+"\tfsqrt\n"
+"\tfstp\tst1\n"
+msgstr ""
+"fmul\tst0, st0\n"
+"\tfld1\n"
+"\tfld\tst1\n"
+"\tfyl2x\n"
+"\tfrndint\n"
+"\tfld1\n"
+"\tfscale\n"
+"\tfsqrt\n"
+"\tfstp\tst1\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3163
+msgid ""
+"The first line, `fmul st0, st0`, squares the contents of the TOS (top of the "
+"stack, same as `st`, called `st0` by nasm). The `fld1` pushes `1` on the "
+"TOS."
+msgstr ""
+"Первая строка, `fmul st0, st0`, возводит в квадрат содержимое TOS (вершина "
+"стека, то же что `st`, называется `st0` в nasm). Команда `fld1` помещает `1` "
+"на вершину стека."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3167
+msgid ""
+"The next line, `fld st1`, pushes the square back to the TOS. At this point "
+"the square is both in `st` and `st(2)` (it will become clear why we leave a "
+"second copy on the stack in a moment). `st(1)` contains `1`."
+msgstr ""
+"Следующая строка, `fld st1`, помещает квадрат обратно в TOS. На этом этапе "
+"квадрат находится и в `st`, и в `st(2)` (скоро станет ясно, зачем мы "
+"оставляем вторую копию в стеке). В `st(1)` содержится `1`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3170
+msgid ""
+"Next, `fyl2x` calculates base-2 logarithm of `st` multiplied by `st(1)`. "
+"That is why we placed `1` on `st(1)` before."
+msgstr ""
+"Далее, `fyl2x` вычисляет логарифм по основанию 2 от `st`, умноженный на "
+"`st(1)`. Именно поэтому мы ранее поместили `1` в `st(1)`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3172
+msgid ""
+"At this point, `st` contains the logarithm we have just calculated, `st(1)` "
+"contains the square of the actual f-number we saved for later."
+msgstr ""
+"На этом этапе `st` содержит логарифм, который мы только что вычислили, а "
+"`st(1)` содержит квадрат фактического значения диафрагменного числа, который "
+"мы сохранили для последующего использования."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3176
+msgid ""
+"`frndint` rounds the TOS to the nearest integer. `fld1` pushes a `1`. "
+"`fscale` shifts the `1` we have on the TOS by the value in `st(1)`, "
+"effectively raising 2 to `st(1)`."
+msgstr ""
+"`frndint` округляет TOS до ближайшего целого числа. `fld1` помещает `1` в "
+"стек. `fscale` сдвигает `1`, находящееся на TOS, на значение в `st(1)`, "
+"фактически возводя 2 в степень `st(1)`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3178
+msgid ""
+"Finally, `fsqrt` calculates the square root of the result, i.e., the nearest "
+"normalized f-number."
+msgstr ""
+"Наконец, `fsqrt` вычисляет квадратный корень из результата, т.е. ближайшее "
+"нормализованное число f."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3181
+msgid ""
+"We now have the nearest normalized f-number on the TOS, the base-2 logarithm "
+"rounded to the nearest integer in `st(1)`, and the square of the actual f-"
+"number in `st(2)`. We are saving the value in `st(2)` for later."
+msgstr ""
+"У нас теперь есть ближайшее нормализованное число f на вершине стека (TOS), "
+"округлённый до ближайшего целого двоичный логарифм в `st(1)` и квадрат "
+"фактического число f в `st(2)`. Мы сохраняем значение в `st(2)` для "
+"последующего использования."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3187
+msgid ""
+"But we do not need the contents of `st(1)` anymore. The last line, `fstp "
+"st1`, places the contents of `st` to `st(1)`, and pops. As a result, what "
+"was `st(1)` is now `st`, what was `st(2)` is now `st(1)`, etc. The new `st` "
+"contains the normalized f-number. The new `st(1)` contains the square of "
+"the actual f-number we have stored there for posterity."
+msgstr ""
+"Но нам больше не нужно содержимое `st(1)`. Последняя строка, `fstp st1`, "
+"помещает содержимое `st` в `st(1)` и выполняет извлечение. В результате, то, "
+"что было `st(1)`, теперь становится `st`, то, что было `st(2)`, теперь "
+"становится `st(1)`, и так далее. Новый `st` содержит нормализованное число "
+"f. Новый `st(1)` содержит квадрат фактического число f, который мы сохранили "
+"для потомков."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3190
+msgid ""
+"At this point, we are ready to output the normalized f-number. Because it "
+"is normalized, we will not round it off to four significant digits, but will "
+"send it out in its full precision."
+msgstr ""
+"На этом этапе мы готовы вывести нормализованное число f. Поскольку оно "
+"нормализовано, мы не будем округлять его до четырёх значащих цифр, а "
+"отправим его с полной точностью."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3193
+msgid ""
+"The normalized f-number is useful as long as it is reasonably small and can "
+"be found on our light meter. Otherwise we need a different method of "
+"determining proper exposure."
+msgstr ""
+"Нормализованное диафрагменное число полезно, пока оно достаточно мало и "
+"может быть найдено на нашем экспонометре. В противном случае нам нужен "
+"другой метод определения правильной экспозиции."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3195
+msgid ""
+"Earlier we have figured out the formula of calculating proper exposure at an "
+"arbitrary f-number from that measured at a different f-number."
+msgstr ""
+"Ранее мы вывели формулу для расчёта правильной экспозиции при произвольной "
+"диафрагме на основе измерений, сделанных при другой диафрагме."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3198
+msgid ""
+"Every light meter I have ever seen can determine proper exposure at f5.6. "
+"We will, therefore, calculate an _\"f5.6 multiplier,\"_ i.e., by how much we "
+"need to multiply the exposure measured at f5.6 to determine the proper "
+"exposure for our pinhole camera."
+msgstr ""
+"Каждый экспонометр, который я когда-либо видел, может определить правильную "
+"экспозицию при f5.6. Поэтому мы рассчитаем _\"множитель f5.6\"_, то есть "
+"насколько нужно умножить экспозицию, измеренную при f5.6, чтобы определить "
+"правильную экспозицию для нашей камеры-обскуры."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3200
+msgid ""
+"From the above formula we know this factor can be calculated by dividing our "
+"f-number (the actual one, not the normalized one) by `5.6`, and squaring the "
+"result."
+msgstr ""
+"Из приведённой формулы мы знаем, что этот коэффициент можно вычислить, "
+"разделив наше число f (фактическое, а не нормализованное) на `5.6` и возведя "
+"результат в квадрат."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3202
+msgid ""
+"Mathematically, dividing the square of our f-number by the square of `5.6` "
+"will give us the same result."
+msgstr ""
+"Математически, деление квадрата нашего числа f на квадрат `5.6` даст нам тот "
+"же результат."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3205
+msgid ""
+"Computationally, we do not want to square two numbers when we can only "
+"square one. So, the first solution seems better at first."
+msgstr ""
+"С вычислительной точки зрения, нам не нужно возводить в квадрат два числа, "
+"когда можно возвести только одно. Таким образом, первое решение на первый "
+"взгляд кажется лучше."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3213
+msgid ""
+"`5.6` is a _constant_. We do not have to have our FPU waste precious "
+"cycles. We can just tell it to divide the square of the f-number by "
+"whatever `5.6²` equals to. Or we can divide the f-number by `5.6`, and then "
+"square the result. The two ways now seem equal."
+msgstr ""
+"`5.6` — это _константа_. Нам не нужно заставлять наш FPU тратить драгоценные "
+"циклы. Мы можем просто указать ему разделить квадрат f-числа на то, чему "
+"равно `5.6²`. Или мы можем разделить f-число на `5.6`, а затем возвести "
+"результат в квадрат. Теперь оба способа кажутся равнозначными."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3215
+msgid "But, they are not!"
+msgstr "Но они не такие!"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3219
+msgid ""
+"Having studied the principles of photography above, we remember that the "
+"`5.6` is actually square root of 2 raised to the fifth power. An "
+"_irrational_ number. The square of this number is _exactly_ `32`."
+msgstr ""
+"Изучив принципы фотографии выше, мы помним, что `5.6` — это квадратный "
+"корень из 2, возведённый в пятую степень. Это _иррациональное_ число. "
+"Квадрат этого числа _ровно_ `32`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3225
+msgid ""
+"Not only is `32` an integer, it is a power of 2. We do not need to divide "
+"the square of the f-number by `32`. We only need to use `fscale` to shift "
+"it right by five positions. In the FPU lingo it means we will `fscale` it "
+"with `st(1)` equal to `-5`. That is _much faster_ than a division."
+msgstr ""
+"`32` — это не просто целое число, это степень двойки. Нам не нужно делить "
+"квадрат числа f на `32`. Достаточно использовать `fscale` для сдвига вправо "
+"на пять позиций. В терминологии FPU это означает, что мы применим `fscale` "
+"со значением `st(1)` равным `-5`. Это _гораздо быстрее_, чем деление."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3228
+msgid ""
+"So, now it has become clear why we have saved the square of the f-number on "
+"the top of the FPU stack. The calculation of the f5.6 multiplier is the "
+"easiest calculation of this entire program! We will output it rounded to "
+"four significant digits."
+msgstr ""
+"Итак, теперь стало ясно, зачем мы сохранили квадрат числа f на вершине стека "
+"FPU. Расчёт множителя для f5.6 — это самое простое вычисление во всей "
+"программе! Мы выведем его, округлив до четырёх значащих цифр."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3231
+msgid ""
+"There is one more useful number we can calculate: The number of stops our f-"
+"number is from f5.6. This may help us if our f-number is just outside the "
+"range of our light meter, but we have a shutter which lets us set various "
+"speeds, and this shutter uses stops."
+msgstr ""
+"Есть ещё одно полезное число, которое мы можем вычислить: количество "
+"ступеней, на которые наше значение диафрагмы отличается от f5.6. Это может "
+"помочь, если наше значение диафрагмы находится чуть за пределами диапазона "
+"нашего экспонометра, но у нас есть затвор, который позволяет устанавливать "
+"различные выдержки, и этот затвор использует ступени."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3234
+msgid ""
+"Say, our f-number is 5 stops from f5.6, and the light meter says we should "
+"use 1/1000 sec. Then we can set our shutter speed to 1/1000 first, then "
+"move the dial by 5 stops."
+msgstr ""
+"Предположим, наше число диафрагмы на 5 ступеней отличается от f5.6, а "
+"экспонометр показывает, что нужно использовать выдержку 1/1000 сек. Тогда мы "
+"можем сначала установить выдержку на 1/1000, а затем повернуть диск на 5 "
+"ступеней."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3239
+msgid ""
+"This calculation is quite easy as well. All we have to do is to calculate "
+"the base-2 logarithm of the f5.6 multiplier we had just calculated (though "
+"we need its value from before we rounded it off). We then output the result "
+"rounded to the nearest integer. We do not need to worry about having more "
+"than four significant digits in this one: The result is most likely to have "
+"only one or two digits anyway."
+msgstr ""
+"Этот расчет также довольно прост. Все, что нам нужно сделать, это вычислить "
+"логарифм по основанию 2 от множителя f5.6, который мы только что рассчитали "
+"(хотя нам нужно его значение до округления). Затем мы выводим результат, "
+"округленный до ближайшего целого числа. Нам не нужно беспокоиться о наличии "
+"более четырех значащих цифр в этом случае: скорее всего, результат будет "
+"содержать только одну или две цифры."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3241
+#, no-wrap
+msgid "FPU Optimizations"
+msgstr "Оптимизации FPU"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3244
+msgid ""
+"In assembly language we can optimize the FPU code in ways impossible in high "
+"languages, including C."
+msgstr ""
+"В ассемблерном коде мы можем оптимизировать инструкции FPU способами, "
+"невозможными в языках высокого уровня, включая C."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3248
+msgid ""
+"Whenever a C function needs to calculate a floating-point value, it loads "
+"all necessary variables and constants into FPU registers. It then does "
+"whatever calculation is required to get the correct result. Good C "
+"compilers can optimize that part of the code really well."
+msgstr ""
+"Всякий раз, когда функции на языке C требуется вычислить значение с "
+"плавающей запятой, она загружает все необходимые переменные и константы в "
+"регистры FPU. Затем выполняются все необходимые вычисления для получения "
+"правильного результата. Хорошие компиляторы C могут очень эффективно "
+"оптимизировать эту часть кода."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3252
+msgid ""
+"It \"returns\" the value by leaving the result on the TOS. However, before "
+"it returns, it cleans up. Any variables and constants it used in its "
+"calculation are now gone from the FPU."
+msgstr ""
+"Он \"возвращает\" значение, оставляя результат на вершине стека (TOS). "
+"Однако перед возвратом он выполняет очистку. Все переменные и константы, "
+"использованные в вычислениях, теперь удалены из FPU."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3254
+msgid ""
+"It cannot do what we just did above: We calculated the square of the f-"
+"number and kept it on the stack for later use by another function."
+msgstr ""
+"Он не может сделать то, что мы только что сделали выше: мы вычислили квадрат "
+"числа f и оставили его в стеке для последующего использования другой "
+"функцией."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3257
+msgid ""
+"We _knew_ we would need that value later on. We also knew we had enough "
+"room on the stack (which only has room for 8 numbers) to store it there."
+msgstr ""
+"Мы _знали_, что это значение понадобится позже. Мы также знали, что у нас "
+"достаточно места в стеке (в котором помещается только 8 чисел), чтобы "
+"сохранить его там."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3259
+msgid ""
+"A C compiler has no way of knowing that a value it has on the stack will be "
+"required again in the very near future."
+msgstr ""
+"Компилятор C не может знать, что значение, находящееся в стеке, потребуется "
+"снова в ближайшем будущем."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3262
+msgid ""
+"Of course, the C programmer may know it. But the only recourse he has is to "
+"store the value in a memory variable."
+msgstr ""
+"Конечно, программист на C может это знать. Но единственное средство, которое "
+"у него есть, — это сохранить значение в переменной памяти."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3264
+msgid ""
+"That means, for one, the value will be changed from the 80-bit precision "
+"used internally by the FPU to a C _double_ (64 bits) or even _single_ (32 "
+"bits)."
+msgstr ""
+"Это означает, что значение будет изменено с 80-битной точности, используемой "
+"внутри FPU, на тип _double_ (64 бита) или даже _single_ (32 бита) в C."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3267
+msgid ""
+"That also means that the value must be moved from the TOS into the memory, "
+"and then back again. Alas, of all FPU operations, the ones that access the "
+"computer memory are the slowest."
+msgstr ""
+"Это также означает, что значение должно быть перемещено из TOS в память, а "
+"затем обратно. Увы, среди всех операций с FPU, доступ к памяти компьютера "
+"является самым медленным."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3269
+msgid ""
+"So, whenever programming the FPU in assembly language, look for the ways of "
+"keeping intermediate results on the FPU stack."
+msgstr ""
+"Итак, при программировании FPU на языке ассемблера ищите способы хранения "
+"промежуточных результатов в стеке FPU."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3271
+msgid ""
+"We can take that idea even further! In our program we are using a _constant_ "
+"(the one we named `PC`)."
+msgstr ""
+"Мы можем развить эту идею еще дальше! В нашей программе мы используем "
+"_константу_ (ту, которую назвали `PC`)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3274
+msgid ""
+"It does not matter how many pinhole diameters we are calculating: 1, 10, 20, "
+"1000, we are always using the same constant. Therefore, we can optimize our "
+"program by keeping the constant on the stack all the time."
+msgstr ""
+"Не имеет значения, сколько диаметров отверстий мы рассчитываем: 1, 10, 20, "
+"1000, мы всегда используем одну и ту же константу. Следовательно, мы можем "
+"оптимизировать нашу программу, сохраняя константу в стеке всё время."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3277
+msgid ""
+"Early on in our program, we are calculating the value of the above "
+"constant. We need to divide our input by `10` for every digit in the "
+"constant."
+msgstr ""
+"В начале нашей программы мы вычисляем значение указанной константы. Нам "
+"нужно разделить наш вход на `10` для каждой цифры в константе."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3280
+msgid ""
+"It is much faster to multiply than to divide. So, at the start of our "
+"program, we divide `10` into `1` to obtain `0.1`, which we then keep on the "
+"stack: Instead of dividing the input by `10` for every digit, we multiply it "
+"by `0.1`."
+msgstr ""
+"Гораздо быстрее умножать, чем делить. Поэтому в начале нашей программы мы "
+"делим `1` на `10`, чтобы получить `0.1`, который затем сохраняем в стеке: "
+"вместо того чтобы делить ввод на `10` для каждой цифры, мы умножаем его на "
+"`0.1`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3284
+msgid ""
+"By the way, we do not input `0.1` directly, even though we could. We have a "
+"reason for that: While `0.1` can be expressed with just one decimal place, "
+"we do not know how many _binary_ places it takes. We, therefore, let the "
+"FPU calculate its binary value to its own high precision."
+msgstr ""
+"Кстати, мы не вводим `0.1` напрямую, хотя могли бы. У нас есть причина для "
+"этого: хотя `0.1` можно выразить всего одним десятичным знаком, мы не знаем, "
+"сколько _двоичных_ разрядов для этого потребуется. Поэтому мы позволяем FPU "
+"вычислить его двоичное значение с собственной высокой точностью."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3289
+msgid ""
+"We are using other constants: We multiply the pinhole diameter by `1000` to "
+"convert it from millimeters to microns. We compare numbers to `10000` when "
+"we are rounding them off to four significant digits. So, we keep both, "
+"`1000` and `10000`, on the stack. And, of course, we reuse the `0.1` when "
+"rounding off numbers to four digits."
+msgstr ""
+"Мы используем другие константы: умножаем диаметр отверстия на `1000`, чтобы "
+"перевести его из миллиметров в микроны. Мы сравниваем числа с `10000`, когда "
+"округляем их до четырёх значащих цифр. Таким образом, мы оставляем и `1000`, "
+"и `10000` в стеке. И, конечно же, мы повторно используем `0.1` при "
+"округлении чисел до четырёх цифр."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3295
+msgid ""
+"Last but not least, we keep `-5` on the stack. We need it to scale the "
+"square of the f-number, instead of dividing it by `32`. It is not by "
+"coincidence we load this constant last. That makes it the top of the stack "
+"when only the constants are on it. So, when the square of the f-number is "
+"being scaled, the `-5` is at `st(1)`, precisely where `fscale` expects it to "
+"be."
+msgstr ""
+"И последнее, но не менее важное: мы оставляем `-5` в стеке. Он нам нужен для "
+"масштабирования квадрата числа f вместо деления его на `32`. Не случайно мы "
+"загружаем эту константу последней. Это делает её вершиной стека, когда в нём "
+"находятся только константы. Таким образом, при масштабировании квадрата "
+"число f `-5` находится в `st(1)`, именно там, где `fscale` ожидает его "
+"увидеть."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3298
+msgid ""
+"It is common to create certain constants from scratch instead of loading "
+"them from the memory. That is what we are doing with `-5`:"
+msgstr ""
+"Это обычная ситуация, когда некоторые константы создаются с нуля, вместо "
+"загрузки их из памяти. Именно это мы делаем с `-5`:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3307
+#, no-wrap
+msgid ""
+"\tfld1\t\t\t; TOS = 1\n"
+"\tfadd\tst0, st0\t; TOS = 2\n"
+"\tfadd\tst0, st0\t; TOS = 4\n"
+"\tfld1\t\t\t; TOS = 1\n"
+"\tfaddp\tst1, st0\t; TOS = 5\n"
+"\tfchs\t\t\t; TOS = -5\n"
+msgstr ""
+"\tfld1\t\t\t; TOS = 1\n"
+"\tfadd\tst0, st0\t; TOS = 2\n"
+"\tfadd\tst0, st0\t; TOS = 4\n"
+"\tfld1\t\t\t; TOS = 1\n"
+"\tfaddp\tst1, st0\t; TOS = 5\n"
+"\tfchs\t\t\t; TOS = -5\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3310
+msgid ""
+"We can generalize all these optimizations into one rule: _Keep repeat values "
+"on the stack!_"
+msgstr ""
+"Мы можем обобщить все эти оптимизации в одном правиле: _Держите "
+"повторяющиеся значения в стеке!_"
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3315
+msgid ""
+"_PostScript(R)_ is a stack-oriented programming language. There are many "
+"more books available about PostScript(R) than about the FPU assembly "
+"language: Mastering PostScript(R) will help you master the FPU."
+msgstr ""
+"_PostScript(R)_ — это стековая язык программирования. Существует гораздо "
+"больше книг о PostScript(R), чем о языке ассемблера FPU: освоение "
+"PostScript(R) поможет вам овладеть FPU."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3318
+#, no-wrap
+msgid "pinhole-The Code"
+msgstr "Код pinhole"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3333
+#, no-wrap
+msgid ""
+";;;;;;; pinhole.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";\n"
+"; Find various parameters of a pinhole camera construction and use\n"
+";\n"
+"; Started:\t 9-Jun-2001\n"
+"; Updated:\t10-Jun-2001\n"
+";\n"
+"; Copyright (c) 2001 G. Adam Stanislav\n"
+"; All rights reserved.\n"
+";\n"
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+msgstr ""
+";;;;;;; pinhole.asm ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+";\n"
+"; Find various parameters of a pinhole camera construction and use\n"
+";\n"
+"; Started:\t 9-Jun-2001\n"
+"; Updated:\t10-Jun-2001\n"
+";\n"
+"; Copyright (c) 2001 G. Adam Stanislav\n"
+"; All rights reserved.\n"
+";\n"
+";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3368
+#, no-wrap
+msgid ""
+"section\t.data\n"
+"align 4\n"
+"ten\tdd\t10\n"
+"thousand\tdd\t1000\n"
+"tthou\tdd\t10000\n"
+"fd.in\tdd\tstdin\n"
+"fd.out\tdd\tstdout\n"
+"envar\tdb\t'PINHOLE='\t; Exactly 8 bytes, or 2 dwords long\n"
+"pinhole\tdb\t'04,', \t\t; Bender's constant (0.04)\n"
+"connors\tdb\t'037', 0Ah\t; Connors' constant\n"
+"usg\tdb\t'Usage: pinhole [-b] [-c] [-e] [-p <value>] [-o <outfile>] [-i <infile>]', 0Ah\n"
+"usglen\tequ\t$-usg\n"
+"iemsg\tdb\t\"pinhole: Can't open input file\", 0Ah\n"
+"iemlen\tequ\t$-iemsg\n"
+"oemsg\tdb\t\"pinhole: Can't create output file\", 0Ah\n"
+"oemlen\tequ\t$-oemsg\n"
+"pinmsg\tdb\t\"pinhole: The PINHOLE constant must not be 0\", 0Ah\n"
+"pinlen\tequ\t$-pinmsg\n"
+"toobig\tdb\t\"pinhole: The PINHOLE constant may not exceed 18 decimal places\", 0Ah\n"
+"biglen\tequ\t$-toobig\n"
+"huhmsg\tdb\t9, '???'\n"
+"separ\tdb\t9, '???'\n"
+"sep2\tdb\t9, '???'\n"
+"sep3\tdb\t9, '???'\n"
+"sep4\tdb\t9, '???', 0Ah\n"
+"huhlen\tequ\t$-huhmsg\n"
+"header\tdb\t'focal length in millimeters,pinhole diameter in microns,'\n"
+"\tdb\t'F-number,normalized F-number,F-5.6 multiplier,stops '\n"
+"\tdb\t'from F-5.6', 0Ah\n"
+"headlen\tequ\t$-header\n"
+msgstr ""
+"section\t.data\n"
+"align 4\n"
+"ten\tdd\t10\n"
+"thousand\tdd\t1000\n"
+"tthou\tdd\t10000\n"
+"fd.in\tdd\tstdin\n"
+"fd.out\tdd\tstdout\n"
+"envar\tdb\t'PINHOLE='\t; Exactly 8 bytes, or 2 dwords long\n"
+"pinhole\tdb\t'04,', \t\t; Bender's constant (0.04)\n"
+"connors\tdb\t'037', 0Ah\t; Connors' constant\n"
+"usg\tdb\t'Usage: pinhole [-b] [-c] [-e] [-p <value>] [-o <outfile>] [-i <infile>]', 0Ah\n"
+"usglen\tequ\t$-usg\n"
+"iemsg\tdb\t\"pinhole: Can't open input file\", 0Ah\n"
+"iemlen\tequ\t$-iemsg\n"
+"oemsg\tdb\t\"pinhole: Can't create output file\", 0Ah\n"
+"oemlen\tequ\t$-oemsg\n"
+"pinmsg\tdb\t\"pinhole: The PINHOLE constant must not be 0\", 0Ah\n"
+"pinlen\tequ\t$-pinmsg\n"
+"toobig\tdb\t\"pinhole: The PINHOLE constant may not exceed 18 decimal places\", 0Ah\n"
+"biglen\tequ\t$-toobig\n"
+"huhmsg\tdb\t9, '???'\n"
+"separ\tdb\t9, '???'\n"
+"sep2\tdb\t9, '???'\n"
+"sep3\tdb\t9, '???'\n"
+"sep4\tdb\t9, '???', 0Ah\n"
+"huhlen\tequ\t$-huhmsg\n"
+"header\tdb\t'focal length in millimeters,pinhole diameter in microns,'\n"
+"\tdb\t'F-number,normalized F-number,F-5.6 multiplier,stops '\n"
+"\tdb\t'from F-5.6', 0Ah\n"
+"headlen\tequ\t$-header\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3374
+#, no-wrap
+msgid ""
+"section .bss\n"
+"ibuffer\tresb\tBUFSIZE\n"
+"obuffer\tresb\tBUFSIZE\n"
+"dbuffer\tresb\t20\t\t; decimal input buffer\n"
+"bbuffer\tresb\t10\t\t; BCD buffer\n"
+msgstr ""
+"section .bss\n"
+"ibuffer\tresb\tBUFSIZE\n"
+"obuffer\tresb\tBUFSIZE\n"
+"dbuffer\tresb\t20\t\t; decimal input buffer\n"
+"bbuffer\tresb\t10\t\t; BCD buffer\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3385
+#, no-wrap
+msgid ""
+"section\t.text\n"
+"align 4\n"
+"huh:\n"
+"\tcall\twrite\n"
+"\tpush\tdword huhlen\n"
+"\tpush\tdword huhmsg\n"
+"\tpush\tdword [fd.out]\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tret\n"
+msgstr ""
+"section\t.text\n"
+"align 4\n"
+"huh:\n"
+"\tcall\twrite\n"
+"\tpush\tdword huhlen\n"
+"\tpush\tdword huhmsg\n"
+"\tpush\tdword [fd.out]\n"
+"\tsys.write\n"
+"\tadd\tesp, byte 12\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3394
+#, no-wrap
+msgid ""
+"align 4\n"
+"perr:\n"
+"\tpush\tdword pinlen\n"
+"\tpush\tdword pinmsg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 4\t\t; return failure\n"
+"\tsys.exit\n"
+msgstr ""
+"align 4\n"
+"perr:\n"
+"\tpush\tdword pinlen\n"
+"\tpush\tdword pinmsg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 4\t\t; return failure\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3403
+#, no-wrap
+msgid ""
+"align 4\n"
+"consttoobig:\n"
+"\tpush\tdword biglen\n"
+"\tpush\tdword toobig\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 5\t\t; return failure\n"
+"\tsys.exit\n"
+msgstr ""
+"align 4\n"
+"consttoobig:\n"
+"\tpush\tdword biglen\n"
+"\tpush\tdword toobig\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 5\t\t; return failure\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3412
+#, no-wrap
+msgid ""
+"align 4\n"
+"ierr:\n"
+"\tpush\tdword iemlen\n"
+"\tpush\tdword iemsg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 1\t\t; return failure\n"
+"\tsys.exit\n"
+msgstr ""
+"align 4\n"
+"ierr:\n"
+"\tpush\tdword iemlen\n"
+"\tpush\tdword iemsg\n"
+"\tpush\tdword stderr\n"
+"\tsys.write\n"
+"\tpush\tdword 1\t\t; return failure\n"
+"\tsys.exit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3436
+#, no-wrap
+msgid ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
+"\tsub\tesi, esi\n"
+msgstr ""
+"align 4\n"
+"global\t_start\n"
+"_start:\n"
+"\tadd\tesp, byte 8\t; discard argc and argv[0]\n"
+"\tsub\tesi, esi\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3441
+#, no-wrap
+msgid ""
+".arg:\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje\tnear .getenv\t\t; no more arguments\n"
+msgstr ""
+".arg:\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje\tnear .getenv\t\t; no more arguments\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3449
+#, no-wrap
+msgid ""
+"\tinc\tecx\n"
+"\tmov\tax, [ecx]\n"
+"\tinc\tecx\n"
+msgstr ""
+"\tinc\tecx\n"
+"\tmov\tax, [ecx]\n"
+"\tinc\tecx\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3467
+#, no-wrap
+msgid ""
+"\tor\tah, ah\n"
+"\tjne\t.openoutput\n"
+"\tpop\tecx\n"
+"\tjecxz\tusage\n"
+msgstr ""
+"\tor\tah, ah\n"
+"\tjne\t.openoutput\n"
+"\tpop\tecx\n"
+"\tjecxz\tusage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3494
+#, no-wrap
+msgid ""
+"\t; Find the path to the input file\n"
+"\tor\tah, ah\n"
+"\tjne\t.openinput\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje near usage\n"
+msgstr ""
+"\t; Find the path to the input file\n"
+"\tor\tah, ah\n"
+"\tjne\t.openinput\n"
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje near usage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3510
+#, no-wrap
+msgid ""
+".p:\n"
+"\tcmp\tal, 'p'\n"
+"\tjne\t.c\n"
+"\tor\tah, ah\n"
+"\tjne\t.pcheck\n"
+msgstr ""
+".p:\n"
+"\tcmp\tal, 'p'\n"
+"\tjne\t.c\n"
+"\tor\tah, ah\n"
+"\tjne\t.pcheck\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3514
+#, no-wrap
+msgid ""
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje\tnear usage\n"
+msgstr ""
+"\tpop\tecx\n"
+"\tor\tecx, ecx\n"
+"\tje\tnear usage\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3516
+#, no-wrap
+msgid "\tmov\tah, [ecx]\n"
+msgstr "\tmov\tah, [ecx]\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3524
+#, no-wrap
+msgid ""
+".pcheck:\n"
+"\tcmp\tah, '0'\n"
+"\tjl\tnear usage\n"
+"\tcmp\tah, '9'\n"
+"\tja\tnear usage\n"
+"\tmov\tesi, ecx\n"
+"\tjmp\t.arg\n"
+msgstr ""
+".pcheck:\n"
+"\tcmp\tah, '0'\n"
+"\tjl\tnear usage\n"
+"\tcmp\tah, '9'\n"
+"\tja\tnear usage\n"
+"\tmov\tesi, ecx\n"
+"\tjmp\t.arg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3532
+#, no-wrap
+msgid ""
+".c:\n"
+"\tcmp\tal, 'c'\n"
+"\tjne\t.b\n"
+"\tor\tah, ah\n"
+"\tjne\tnear usage\n"
+"\tmov\tesi, connors\n"
+"\tjmp\t.arg\n"
+msgstr ""
+".c:\n"
+"\tcmp\tal, 'c'\n"
+"\tjne\t.b\n"
+"\tor\tah, ah\n"
+"\tjne\tnear usage\n"
+"\tmov\tesi, connors\n"
+"\tjmp\t.arg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3540
+#, no-wrap
+msgid ""
+".b:\n"
+"\tcmp\tal, 'b'\n"
+"\tjne\t.e\n"
+"\tor\tah, ah\n"
+"\tjne\tnear usage\n"
+"\tmov\tesi, pinhole\n"
+"\tjmp\t.arg\n"
+msgstr ""
+".b:\n"
+"\tcmp\tal, 'b'\n"
+"\tjne\t.e\n"
+"\tor\tah, ah\n"
+"\tjne\tnear usage\n"
+"\tmov\tesi, pinhole\n"
+"\tjmp\t.arg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3553
+#, no-wrap
+msgid ""
+".e:\n"
+"\tcmp\tal, 'e'\n"
+"\tjne\tnear usage\n"
+"\tor\tah, ah\n"
+"\tjne\tnear usage\n"
+"\tmov\tal, ','\n"
+"\tmov\t[huhmsg], al\n"
+"\tmov\t[separ], al\n"
+"\tmov\t[sep2], al\n"
+"\tmov\t[sep3], al\n"
+"\tmov\t[sep4], al\n"
+"\tjmp\t.arg\n"
+msgstr ""
+".e:\n"
+"\tcmp\tal, 'e'\n"
+"\tjne\tnear usage\n"
+"\tor\tah, ah\n"
+"\tjne\tnear usage\n"
+"\tmov\tal, ','\n"
+"\tmov\t[huhmsg], al\n"
+"\tmov\t[separ], al\n"
+"\tmov\t[sep2], al\n"
+"\tmov\t[sep3], al\n"
+"\tmov\t[sep4], al\n"
+"\tjmp\t.arg\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3560
+#, no-wrap
+msgid ""
+"align 4\n"
+".getenv:\n"
+"\t; If ESI = 0, we did not have a -p argument,\n"
+"\t; and need to check the environment for \"PINHOLE=\"\n"
+"\tor\tesi, esi\n"
+"\tjne\t.init\n"
+msgstr ""
+"align 4\n"
+".getenv:\n"
+"\t; If ESI = 0, we did not have a -p argument,\n"
+"\t; and need to check the environment for \"PINHOLE=\"\n"
+"\tor\tesi, esi\n"
+"\tjne\t.init\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3562
+#, no-wrap
+msgid "\tsub\tecx, ecx\n"
+msgstr "\tsub\tecx, ecx\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3567
+#, no-wrap
+msgid ""
+".nextenv:\n"
+"\tpop\tesi\n"
+"\tor\tesi, esi\n"
+"\tje\t.default\t; no PINHOLE envar found\n"
+msgstr ""
+".nextenv:\n"
+"\tpop\tesi\n"
+"\tor\tesi, esi\n"
+"\tje\t.default\t; no PINHOLE envar found\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3573
+#, no-wrap
+msgid ""
+"\t; check if this envar starts with 'PINHOLE='\n"
+"\tmov\tedi, envar\n"
+"\tmov\tcl, 2\t\t; 'PINHOLE=' is 2 dwords long\n"
+"rep\tcmpsd\n"
+"\tjne\t.nextenv\n"
+msgstr ""
+"\t; check if this envar starts with 'PINHOLE='\n"
+"\tmov\tedi, envar\n"
+"\tmov\tcl, 2\t\t; 'PINHOLE=' is 2 dwords long\n"
+"rep\tcmpsd\n"
+"\tjne\t.nextenv\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3581
+#, no-wrap
+msgid ""
+"\t; Check if it is followed by a digit\n"
+"\tmov\tal, [esi]\n"
+"\tcmp\tal, '0'\n"
+"\tjl\t.default\n"
+"\tcmp\tal, '9'\n"
+"\tjbe\t.init\n"
+"\t; fall through\n"
+msgstr ""
+"\t; Check if it is followed by a digit\n"
+"\tmov\tal, [esi]\n"
+"\tcmp\tal, '0'\n"
+"\tjl\t.default\n"
+"\tcmp\tal, '9'\n"
+"\tjbe\t.init\n"
+"\t; fall through\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3588
+#, no-wrap
+msgid ""
+"align 4\n"
+".default:\n"
+"\t; We got here because we had no -p argument,\n"
+"\t; and did not find the PINHOLE envar.\n"
+"\tmov\tesi, pinhole\n"
+"\t; fall through\n"
+msgstr ""
+"align 4\n"
+".default:\n"
+"\t; We got here because we had no -p argument,\n"
+"\t; and did not find the PINHOLE envar.\n"
+"\tmov\tesi, pinhole\n"
+"\t; fall through\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3597
+#, no-wrap
+msgid ""
+"align 4\n"
+".init:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tsub\tedx, edx\n"
+"\tmov\tedi, dbuffer+1\n"
+"\tmov\tbyte [dbuffer], '0'\n"
+msgstr ""
+"align 4\n"
+".init:\n"
+"\tsub\teax, eax\n"
+"\tsub\tebx, ebx\n"
+"\tsub\tecx, ecx\n"
+"\tsub\tedx, edx\n"
+"\tmov\tedi, dbuffer+1\n"
+"\tmov\tbyte [dbuffer], '0'\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3606
+#, no-wrap
+msgid ""
+"\t; Convert the pinhole constant to real\n"
+".constloop:\n"
+"\tlodsb\n"
+"\tcmp\tal, '9'\n"
+"\tja\t.setconst\n"
+"\tcmp\tal, '0'\n"
+"\tje\t.processconst\n"
+"\tjb\t.setconst\n"
+msgstr ""
+"\t; Convert the pinhole constant to real\n"
+".constloop:\n"
+"\tlodsb\n"
+"\tcmp\tal, '9'\n"
+"\tja\t.setconst\n"
+"\tcmp\tal, '0'\n"
+"\tje\t.processconst\n"
+"\tjb\t.setconst\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3608
+#, no-wrap
+msgid "\tinc\tdl\n"
+msgstr "\tinc\tdl\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3615
+#, no-wrap
+msgid ""
+".processconst:\n"
+"\tinc\tcl\n"
+"\tcmp\tcl, 18\n"
+"\tja\tnear consttoobig\n"
+"\tstosb\n"
+"\tjmp\tshort .constloop\n"
+msgstr ""
+".processconst:\n"
+"\tinc\tcl\n"
+"\tcmp\tcl, 18\n"
+"\tja\tnear consttoobig\n"
+"\tstosb\n"
+"\tjmp\tshort .constloop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3620
+#, no-wrap
+msgid ""
+"align 4\n"
+".setconst:\n"
+"\tor\tdl, dl\n"
+"\tje\tnear perr\n"
+msgstr ""
+"align 4\n"
+".setconst:\n"
+"\tor\tdl, dl\n"
+"\tje\tnear perr\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3623
+#, no-wrap
+msgid ""
+"\tfinit\n"
+"\tfild\tdword [tthou]\n"
+msgstr ""
+"\tfinit\n"
+"\tfild\tdword [tthou]\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3627
+#, no-wrap
+msgid ""
+"\tfld1\n"
+"\tfild\tdword [ten]\n"
+"\tfdivp\tst1, st0\n"
+msgstr ""
+"\tfld1\n"
+"\tfild\tdword [ten]\n"
+"\tfdivp\tst1, st0\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3630
+#, no-wrap
+msgid ""
+"\tfild\tdword [thousand]\n"
+"\tmov\tedi, obuffer\n"
+msgstr ""
+"\tfild\tdword [thousand]\n"
+"\tmov\tedi, obuffer\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3633
+#, no-wrap
+msgid ""
+"\tmov\tebp, ecx\n"
+"\tcall\tbcdload\n"
+msgstr ""
+"\tmov\tebp, ecx\n"
+"\tcall\tbcdload\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3637
+#, no-wrap
+msgid ""
+".constdiv:\n"
+"\tfmul\tst0, st2\n"
+"\tloop\t.constdiv\n"
+msgstr ""
+".constdiv:\n"
+"\tfmul\tst0, st2\n"
+"\tloop\t.constdiv\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3644
+#, no-wrap
+msgid ""
+"\tfld1\n"
+"\tfadd\tst0, st0\n"
+"\tfadd\tst0, st0\n"
+"\tfld1\n"
+"\tfaddp\tst1, st0\n"
+"\tfchs\n"
+msgstr ""
+"\tfld1\n"
+"\tfadd\tst0, st0\n"
+"\tfadd\tst0, st0\n"
+"\tfld1\n"
+"\tfaddp\tst1, st0\n"
+"\tfchs\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3649
+#, no-wrap
+msgid ""
+"\t; If we are creating a CSV file,\n"
+"\t; print header\n"
+"\tcmp\tbyte [separ], ','\n"
+"\tjne\t.bigloop\n"
+msgstr ""
+"\t; If we are creating a CSV file,\n"
+"\t; print header\n"
+"\tcmp\tbyte [separ], ','\n"
+"\tjne\t.bigloop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3654
+#, no-wrap
+msgid ""
+"\tpush\tdword headlen\n"
+"\tpush\tdword header\n"
+"\tpush\tdword [fd.out]\n"
+"\tsys.write\n"
+msgstr ""
+"\tpush\tdword headlen\n"
+"\tpush\tdword header\n"
+"\tpush\tdword [fd.out]\n"
+"\tsys.write\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3658
+#, no-wrap
+msgid ""
+".bigloop:\n"
+"\tcall\tgetchar\n"
+"\tjc\tnear done\n"
+msgstr ""
+".bigloop:\n"
+"\tcall\tgetchar\n"
+"\tjc\tnear done\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3664
+#, no-wrap
+msgid ""
+"\t; Skip to the end of the line if you got '#'\n"
+"\tcmp\tal, '#'\n"
+"\tjne\t.num\n"
+"\tcall\tskiptoeol\n"
+"\tjmp\tshort .bigloop\n"
+msgstr ""
+"\t; Skip to the end of the line if you got '#'\n"
+"\tcmp\tal, '#'\n"
+"\tjne\t.num\n"
+"\tcall\tskiptoeol\n"
+"\tjmp\tshort .bigloop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3671
+#, no-wrap
+msgid ""
+".num:\n"
+"\t; See if you got a number\n"
+"\tcmp\tal, '0'\n"
+"\tjl\t.bigloop\n"
+"\tcmp\tal, '9'\n"
+"\tja\t.bigloop\n"
+msgstr ""
+".num:\n"
+"\t; See if you got a number\n"
+"\tcmp\tal, '0'\n"
+"\tjl\t.bigloop\n"
+"\tcmp\tal, '9'\n"
+"\tja\t.bigloop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3675
+#, no-wrap
+msgid ""
+"\t; Yes, we have a number\n"
+"\tsub\tebp, ebp\n"
+"\tsub\tedx, edx\n"
+msgstr ""
+"\t; Yes, we have a number\n"
+"\tsub\tebp, ebp\n"
+"\tsub\tedx, edx\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3680
+#, no-wrap
+msgid ""
+".number:\n"
+"\tcmp\tal, '0'\n"
+"\tje\t.number0\n"
+"\tmov\tdl, 1\n"
+msgstr ""
+".number:\n"
+"\tcmp\tal, '0'\n"
+"\tje\t.number0\n"
+"\tmov\tdl, 1\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3691
+#, no-wrap
+msgid ""
+".number0:\n"
+"\tor\tdl, dl\t\t; Skip leading 0's\n"
+"\tje\t.nextnumber\n"
+"\tpush\teax\n"
+"\tcall\tputchar\n"
+"\tpop\teax\n"
+"\tinc\tebp\n"
+"\tcmp\tebp, 19\n"
+"\tjae\t.nextnumber\n"
+"\tmov\t[dbuffer+ebp], al\n"
+msgstr ""
+".number0:\n"
+"\tor\tdl, dl\t\t; Skip leading 0's\n"
+"\tje\t.nextnumber\n"
+"\tpush\teax\n"
+"\tcall\tputchar\n"
+"\tpop\teax\n"
+"\tinc\tebp\n"
+"\tcmp\tebp, 19\n"
+"\tjae\t.nextnumber\n"
+"\tmov\t[dbuffer+ebp], al\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3702
+#, no-wrap
+msgid ""
+".nextnumber:\n"
+"\tcall\tgetchar\n"
+"\tjc\t.work\n"
+"\tcmp\tal, '#'\n"
+"\tje\t.ungetc\n"
+"\tcmp\tal, '0'\n"
+"\tjl\t.work\n"
+"\tcmp\tal, '9'\n"
+"\tja\t.work\n"
+"\tjmp\tshort .number\n"
+msgstr ""
+".nextnumber:\n"
+"\tcall\tgetchar\n"
+"\tjc\t.work\n"
+"\tcmp\tal, '#'\n"
+"\tje\t.ungetc\n"
+"\tcmp\tal, '0'\n"
+"\tjl\t.work\n"
+"\tcmp\tal, '9'\n"
+"\tja\t.work\n"
+"\tjmp\tshort .number\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3706
+#, no-wrap
+msgid ""
+".ungetc:\n"
+"\tdec\tesi\n"
+"\tinc\tebx\n"
+msgstr ""
+".ungetc:\n"
+"\tdec\tesi\n"
+"\tinc\tebx\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3711
+#, no-wrap
+msgid ""
+".work:\n"
+"\t; Now, do all the work\n"
+"\tor\tdl, dl\n"
+"\tje\tnear .work0\n"
+msgstr ""
+".work:\n"
+"\t; Now, do all the work\n"
+"\tor\tdl, dl\n"
+"\tje\tnear .work0\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3714
+#, no-wrap
+msgid ""
+"\tcmp\tebp, 19\n"
+"\tjae\tnear .toobig\n"
+msgstr ""
+"\tcmp\tebp, 19\n"
+"\tjae\tnear .toobig\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3716
+#, no-wrap
+msgid "\tcall\tbcdload\n"
+msgstr "\tcall\tbcdload\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3718
+#, no-wrap
+msgid "\t; Calculate pinhole diameter\n"
+msgstr "\t; Calculate pinhole diameter\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3725
+#, no-wrap
+msgid ""
+"\tfld\tst0\t; save it\n"
+"\tfsqrt\n"
+"\tfmul\tst0, st3\n"
+"\tfld\tst0\n"
+"\tfmul\tst5\n"
+"\tsub\tebp, ebp\n"
+msgstr ""
+"\tfld\tst0\t; save it\n"
+"\tfsqrt\n"
+"\tfmul\tst0, st3\n"
+"\tfld\tst0\n"
+"\tfmul\tst5\n"
+"\tsub\tebp, ebp\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3735
+#, no-wrap
+msgid ""
+"\t; Round off to 4 significant digits\n"
+".diameter:\n"
+"\tfcom\tst0, st7\n"
+"\tfstsw\tax\n"
+"\tsahf\n"
+"\tjb\t.printdiameter\n"
+"\tfmul\tst0, st6\n"
+"\tinc\tebp\n"
+"\tjmp\tshort .diameter\n"
+msgstr ""
+"\t; Round off to 4 significant digits\n"
+".diameter:\n"
+"\tfcom\tst0, st7\n"
+"\tfstsw\tax\n"
+"\tsahf\n"
+"\tjb\t.printdiameter\n"
+"\tfmul\tst0, st6\n"
+"\tinc\tebp\n"
+"\tjmp\tshort .diameter\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3738
+#, no-wrap
+msgid ""
+".printdiameter:\n"
+"\tcall\tprintnumber\t; pinhole diameter\n"
+msgstr ""
+".printdiameter:\n"
+"\tcall\tprintnumber\t; pinhole diameter\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3740
+#, no-wrap
+msgid "\t; Calculate F-number\n"
+msgstr "\t; Calculate F-number\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3743
+#, no-wrap
+msgid ""
+"\tfdivp\tst1, st0\n"
+"\tfld\tst0\n"
+msgstr ""
+"\tfdivp\tst1, st0\n"
+"\tfld\tst0\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3745
+#, no-wrap
+msgid "\tsub\tebp, ebp\n"
+msgstr "\tsub\tebp, ebp\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3754
+#, no-wrap
+msgid ""
+".fnumber:\n"
+"\tfcom\tst0, st6\n"
+"\tfstsw\tax\n"
+"\tsahf\n"
+"\tjb\t.printfnumber\n"
+"\tfmul\tst0, st5\n"
+"\tinc\tebp\n"
+"\tjmp\tshort .fnumber\n"
+msgstr ""
+".fnumber:\n"
+"\tfcom\tst0, st6\n"
+"\tfstsw\tax\n"
+"\tsahf\n"
+"\tjb\t.printfnumber\n"
+"\tfmul\tst0, st5\n"
+"\tinc\tebp\n"
+"\tjmp\tshort .fnumber\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3757
+#, no-wrap
+msgid ""
+".printfnumber:\n"
+"\tcall\tprintnumber\t; F number\n"
+msgstr ""
+".printfnumber:\n"
+"\tcall\tprintnumber\t; F number\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3768
+#, no-wrap
+msgid ""
+"\t; Calculate normalized F-number\n"
+"\tfmul\tst0, st0\n"
+"\tfld1\n"
+"\tfld\tst1\n"
+"\tfyl2x\n"
+"\tfrndint\n"
+"\tfld1\n"
+"\tfscale\n"
+"\tfsqrt\n"
+"\tfstp\tst1\n"
+msgstr ""
+"\t; Calculate normalized F-number\n"
+"\tfmul\tst0, st0\n"
+"\tfld1\n"
+"\tfld\tst1\n"
+"\tfyl2x\n"
+"\tfrndint\n"
+"\tfld1\n"
+"\tfscale\n"
+"\tfsqrt\n"
+"\tfstp\tst1\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3771
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3799
+#, no-wrap
+msgid ""
+"\tsub\tebp, ebp\n"
+"\tcall\tprintnumber\n"
+msgstr ""
+"\tsub\tebp, ebp\n"
+"\tcall\tprintnumber\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3773
+#, no-wrap
+msgid "\t; Calculate time multiplier from F-5.6\n"
+msgstr "\t; Calculate time multiplier from F-5.6\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3776
+#, no-wrap
+msgid ""
+"\tfscale\n"
+"\tfld\tst0\n"
+msgstr ""
+"\tfscale\n"
+"\tfld\tst0\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3782
+#, no-wrap
+msgid ""
+"\t; Round off to 4 significant digits\n"
+".fmul:\n"
+"\tfcom\tst0, st6\n"
+"\tfstsw\tax\n"
+"\tsahf\n"
+msgstr ""
+"\t; Round off to 4 significant digits\n"
+".fmul:\n"
+"\tfcom\tst0, st6\n"
+"\tfstsw\tax\n"
+"\tsahf\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3787
+#, no-wrap
+msgid ""
+"\tjb\t.printfmul\n"
+"\tinc\tebp\n"
+"\tfmul\tst0, st5\n"
+"\tjmp\tshort .fmul\n"
+msgstr ""
+"\tjb\t.printfmul\n"
+"\tinc\tebp\n"
+"\tfmul\tst0, st5\n"
+"\tjmp\tshort .fmul\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3790
+#, no-wrap
+msgid ""
+".printfmul:\n"
+"\tcall\tprintnumber\t; F multiplier\n"
+msgstr ""
+".printfmul:\n"
+"\tcall\tprintnumber\t; F multiplier\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3792
+#, no-wrap
+msgid "\t; Calculate F-stops from 5.6\n"
+msgstr "\t; Calculate F-stops from 5.6\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3796
+#, no-wrap
+msgid ""
+"\tfld1\n"
+"\tfxch\tst1\n"
+"\tfyl2x\n"
+msgstr ""
+"\tfld1\n"
+"\tfxch\tst1\n"
+"\tfyl2x\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3803
+#, no-wrap
+msgid ""
+"\tmov\tal, 0Ah\n"
+"\tcall\tputchar\n"
+"\tjmp\t.bigloop\n"
+msgstr ""
+"\tmov\tal, 0Ah\n"
+"\tcall\tputchar\n"
+"\tjmp\t.bigloop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3807
+#, no-wrap
+msgid ""
+".work0:\n"
+"\tmov\tal, '0'\n"
+"\tcall\tputchar\n"
+msgstr ""
+".work0:\n"
+"\tmov\tal, '0'\n"
+"\tcall\tputchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3812
+#, no-wrap
+msgid ""
+"align 4\n"
+".toobig:\n"
+"\tcall\thuh\n"
+"\tjmp\t.bigloop\n"
+msgstr ""
+"align 4\n"
+".toobig:\n"
+"\tcall\thuh\n"
+"\tjmp\t.bigloop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3816
+#, no-wrap
+msgid ""
+"align 4\n"
+"done:\n"
+"\tcall\twrite\t\t; flush output buffer\n"
+msgstr ""
+"align 4\n"
+"done:\n"
+"\tcall\twrite\t\t; flush output buffer\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3825
+#, no-wrap
+msgid "\tfinit\n"
+msgstr "\tfinit\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3838
+#, no-wrap
+msgid ""
+"align 4\n"
+"skiptoeol:\n"
+"\t; Keep reading until you come to cr, lf, or eof\n"
+"\tcall\tgetchar\n"
+"\tjc\tdone\n"
+"\tcmp\tal, 0Ah\n"
+"\tjne\t.cr\n"
+"\tret\n"
+msgstr ""
+"align 4\n"
+"skiptoeol:\n"
+"\t; Keep reading until you come to cr, lf, or eof\n"
+"\tcall\tgetchar\n"
+"\tjc\tdone\n"
+"\tcmp\tal, 0Ah\n"
+"\tjne\t.cr\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3843
+#, no-wrap
+msgid ""
+".cr:\n"
+"\tcmp\tal, 0Dh\n"
+"\tjne\tskiptoeol\n"
+"\tret\n"
+msgstr ""
+".cr:\n"
+"\tcmp\tal, 0Dh\n"
+"\tjne\tskiptoeol\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3856
+#, no-wrap
+msgid ""
+".fetch:\n"
+"\tlodsb\n"
+"\tdec\tebx\n"
+"\tclc\n"
+"\tret\n"
+msgstr ""
+".fetch:\n"
+"\tlodsb\n"
+"\tdec\tebx\n"
+"\tclc\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3873
+#, no-wrap
+msgid ""
+".read:\n"
+"\tpush\tdword BUFSIZE\n"
+"\tmov\tesi, ibuffer\n"
+"\tpush\tesi\n"
+"\tpush\tdword [fd.in]\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tmov\tebx, eax\n"
+"\tor\teax, eax\n"
+"\tje\t.empty\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+msgstr ""
+".read:\n"
+"\tpush\tdword BUFSIZE\n"
+"\tmov\tesi, ibuffer\n"
+"\tpush\tesi\n"
+"\tpush\tdword [fd.in]\n"
+"\tsys.read\n"
+"\tadd\tesp, byte 12\n"
+"\tmov\tebx, eax\n"
+"\tor\teax, eax\n"
+"\tje\t.empty\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3879
+#, no-wrap
+msgid ""
+"align 4\n"
+".empty:\n"
+"\tadd\tesp, byte 4\n"
+"\tstc\n"
+"\tret\n"
+msgstr ""
+"align 4\n"
+".empty:\n"
+"\tadd\tesp, byte 4\n"
+"\tstc\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3908
+#, no-wrap
+msgid ""
+"align 4\n"
+"bcdload:\n"
+"\t; EBP contains the number of chars in dbuffer\n"
+"\tpush\tecx\n"
+"\tpush\tesi\n"
+"\tpush\tedi\n"
+msgstr ""
+"align 4\n"
+"bcdload:\n"
+"\t; EBP contains the number of chars in dbuffer\n"
+"\tpush\tecx\n"
+"\tpush\tesi\n"
+"\tpush\tedi\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3912
+#, no-wrap
+msgid ""
+"\tlea\tecx, [ebp+1]\n"
+"\tlea\tesi, [dbuffer+ebp-1]\n"
+"\tshr\tecx, 1\n"
+msgstr ""
+"\tlea\tecx, [ebp+1]\n"
+"\tlea\tesi, [dbuffer+ebp-1]\n"
+"\tshr\tecx, 1\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3914
+#, no-wrap
+msgid "\tstd\n"
+msgstr "\tstd\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3920
+#, no-wrap
+msgid ""
+"\tmov\tedi, bbuffer\n"
+"\tsub\teax, eax\n"
+"\tmov\t[edi], eax\n"
+"\tmov\t[edi+4], eax\n"
+"\tmov\t[edi+2], ax\n"
+msgstr ""
+"\tmov\tedi, bbuffer\n"
+"\tsub\teax, eax\n"
+"\tmov\t[edi], eax\n"
+"\tmov\t[edi+4], eax\n"
+"\tmov\t[edi+2], ax\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3929
+#, no-wrap
+msgid ""
+".loop:\n"
+"\tlodsw\n"
+"\tsub\tax, 3030h\n"
+"\tshl\tal, 4\n"
+"\tor\tal, ah\n"
+"\tmov\t[edi], al\n"
+"\tinc\tedi\n"
+"\tloop\t.loop\n"
+msgstr ""
+".loop:\n"
+"\tlodsw\n"
+"\tsub\tax, 3030h\n"
+"\tshl\tal, 4\n"
+"\tor\tal, ah\n"
+"\tmov\t[edi], al\n"
+"\tinc\tedi\n"
+"\tloop\t.loop\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3931
+#, no-wrap
+msgid "\tfbld\t[bbuffer]\n"
+msgstr "\tfbld\t[bbuffer]\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3938
+#, no-wrap
+msgid ""
+"\tcld\n"
+"\tpop\tedi\n"
+"\tpop\tesi\n"
+"\tpop\tecx\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+msgstr ""
+"\tcld\n"
+"\tpop\tedi\n"
+"\tpop\tesi\n"
+"\tpop\tecx\n"
+"\tsub\teax, eax\n"
+"\tret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3944
+#, no-wrap
+msgid ""
+"align 4\n"
+"printnumber:\n"
+"\tpush\tebp\n"
+"\tmov\tal, [separ]\n"
+"\tcall\tputchar\n"
+msgstr ""
+"align 4\n"
+"printnumber:\n"
+"\tpush\tebp\n"
+"\tmov\tal, [separ]\n"
+"\tcall\tputchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3948
+#, no-wrap
+msgid ""
+"\t; Print the integer at the TOS\n"
+"\tmov\tebp, bbuffer+9\n"
+"\tfbstp\t[bbuffer]\n"
+msgstr ""
+"\t; Print the integer at the TOS\n"
+"\tmov\tebp, bbuffer+9\n"
+"\tfbstp\t[bbuffer]\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3954
+#, no-wrap
+msgid ""
+"\t; Check the sign\n"
+"\tmov\tal, [ebp]\n"
+"\tdec\tebp\n"
+"\tor\tal, al\n"
+"\tjns\t.leading\n"
+msgstr ""
+"\t; Check the sign\n"
+"\tmov\tal, [ebp]\n"
+"\tdec\tebp\n"
+"\tor\tal, al\n"
+"\tjns\t.leading\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3958
+#, no-wrap
+msgid ""
+"\t; We got a negative number (should never happen)\n"
+"\tmov\tal, '-'\n"
+"\tcall\tputchar\n"
+msgstr ""
+"\t; We got a negative number (should never happen)\n"
+"\tmov\tal, '-'\n"
+"\tcall\tputchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3967
+#, no-wrap
+msgid ""
+".leading:\n"
+"\t; Skip leading zeros\n"
+"\tmov\tal, [ebp]\n"
+"\tdec\tebp\n"
+"\tor\tal, al\n"
+"\tjne\t.first\n"
+"\tcmp\tebp, bbuffer\n"
+"\tjae\t.leading\n"
+msgstr ""
+".leading:\n"
+"\t; Skip leading zeros\n"
+"\tmov\tal, [ebp]\n"
+"\tdec\tebp\n"
+"\tor\tal, al\n"
+"\tjne\t.first\n"
+"\tcmp\tebp, bbuffer\n"
+"\tjae\t.leading\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3972
+#, no-wrap
+msgid ""
+"\t; We are here because the result was 0.\n"
+"\t; Print '0' and return\n"
+"\tmov\tal, '0'\n"
+"\tjmp\tputchar\n"
+msgstr ""
+"\t; We are here because the result was 0.\n"
+"\t; Print '0' and return\n"
+"\tmov\tal, '0'\n"
+"\tjmp\tputchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3984
+#, no-wrap
+msgid ""
+".first:\n"
+"\t; We have found the first non-zero.\n"
+"\t; But it is still packed\n"
+"\ttest\tal, 0F0h\n"
+"\tjz\t.second\n"
+"\tpush\teax\n"
+"\tshr\tal, 4\n"
+"\tadd\tal, '0'\n"
+"\tcall\tputchar\n"
+"\tpop\teax\n"
+"\tand\tal, 0Fh\n"
+msgstr ""
+".first:\n"
+"\t; We have found the first non-zero.\n"
+"\t; But it is still packed\n"
+"\ttest\tal, 0F0h\n"
+"\tjz\t.second\n"
+"\tpush\teax\n"
+"\tshr\tal, 4\n"
+"\tadd\tal, '0'\n"
+"\tcall\tputchar\n"
+"\tpop\teax\n"
+"\tand\tal, 0Fh\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3988
+#, no-wrap
+msgid ""
+".second:\n"
+"\tadd\tal, '0'\n"
+"\tcall\tputchar\n"
+msgstr ""
+".second:\n"
+"\tadd\tal, '0'\n"
+"\tcall\tputchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:3992
+#, no-wrap
+msgid ""
+".next:\n"
+"\tcmp\tebp, bbuffer\n"
+"\tjb\t.done\n"
+msgstr ""
+".next:\n"
+"\tcmp\tebp, bbuffer\n"
+"\tjb\t.done\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4002
+#, no-wrap
+msgid ""
+"\tmov\tal, [ebp]\n"
+"\tpush\teax\n"
+"\tshr\tal, 4\n"
+"\tadd\tal, '0'\n"
+"\tcall\tputchar\n"
+"\tpop\teax\n"
+"\tand\tal, 0Fh\n"
+"\tadd\tal, '0'\n"
+"\tcall\tputchar\n"
+msgstr ""
+"\tmov\tal, [ebp]\n"
+"\tpush\teax\n"
+"\tshr\tal, 4\n"
+"\tadd\tal, '0'\n"
+"\tcall\tputchar\n"
+"\tpop\teax\n"
+"\tand\tal, 0Fh\n"
+"\tadd\tal, '0'\n"
+"\tcall\tputchar\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4005
+#, no-wrap
+msgid ""
+"\tdec\tebp\n"
+"\tjmp\tshort .next\n"
+msgstr ""
+"\tdec\tebp\n"
+"\tjmp\tshort .next\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4010
+#, no-wrap
+msgid ""
+".done:\n"
+"\tpop\tebp\n"
+"\tor\tebp, ebp\n"
+"\tje\t.ret\n"
+msgstr ""
+".done:\n"
+"\tpop\tebp\n"
+"\tor\tebp, ebp\n"
+"\tje\t.ret\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4016
+#, no-wrap
+msgid ""
+".zeros:\n"
+"\tmov\tal, '0'\n"
+"\tcall\tputchar\n"
+"\tdec\tebp\n"
+"\tjne\t.zeros\n"
+msgstr ""
+".zeros:\n"
+"\tmov\tal, '0'\n"
+"\tcall\tputchar\n"
+"\tdec\tebp\n"
+"\tjne\t.zeros\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4019
+#, no-wrap
+msgid ""
+".ret:\n"
+"\tret\n"
+msgstr ""
+".ret:\n"
+"\tret\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4022
+msgid ""
+"The code follows the same format as all the other filters we have seen "
+"before, with one subtle exception:"
+msgstr ""
+"Код следует тому же формату, что и все остальные фильтры, которые мы видели "
+"ранее, с одним небольшим исключением:"
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4025
+msgid ""
+"We are no longer assuming that the end of input implies the end of things to "
+"do, something we took for granted in the _character-oriented_ filters."
+msgstr ""
+"Мы больше не предполагаем, что конец ввода означает конец задач, как мы "
+"привыкли в фильтрах, _ориентированных на символы_."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4027
+msgid ""
+"This filter does not process characters. It processes a _language_ (albeit a "
+"very simple one, consisting only of numbers)."
+msgstr ""
+"Этот фильтр не обрабатывает символы. Он обрабатывает _язык_ (хотя и очень "
+"простой, состоящий только из чисел)."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4029
+msgid "When we have no more input, it can mean one of two things:"
+msgstr ""
+"Когда у нас больше нет входных данных, это может означать одно из двух:"
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4031
+msgid "We are done and can quit. This is the same as before."
+msgstr "Мы закончили и можем выйти. Это то же самое, что и раньше."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4032
+msgid ""
+"The last character we have read was a digit. We have stored it at the end of "
+"our ASCII-to-float conversion buffer. We now need to convert the contents of "
+"that buffer into a number and write the last line of our output."
+msgstr ""
+"Последний прочитанный символ был цифрой. Мы сохранили его в конце буфера "
+"преобразования ASCII в число с плавающей точкой. Теперь нам нужно "
+"преобразовать содержимое этого буфера в число и записать последнюю строку "
+"нашего вывода."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4034
+msgid ""
+"For that reason, we have modified our `getchar` and our `read` routines to "
+"return with the `carry flag` _clear_ whenever we are fetching another "
+"character from the input, or the `carry flag` _set_ whenever there is no "
+"more input."
+msgstr ""
+"По этой причине мы изменили наши подпрограммы `getchar` и `read`, чтобы они "
+"возвращались с _сброшенным_ флагом `carry`, когда получают очередной символ "
+"из ввода, или с _установленным_ флагом `carry`, когда ввода больше нет."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4037
+msgid ""
+"Of course, we are still using assembly language magic to do that! Take a "
+"good look at `getchar`. It _always_ returns with the `carry flag` _clear_."
+msgstr ""
+"Конечно, мы по-прежнему используем магию ассемблера для этого! Внимательно "
+"посмотрите на `getchar`. Он _всегда_ возвращает _очищенный_ `флаг переноса`."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4039
+msgid ""
+"Yet, our main code relies on the `carry flag` to tell it when to quit-and it "
+"works."
+msgstr ""
+"Тем не менее, наш основной код использует `флаг переноса` для определения "
+"момента завершения — и это работает."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4042
+msgid ""
+"The magic is in `read`. Whenever it receives more input from the system, it "
+"just returns to `getchar`, which fetches a character from the input buffer, "
+"_clears_ the `carry flag` and returns."
+msgstr ""
+"Волшебство кроется в `read`. Каждый раз, когда он получает больше входных "
+"данных от системы, он просто возвращается к `getchar`, который извлекает "
+"символ из входного буфера, _сбрасывает_ флаг переноса (`carry flag`) и "
+"возвращает управление."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4045
+msgid ""
+"But when `read` receives no more input from the system, it does _not_ return "
+"to `getchar` at all. Instead, the `add esp, byte 4` op code adds `4` to "
+"`ESP`, _sets_ the `carry flag`, and returns."
+msgstr ""
+"Но когда `read` больше не получает входных данных от системы, он _не_ "
+"возвращается к `getchar` вообще. Вместо этого, инструкция `add esp, byte 4` "
+"добавляет `4` к `ESP`, _устанавливает_ флаг переноса (`carry flag`) и "
+"возвращает управление."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4049
+msgid ""
+"So, where does it return to? Whenever a program uses the `call` op code, the "
+"microprocessor ``push``es the return address, i.e., it stores it on the top "
+"of the stack (not the FPU stack, the system stack, which is in the memory). "
+"When a program uses the `ret` op code, the microprocessor ``pop``s the "
+"return value from the stack, and jumps to the address that was stored there."
+msgstr ""
+"Итак, куда же она возвращается? Каждый раз, когда программа использует "
+"операцию `call`, микропроцессор делает ``push`` для адрес возврата, то есть "
+"сохраняет его на вершине стека (не стека FPU, а системного стека, который "
+"находится в памяти). Когда программа использует операцию `ret`, "
+"микропроцессор делает ``pop`` для значения возврата из стека и переходит по "
+"адресу, который там был сохранён."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4051
+msgid ""
+"But since we added `4` to `ESP` (which is the stack pointer register), we "
+"have effectively given the microprocessor a minor case of _amnesia_: It no "
+"longer remembers it was `getchar` that ``call``ed `read`."
+msgstr ""
+"Но поскольку мы добавили `4` к `ESP` (который является регистром указателя "
+"стека), мы фактически вызвали у микропроцессора лёгкий случай _амнезии_: он "
+"больше не помнит, что именно `getchar` ``вызвал`` `read`."
+
+#. type: delimited block _ 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4053
+msgid ""
+"And since `getchar` never ``push``ed anything before ``call``ing `read`, the "
+"top of the stack now contains the return address to whatever or whoever "
+"``call``ed `getchar`. As far as that caller is concerned, he ``call``ed "
+"`getchar`, which ``ret``urned with the `carry flag` set!"
+msgstr ""
+"И поскольку `getchar` не делал ``push`` ни для чего перед вызовом `read`, "
+"верхушка стека теперь содержит адрес возврата к тому, что или кто вызывал "
+"`getchar`. С точки зрения этого вызывающего, он вызывал `getchar`, который "
+"вызвал ``ret`` с установленным `флагом переноса`!"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4056
+msgid ""
+"Other than that, the `bcdload` routine is caught up in the middle of a "
+"Lilliputian conflict between the Big-Endians and the Little-Endians."
+msgstr ""
+"Помимо этого, процедура `bcdload` оказывается втянута в лилипутский конфликт "
+"между Биг-Эндианцами и Литл-Эндианцами."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4058
+msgid ""
+"It is converting the text representation of a number into that number: The "
+"text is stored in the big-endian order, but the _packed decimal_ is little-"
+"endian."
+msgstr ""
+"Он преобразует текстовое представление числа в само число: текст хранится в "
+"порядке big-endian, но _упакованный десятичный_ формат имеет порядок little-"
+"endian."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4061
+msgid ""
+"To solve the conflict, we use the `std` op code early on. We cancel it with "
+"`cld` later on: It is quite important we do not `call` anything that may "
+"depend on the default setting of the _direction flag_ while `std` is active."
+msgstr ""
+"Для разрешения конфликта мы используем инструкцию процессора `std` в самом "
+"начале. Позже мы отменяем его с помощью `cld`: очень важно не вызывать "
+"ничего, что может зависеть от стандартного значения _флага направления_, "
+"пока активен `std`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4063
+msgid ""
+"Everything else in this code should be quit eclear, providing you have read "
+"the entire chapter that precedes it."
+msgstr ""
+"Всё остальное в этом коде должно быть достаточно понятным, при условии, что "
+"вы прочитали всю предшествующую главу."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4066
+msgid ""
+"It is a classical example of the adage that programming requires a lot of "
+"thought and only a little coding. Once we have thought through every tiny "
+"detail, the code almost writes itself."
+msgstr ""
+"Это классический пример поговорки о том, что программирование требует много "
+"размышлений и лишь немного кодирования. Как только мы продумаем каждую "
+"мельчайшую деталь, код практически напишется сам."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4068
+#, no-wrap
+msgid "Using pinhole"
+msgstr "Использование программы pinhole"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4072
+msgid ""
+"Because we have decided to make the program _ignore_ any input except for "
+"numbers (and even those inside a comment), we can actually perform _textual "
+"queries_. We do not _have to_, but we _can_."
+msgstr ""
+"Поскольку мы решили сделать так, чтобы программа _игнорировала_ любой ввод, "
+"кроме чисел (и даже их внутри комментария), мы можем выполнять _текстовые "
+"запросы_. Мы не _обязаны_ этого делать, но _можем_."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4074
+msgid ""
+"In my humble opinion, forming a textual query, instead of having to follow a "
+"very strict syntax, makes software much more user friendly."
+msgstr ""
+"По моему скромному мнению, формирование текстового запроса вместо "
+"необходимости следовать очень строгому синтаксису делает программное "
+"обеспечение гораздо более дружелюбным к пользователю."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4080
+msgid ""
+"Suppose we want to build a pinhole camera to use the 4x5 inch film. The "
+"standard focal length for that film is about 150mm. We want to _fine-tune_ "
+"our focal length so the pinhole diameter is as round a number as possible. "
+"Let us also suppose we are quite comfortable with cameras but somewhat "
+"intimidated by computers. Rather than just have to type in a bunch of "
+"numbers, we want to _ask_ a couple of questions."
+msgstr ""
+"Предположим, мы хотим построить камеру-обскуру для использования плёнки "
+"размером 4x5 дюймов. Стандартное фокусное расстояние для такой плёнки "
+"составляет около 150 мм. Мы хотим _точно настроить_ фокусное расстояние, "
+"чтобы диаметр отверстия был как можно более круглым числом. Допустим также, "
+"что мы хорошо разбираемся в фотоаппаратах, но немного боимся компьютеров. "
+"Вместо того чтобы просто вводить кучу цифр, мы хотим _задать_ пару вопросов."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4082
+msgid "Our session might look like this:"
+msgstr "Наша сессия может выглядеть так:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4086
+#, no-wrap
+msgid "% pinhole\n"
+msgstr "% pinhole\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4088
+#, no-wrap
+msgid "Computer,\n"
+msgstr "Computer,\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4101
+#, no-wrap
+msgid ""
+"What size pinhole do I need for the focal length of 150?\n"
+"150\t490\t306\t362\t2930\t12\n"
+"Hmmm... How about 160?\n"
+"160\t506\t316\t362\t3125\t12\n"
+"Let's make it 155, please.\n"
+"155\t498\t311\t362\t3027\t12\n"
+"Ah, let's try 157...\n"
+"157\t501\t313\t362\t3066\t12\n"
+"156?\n"
+"156\t500\t312\t362\t3047\t12\n"
+"That's it! Perfect! Thank you very much!\n"
+"^D\n"
+msgstr ""
+"What size pinhole do I need for the focal length of 150?\n"
+"150\t490\t306\t362\t2930\t12\n"
+"Hmmm... How about 160?\n"
+"160\t506\t316\t362\t3125\t12\n"
+"Let's make it 155, please.\n"
+"155\t498\t311\t362\t3027\t12\n"
+"Ah, let's try 157...\n"
+"157\t501\t313\t362\t3066\t12\n"
+"156?\n"
+"156\t500\t312\t362\t3047\t12\n"
+"That's it! Perfect! Thank you very much!\n"
+"^D\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4104
+msgid ""
+"We have found that while for the focal length of 150, our pinhole diameter "
+"should be 490 microns, or 0.49 mm, if we go with the almost identical focal "
+"length of 156 mm, we can get away with a pinhole diameter of exactly one "
+"half of a millimeter."
+msgstr ""
+"Мы выяснили, что при фокусном расстоянии 150 мм диаметр отверстия должен "
+"составлять 490 микрон, или 0,49 мм, но если взять почти идентичное фокусное "
+"расстояние 156 мм, можно использовать отверстие диаметром ровно половину "
+"миллиметра."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4106
+#, no-wrap
+msgid "Scripting"
+msgstr "Скриптинг"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4109
+msgid ""
+"Because we have chosen the `+#+` character to denote the start of a comment, "
+"we can treat our pinhole software as a _scripting language_."
+msgstr ""
+"Поскольку мы выбрали символ `+#+` для обозначения начала комментария, мы "
+"можем рассматривать наше программное обеспечение pinhole как _скриптовый "
+"язык_."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4111
+msgid "You have probably seen shell _scripts_ that start with:"
+msgstr "Вы, вероятно, видели _сценарии_ оболочки, которые начинаются с:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4115
+#, no-wrap
+msgid "#! /bin/sh\n"
+msgstr "#! /bin/sh\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4118
+msgid "...or..."
+msgstr "...или..."
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4122
+#, no-wrap
+msgid "#!/bin/sh\n"
+msgstr "#!/bin/sh\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4125
+msgid "...because the blank space after the `#!` is optional."
+msgstr "...потому что пробел после `#!` необязателен."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4128
+msgid ""
+"Whenever UNIX(R) is asked to run an executable file which starts with the `#!"
+"`, it assumes the file is a script. It adds the command to the rest of the "
+"first line of the script, and tries to execute that."
+msgstr ""
+"Когда UNIX(R) получает запрос на выполнение исполняемого файла, который "
+"начинается с `#!`, он предполагает, что это скрипт. Он добавляет команду к "
+"остальной части первой строки скрипта и пытается выполнить её."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4130
+msgid ""
+"Suppose now that we have installed pinhole in /usr/local/bin/, we can now "
+"write a script to calculate various pinhole diameters suitable for various "
+"focal lengths commonly used with the 120 film."
+msgstr ""
+"Предположим, что мы установили pinhole в /usr/local/bin/, теперь мы можем "
+"написать скрипт для расчёта различных диаметров отверстий, подходящих для "
+"различных фокусных расстояний, обычно используемых с плёнкой 120."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4132
+msgid "The script might look something like this:"
+msgstr "Скрипт может выглядеть примерно так:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4138
+#, no-wrap
+msgid ""
+"#! /usr/local/bin/pinhole -b -i\n"
+"# Find the best pinhole diameter\n"
+"# for the 120 film\n"
+msgstr ""
+"#! /usr/local/bin/pinhole -b -i\n"
+"# Find the best pinhole diameter\n"
+"# for the 120 film\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4141
+#, no-wrap
+msgid ""
+"### Standard\n"
+"80\n"
+msgstr ""
+"### Standard\n"
+"80\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4144
+#, no-wrap
+msgid ""
+"### Wide angle\n"
+"30, 40, 50, 60, 70\n"
+msgstr ""
+"### Wide angle\n"
+"30, 40, 50, 60, 70\n"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4147
+#, no-wrap
+msgid ""
+"### Telephoto\n"
+"100, 120, 140\n"
+msgstr ""
+"### Telephoto\n"
+"100, 120, 140\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4150
+msgid "Because 120 is a medium size film, we may name this file medium."
+msgstr ""
+"Поскольку 120 — это плёнка среднего размера, мы можем назвать этот файл "
+"`medium`."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4152
+msgid ""
+"We can set its permissions to execute, and run it as if it were a program:"
+msgstr ""
+"Мы можем установить права на выполнение и запустить его, как если бы это "
+"была программа:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4157
+#, no-wrap
+msgid ""
+"% chmod 755 medium\n"
+"% ./medium\n"
+msgstr ""
+"% chmod 755 medium\n"
+"% ./medium\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4160
+msgid "UNIX(R) will interpret that last command as:"
+msgstr "UNIX(R) интерпретирует последнюю команду следующим образом:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4164
+#, no-wrap
+msgid "% /usr/local/bin/pinhole -b -i ./medium\n"
+msgstr "% /usr/local/bin/pinhole -b -i ./medium\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4167
+msgid "It will run that command and display:"
+msgstr "Он выполнит эту команду и отобразит:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4179
+#, no-wrap
+msgid ""
+"80\t358\t224\t256\t1562\t11\n"
+"30\t219\t137\t128\t586\t9\n"
+"40\t253\t158\t181\t781\t10\n"
+"50\t283\t177\t181\t977\t10\n"
+"60\t310\t194\t181\t1172\t10\n"
+"70\t335\t209\t181\t1367\t10\n"
+"100\t400\t250\t256\t1953\t11\n"
+"120\t438\t274\t256\t2344\t11\n"
+"140\t473\t296\t256\t2734\t11\n"
+msgstr ""
+"80\t358\t224\t256\t1562\t11\n"
+"30\t219\t137\t128\t586\t9\n"
+"40\t253\t158\t181\t781\t10\n"
+"50\t283\t177\t181\t977\t10\n"
+"60\t310\t194\t181\t1172\t10\n"
+"70\t335\t209\t181\t1367\t10\n"
+"100\t400\t250\t256\t1953\t11\n"
+"120\t438\t274\t256\t2344\t11\n"
+"140\t473\t296\t256\t2734\t11\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4182
+msgid "Now, let us enter:"
+msgstr "Теперь введем:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4186
+#, no-wrap
+msgid "% ./medium -c\n"
+msgstr "% ./medium -c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4189
+msgid "UNIX(R) will treat that as:"
+msgstr "UNIX(R) интерпретирует это следующим образом:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4193
+#, no-wrap
+msgid "% /usr/local/bin/pinhole -b -i ./medium -c\n"
+msgstr "% /usr/local/bin/pinhole -b -i ./medium -c\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4197
+msgid ""
+"That gives it two conflicting options: `-b` and `-c` (Use Bender's constant "
+"and use Connors' constant). We have programmed it so later options override "
+"early ones-our program will calculate everything using Connors' constant:"
+msgstr ""
+"Это дает ему два конфликтующих параметра: `-b` и `-c` (Использовать "
+"константу Бендера и использовать константу Коннорса). Мы запрограммировали "
+"его так, что более поздние параметры переопределяют ранние — наша программа "
+"будет вычислять все, используя константу Коннорса:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4209
+#, no-wrap
+msgid ""
+"80\t331\t242\t256\t1826\t11\n"
+"30\t203\t148\t128\t685\t9\n"
+"40\t234\t171\t181\t913\t10\n"
+"50\t262\t191\t181\t1141\t10\n"
+"60\t287\t209\t181\t1370\t10\n"
+"70\t310\t226\t256\t1598\t11\n"
+"100\t370\t270\t256\t2283\t11\n"
+"120\t405\t296\t256\t2739\t11\n"
+"140\t438\t320\t362\t3196\t12\n"
+msgstr ""
+"80\t331\t242\t256\t1826\t11\n"
+"30\t203\t148\t128\t685\t9\n"
+"40\t234\t171\t181\t913\t10\n"
+"50\t262\t191\t181\t1141\t10\n"
+"60\t287\t209\t181\t1370\t10\n"
+"70\t310\t226\t256\t1598\t11\n"
+"100\t370\t270\t256\t2283\t11\n"
+"120\t405\t296\t256\t2739\t11\n"
+"140\t438\t320\t362\t3196\t12\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4213
+msgid ""
+"We decide we want to go with Bender's constant after all. We want to save "
+"its values as a comma-separated file:"
+msgstr ""
+"Мы решаем, что всё же выбираем константу Бендера. Мы хотим сохранить её "
+"значения в виде файла с разделителями-запятыми:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4229
+#, no-wrap
+msgid ""
+"% ./medium -b -e > bender\n"
+"% cat bender\n"
+"focal length in millimeters,pinhole diameter in microns,F-number,normalized F-number,F-5.6 multiplier,stops from F-5.6\n"
+"80,358,224,256,1562,11\n"
+"30,219,137,128,586,9\n"
+"40,253,158,181,781,10\n"
+"50,283,177,181,977,10\n"
+"60,310,194,181,1172,10\n"
+"70,335,209,181,1367,10\n"
+"100,400,250,256,1953,11\n"
+"120,438,274,256,2344,11\n"
+"140,473,296,256,2734,11\n"
+"%\n"
+msgstr ""
+"% ./medium -b -e > bender\n"
+"% cat bender\n"
+"focal length in millimeters,pinhole diameter in microns,F-number,normalized F-number,F-5.6 multiplier,stops from F-5.6\n"
+"80,358,224,256,1562,11\n"
+"30,219,137,128,586,9\n"
+"40,253,158,181,781,10\n"
+"50,283,177,181,977,10\n"
+"60,310,194,181,1172,10\n"
+"70,335,209,181,1367,10\n"
+"100,400,250,256,1953,11\n"
+"120,438,274,256,2344,11\n"
+"140,473,296,256,2734,11\n"
+"%\n"
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4232
+#, no-wrap
+msgid "Caveats"
+msgstr "Предостережения"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4236
+msgid ""
+"Assembly language programmers who \"grew up\" under MS-DOS(R) and Windows(R) "
+"often tend to take shortcuts. Reading the keyboard scan codes and writing "
+"directly to video memory are two classical examples of practices which, "
+"under MS-DOS(R) are not frowned upon but considered the right thing to do."
+msgstr ""
+"Программисты на ассемблере, которые \"выросли\" на MS-DOS(R) и Windows(R), "
+"часто склонны искать короткие пути. Чтение скан-кодов клавиатуры и запись "
+"напрямую в видеопамять — это два классических примера подходов, которые в MS-"
+"DOS(R) не только не порицаются, но и считаются правильными."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4238
+msgid ""
+"The reason? Both the PC BIOS and MS-DOS(R) are notoriously slow when "
+"performing these operations."
+msgstr ""
+"Причина? И BIOS ПК, и MS-DOS(R) печально известны своей медленной работой "
+"при выполнении этих операций."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4241
+msgid ""
+"You may be tempted to continue similar practices in the UNIX(R) "
+"environment. For example, I have seen a web site which explains how to "
+"access the keyboard scan codes on a popular UNIX(R) clone."
+msgstr ""
+"Вас может возникнуть соблазн продолжить подобные практики в среде UNIX(R). "
+"Например, я видел веб-сайт, который объясняет, как получить доступ к скан-"
+"кодам клавиатуры на популярном клоне UNIX(R)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4243
+msgid ""
+"That is generally a _very bad idea_ in UNIX(R) environment! Let me explain "
+"why."
+msgstr ""
+"Это, как правило, *очень плохая идея* в среде UNIX(R)! Позвольте объяснить "
+"почему."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4245
+#, no-wrap
+msgid "UNIX(R) Is Protected"
+msgstr "UNIX(R) защищен"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4252
+msgid ""
+"For one thing, it may simply not be possible. UNIX(R) runs in protected "
+"mode. Only the kernel and device drivers are allowed to access hardware "
+"directly. Perhaps a particular UNIX(R) clone will let you read the keyboard "
+"scan codes, but chances are a real UNIX(R) operating system will not. And "
+"even if one version may let you do it, the next one may not, so your "
+"carefully crafted software may become a dinosaur overnight."
+msgstr ""
+"Прежде всего, это может быть просто невозможно. UNIX(R) работает в "
+"защищённом режиме. Только ядро и драйверы устройств имеют прямой доступ к "
+"аппаратному обеспечению. Возможно, какой-то конкретный клон UNIX(R) позволит "
+"вам читать скан-коды клавиатуры, но скорее всего настоящая операционная "
+"система UNIX(R) этого не допустит. И даже если одна версия разрешает это, "
+"следующая может запретить, так что ваше тщательно разработанное программное "
+"обеспечение может в одночасье устареть."
+
+#. type: Title ===
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4254
+#, no-wrap
+msgid "UNIX(R) Is an Abstraction"
+msgstr "UNIX(R) — это работа с абстракциями"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4257
+msgid ""
+"But there is a much more important reason not to try accessing the hardware "
+"directly (unless, of course, you are writing a device driver), even on the "
+"UNIX(R) like systems that let you do it:"
+msgstr ""
+"Но существует гораздо более важная причина не пытаться обращаться к "
+"оборудованию напрямую (если, конечно, вы не пишете драйвер устройства), даже "
+"в UNIX(R)-подобных системах, которые позволяют это делать:"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4259
+msgid "_UNIX(R) is an abstraction!_"
+msgstr "_UNIX(R) — это работа с абстракциями!_"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4265
+msgid ""
+"There is a major difference in the philosophy of design between MS-DOS(R) "
+"and UNIX(R). MS-DOS(R) was designed as a single-user system. It is run on "
+"a computer with a keyboard and a video screen attached directly to that "
+"computer. User input is almost guaranteed to come from that keyboard. Your "
+"program's output virtually always ends up on that screen."
+msgstr ""
+"Существует фундаментальное различие в философии проектирования между MS-"
+"DOS(R) и UNIX(R). MS-DOS(R) разрабатывалась как однопользовательская "
+"система. Она работает на компьютере, к которому напрямую подключены "
+"клавиатура и монитор. Ввод пользователя практически гарантированно поступает "
+"с этой клавиатуры. Вывод вашей программы почти всегда отображается на этом "
+"экране."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4268
+msgid ""
+"This is NEVER guaranteed under UNIX(R). It is quite common for a UNIX(R) "
+"user to pipe and redirect program input and output:"
+msgstr ""
+"Это НИКОГДА не гарантируется в UNIX(R). Довольно часто пользователь UNIX(R) "
+"перенаправляет ввод и вывод программы с помощью конвейеров и перенаправлений:"
+
+#. type: delimited block . 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4272
+#, no-wrap
+msgid "% program1 | program2 | program3 > file1\n"
+msgstr "% program1 | program2 | program3 > file1\n"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4276
+msgid ""
+"If you have written program2, your input does not come from the keyboard but "
+"from the output of program1. Similarly, your output does not go to the "
+"screen but becomes the input for program3 whose output, in turn, goes to [."
+"filename]#file1#."
+msgstr ""
+"Если вы написали program2, ваш ввод поступает не с клавиатуры, а из вывода "
+"program1. Аналогично, ваш вывод не выводится на экран, а становится вводом "
+"для program3, чей вывод, в свою очередь, отправляется в [.filename]#file1#."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4279
+msgid ""
+"But there is more! Even if you made sure that your input comes from, and "
+"your output goes to, the terminal, there is no guarantee the terminal is a "
+"PC: It may not have its video memory where you expect it, nor may its "
+"keyboard be producing PC-style scan codes. It may be a Macintosh(R), or any "
+"other computer."
+msgstr ""
+"Но это еще не все! Даже если вы убедились, что ваш ввод поступает с "
+"терминала, а вывод отправляется на терминал, нет гарантии, что терминал "
+"является ПК: его видеопамять может находиться не там, где вы ожидаете, а "
+"клавиатура может генерировать не PC-совместимые скан-коды. Это может быть "
+"Macintosh(R) или любой другой компьютер."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4281
+msgid ""
+"Now you may be shaking your head: My software is in PC assembly language, "
+"how can it run on a Macintosh(R)? But I did not say your software would be "
+"running on a Macintosh(R), only that its terminal may be a Macintosh(R)."
+msgstr ""
+"Вот вы, возможно, покачаете головой: мое программное обеспечение написано на "
+"языке ассемблера для ПК, как оно может работать на Macintosh(R)? Но я не "
+"говорил, что ваше программное обеспечение будет работать на Macintosh(R), а "
+"лишь что его терминалом может быть Macintosh(R)."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4285
+msgid ""
+"Under UNIX(R), the terminal does not have to be directly attached to the "
+"computer that runs your software, it can even be on another continent, or, "
+"for that matter, on another planet. It is perfectly possible that a "
+"Macintosh(R) user in Australia connects to a UNIX(R) system in North America "
+"(or anywhere else) via telnet. The software then runs on one computer, "
+"while the terminal is on a different computer: If you try to read the scan "
+"codes, you will get the wrong input!"
+msgstr ""
+"В UNIX(R) терминал не обязательно должен быть напрямую подключён к "
+"компьютеру, на котором работает ваше программное обеспечение — он может "
+"находиться даже на другом континенте или, например, на другой планете. "
+"Вполне возможно, что пользователь Macintosh(R) в Австралии подключается к "
+"системе UNIX(R) в Северной Америке (или где-либо ещё) через telnet. "
+"Программное обеспечение работает на одном компьютере, а терминал находится "
+"на другом: если попытаться считать скан-коды, будут получены неверные данные!"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4288
+msgid ""
+"Same holds true about any other hardware: A file you are reading may be on a "
+"disk you have no direct access to. A camera you are reading images from may "
+"be on a space shuttle, connected to you via satellites."
+msgstr ""
+"То же самое относится и к любому другому оборудованию: файл, который вы "
+"читаете, может находиться на диске, к которому у вас нет прямого доступа. "
+"Камера, с которой вы считываете изображения, может находиться на космическом "
+"корабле, соединённом с вами через спутники."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4291
+msgid ""
+"That is why under UNIX(R) you must never make any assumptions about where "
+"your data is coming from and going to. Always let the system handle the "
+"physical access to the hardware."
+msgstr ""
+"Вот почему в UNIX(R) никогда нельзя делать никаких предположений о том, "
+"откуда поступают ваши данные и куда они направляются. Всегда позволяйте "
+"системе управлять физическим доступом к оборудованию."
+
+#. type: delimited block = 4
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4299
+msgid ""
+"These are caveats, not absolute rules. Exceptions are possible. For "
+"example, if a text editor has determined it is running on a local machine, "
+"it may want to read the scan codes directly for improved control. I am not "
+"mentioning these caveats to tell you what to do or what not to do, just to "
+"make you aware of certain pitfalls that await you if you have just arrived "
+"to UNIX(R) form MS-DOS(R). Of course, creative people often break rules, "
+"and it is OK as long as they know they are breaking them and why."
+msgstr ""
+"Это предостережения, а не абсолютные правила. Возможны исключения. Например, "
+"если текстовый редактор определил, что работает на локальной машине, он "
+"может захотеть читать скан-коды напрямую для улучшенного управления. Я "
+"упоминаю эти предостережения не для того, чтобы сказать вам, что делать или "
+"чего не делать, а просто чтобы вы осознавали определённые подводные камни, "
+"которые ждут вас, если вы только что перешли с MS-DOS(R) на UNIX(R). "
+"Конечно, творческие люди часто нарушают правила, и это нормально, пока они "
+"осознают, что нарушают их, и понимают почему."
+
+#. type: Title ==
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4302
+#, no-wrap
+msgid "Acknowledgements"
+msgstr "Благодарности"
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4305
+msgid ""
+"This tutorial would never have been possible without the help of many "
+"experienced FreeBSD programmers from the {freebsd-hackers}, many of whom "
+"have patiently answered my questions, and pointed me in the right direction "
+"in my attempts to explore the inner workings of UNIX(R) system programming "
+"in general and FreeBSD in particular."
+msgstr ""
+"Это руководство никогда бы не было создано без помощи многих опытных "
+"программистов FreeBSD из {freebsd-hackers}, которые терпеливо отвечали на "
+"мои вопросы и направляли меня в моих попытках изучить внутренние механизмы "
+"программирования в системе UNIX(R) в целом и в FreeBSD в частности."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4308
+msgid ""
+"Thomas M. Sommers opened the door for me . His https://web.archive.org/"
+"web/20090914064615/http://www.codebreakers-journal.com/content/"
+"view/262/27[How do I write \"Hello, world\" in FreeBSD assembler?] web page "
+"was my first encounter with an example of assembly language programming "
+"under FreeBSD."
+msgstr ""
+"Томас М. Соммерс открыл дверь для меня. Его https://web.archive.org/"
+"web/20090914064615/http://www.codebreakers-journal.com/content/"
+"view/262/27[Как написать \"Hello, world\" на ассемблере в FreeBSD?] веб-"
+"страница стала моей первой встречей с примером программирования на "
+"ассемблере под FreeBSD."
+
+#. type: Plain text
+#: documentation/content/en/books/developers-handbook/x86/_index.adoc:4310
+msgid ""
+"Jake Burkholder has kept the door open by willingly answering all of my "
+"questions and supplying me with example assembly language source code."
+msgstr ""
+"Джейк Буркхолдер держал дверь открытой, охотно отвечая на все мои вопросы и "
+"предоставляя примеры исходного кода на языке ассемблера."