diff options
Diffstat (limited to 'documentation/content/ru/books/developers-handbook/x86/_index.po')
| -rw-r--r-- | documentation/content/ru/books/developers-handbook/x86/_index.po | 11158 |
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 "" +"Джейк Буркхолдер держал дверь открытой, охотно отвечая на все мои вопросы и " +"предоставляя примеры исходного кода на языке ассемблера." |
