mirror of
https://git.FreeBSD.org/doc.git
synced 2026-06-02 19:35:07 +00:00
1580646eab
Reviewed by: andy Differential Revision: https://reviews.freebsd.org/В56932
11158 lines
458 KiB
Plaintext
11158 lines
458 KiB
Plaintext
# 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, 2026.
|
||
msgid ""
|
||
msgstr ""
|
||
"Project-Id-Version: FreeBSD Documentation VERSION\n"
|
||
"POT-Creation-Date: 2025-11-08 16:17+0000\n"
|
||
"PO-Revision-Date: 2026-04-05 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 ""
|
||
"Джейк Буркхолдер держал дверь открытой, охотно отвечая на все мои вопросы и "
|
||
"предоставляя примеры исходного кода на языке ассемблера."
|