Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 19 May 2026 14:25:10 +0000
From:      Mitchell Horne <mhorne@FreeBSD.org>
To:        doc-committers@FreeBSD.org, dev-commits-doc-all@FreeBSD.org
Subject:   git: 204da0afff - main - x86-assembly: update the article a bit
Message-ID:  <6a0c72c6.3e5f4.635991d3@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by mhorne:

URL: https://cgit.FreeBSD.org/doc/commit/?id=204da0afff16e333db3fdd6be60eca849ce480fa

commit 204da0afff16e333db3fdd6be60eca849ce480fa
Author:     Mitchell Horne <mhorne@FreeBSD.org>
AuthorDate: 2026-05-19 14:15:53 +0000
Commit:     Mitchell Horne <mhorne@FreeBSD.org>
CommitDate: 2026-05-19 14:15:53 +0000

    x86-assembly: update the article a bit
    
    Minor tweaks for consistency/readability. Actual content is not touched.
    
     - Replace references to "chapter" with "article".
     - Add a NOTE of the historical nature of the document.
     - Clarify assemblers available on FreeBSD.
     - List the trademarks used in the article, and reduce the (R) symbol
       usage. Per the Doc Primer, it only needs to be emitted with the first
       usage of the trademark.
     - Add more tags for SEO
    
    Reviewed by:    0mp, emaste (previous version)
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D45962
---
 .../content/de/articles/x86-assembly/_index.adoc   |   2 +-
 .../content/en/articles/x86-assembly/_index.adoc   | 214 ++++++++++-----------
 .../content/ru/articles/x86-assembly/_index.adoc   |   2 +-
 3 files changed, 100 insertions(+), 118 deletions(-)

diff --git a/documentation/content/de/articles/x86-assembly/_index.adoc b/documentation/content/de/articles/x86-assembly/_index.adoc
index 0a3aa3831a..da56b90f38 100644
--- a/documentation/content/de/articles/x86-assembly/_index.adoc
+++ b/documentation/content/de/articles/x86-assembly/_index.adoc
@@ -4,7 +4,7 @@ authors:
   - author: Adam Stanislav
     email: adam@redprince.net
 description: A tutorial on writing programs for FreeBSD in x86 assembly language
-tags: ["x86", "assembly", "programming", "guide"]
+tags: ["assembly", "guide", "ia32", "ld", "llvm-as", "nasm", "programming", "x86"]
 ---
 
 = x86-Assembler-Programmierung
diff --git a/documentation/content/en/articles/x86-assembly/_index.adoc b/documentation/content/en/articles/x86-assembly/_index.adoc
index 73e34b3817..b14d045530 100644
--- a/documentation/content/en/articles/x86-assembly/_index.adoc
+++ b/documentation/content/en/articles/x86-assembly/_index.adoc
@@ -4,7 +4,8 @@ authors:
   - author: Adam Stanislav
     email: adam@redprince.net
 description: A tutorial on writing programs for FreeBSD in x86 assembly language
-tags: ["x86", "assembly", "programming", "guide"]
+trademarks: ["apple", "freebsd", "general", "intel", "linux", "microsoft", "posix", "unix"]
+tags: ["assembly", "guide", "ia32", "ld", "llvm-as", "nasm", "programming", "x86"]
 ---
 
 = x86 Assembly Language Programming
@@ -41,26 +42,31 @@ toc::[]
 include::../../../../../shared/asciidoctor.adoc[]
 endif::[]
 
-_This chapter was written by {stanislav}._
+_This article was written by {stanislav} (2001), and adjusted by {mhorne} (2026)._
+
+[NOTE]
+====
+The content in this article is historical.
+====
 
 [[x86-intro]]
 == Synopsis
 
 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.
+It is generally assumed that no one would ever want to use it because various UNIX systems run on different microprocessors, so everything should be written in C for portability.
 
 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.
+Even C programs need to be modified when ported from one UNIX 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.
 
-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?
+Even if we believe that all of UNIX 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?
 
-In this chapter I will attempt to show you how you can use assembly language writing UNIX(R) programs, specifically under FreeBSD.
+In this article I will attempt to show you how you can use assembly language writing UNIX programs, specifically under FreeBSD.
 
-This chapter does not explain the basics of assembly language.
+This article 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.
+However, once the article is finished, any assembly language programmer will be able to write programs for FreeBSD quickly and efficiently.
 
 Copyright (R) 2000-2001 G. Adam Stanislav. All rights reserved.
 
@@ -71,14 +77,15 @@ Copyright (R) 2000-2001 G. Adam Stanislav. All rights reserved.
 === The Assembler
 
 The most important tool for assembly language programming is the assembler, the software that converts assembly language code into machine language.
+Two very different types of assemblers are available for FreeBSD.
 
-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.
+The first is the GNU man:as[1] (package:devel/binutils[]), which uses the traditional UNIX assembly language syntax.
+Alternatively, one can use man:clang[1], which is a compatible replacement for the GNU assembler and comes with the system.
 
-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.
+The other is man:nasm[1] (package:devel/nasm[]).
+This assembler uses the Intel syntax, and its main advantage is that it can assemble code for many operating systems.
 
-This chapter uses nasm syntax because most assembly language programmers coming to FreeBSD from other operating systems will find it easier to understand.
+This article 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.
 
 [[x86-the-linker]]
@@ -99,7 +106,7 @@ 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.
 
 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.
+Why? Because the UNIX convention allows any program written in any language to access the kernel.
 
 An assembly language program can do that as well.
 For example, we could open a file:
@@ -121,7 +128,7 @@ open:
 ....
 
 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.
+If you need to port the code to a UNIX system which uses a different interrupt, or a different way of passing parameters, all you need to change is the kernel procedure.
 
 But assembly language programmers like to shave off cycles.
 The above example requires a `call/ret` combination.
@@ -146,11 +153,11 @@ The `5` that we have placed in `EAX` identifies the kernel function, in this cas
 
 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.
+For it to work, however, the system must have Linux(R) emulation installed.
 
-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`.
+Linux is a UNIX-like system.
+However, its kernel uses the same system-call convention of passing parameters in registers MS-DOS does.
+As with the UNIX 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`:
 
 [.programlisting]
@@ -179,7 +186,7 @@ After your program is assembled and linked, you need to brand the executable:
 [[x86-use-geneva]]
 === Which Convention Should You Use?
 
-If you are coding specifically for FreeBSD, you should always use the UNIX(R) convention:
+If you are coding specifically for FreeBSD, you should always use the UNIX 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.
 
@@ -198,7 +205,7 @@ Of course, you need to know what the number is.
 The numbers are listed in [.filename]#syscalls#.
 `locate syscalls` finds this file in several different formats, all produced automatically from [.filename]#syscalls.master#.
 
-You can find the master file for the default UNIX(R) calling convention in [.filename]#/usr/src/sys/kern/syscalls.master#.
+You can find the master file for the default UNIX 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#.
 
 [NOTE]
@@ -239,7 +246,7 @@ A file does not exist, system resources are exhausted, we passed an invalid para
 [[x86-man-pages]]
 === Man Pages
 
-The traditional place to look for information about various system calls under UNIX(R) systems are the manual pages.
+The traditional place to look for information about various system calls under UNIX systems are the manual pages.
 FreeBSD describes its system calls in section 2, sometimes in section 3.
 
 For example,  man:open[2] says:
@@ -248,7 +255,7 @@ For example,  man:open[2] says:
 If successful, `open()` returns a non-negative integer, termed a file descriptor.
 It returns `-1` on failure, and sets `errno` to indicate the error.
 
-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?
+The assembly language programmer new to UNIX and FreeBSD will immediately ask the puzzling question: Where is `errno` and how do I get to it?
 
 [NOTE]
 ====
@@ -280,7 +287,7 @@ If you cannot find the answer here or anywhere else, study libc source code and
 
 Actually, nowhere...
 
-`errno` is part of the C language, not the UNIX(R) kernel.
+`errno` is part of the C language, not the UNIX kernel.
 When accessing kernel services directly, the error code is returned in `EAX`, the same register the proper return value generally ends up in.
 
 This makes perfect sense. If there is no error, there is no error code.
@@ -304,7 +311,7 @@ I have written assembly language libraries that can be assembled for such differ
 
 It is all the more possible when you want your code to run on two platforms which, while different, are based on similar architectures.
 
-For example, FreeBSD is UNIX(R), Linux is UNIX(R) like.
+For example, FreeBSD is UNIX, Linux is UNIX-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.
 
@@ -454,7 +461,7 @@ No library or external object file is necessary, yet your code is portable witho
 
 [NOTE]
 ====
-This is the approach we will use throughout this chapter.
+This is the approach we will use throughout this article.
 We will name our include file [.filename]#system.inc#, and add to it whenever we deal with a new system call.
 ====
 
@@ -569,8 +576,8 @@ The `SYS_exit` syscall never returns, so the code ends there.
 
 [NOTE]
 ====
-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).
+If you have come to UNIX from MS-DOS 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.
 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.
@@ -580,32 +587,7 @@ Which one it is, is for the system to figure out.
 === Assembling the Code
 
 Type the code in an editor, and save it in a file named [.filename]#hello.asm#.
-You need nasm to assemble it.
-
-[[x86-get-nasm]]
-==== Installing nasm
-
-If you do not have nasm, type:
-
-[source,shell]
-....
-% su
-Password:your root password
-# cd /usr/ports/devel/nasm
-# make install
-# exit
-%
-....
-
-You may type `make install clean` instead of just `make install` if you do not want to keep nasm source code.
-
-Either way, FreeBSD will automatically download nasm from the Internet, compile it, and install it on your system.
-
-[NOTE]
-====
-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.
-====
+You need package:devel/nasm[] to assemble it.
 
 Now you can assemble, link, and run the code:
 
@@ -619,9 +601,9 @@ Hello, World!
 ....
 
 [[x86-unix-filters]]
-== Writing UNIX(R) Filters
+== Writing UNIX Filters
 
-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#.
+A common type of UNIX application is a filter-a program that reads data from the [.filename]#stdin#, processes it somehow, then writes the result to [.filename]#stdout#.
 
 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.
@@ -712,8 +694,8 @@ Hello, World!
 
 [NOTE]
 ====
-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.
+If you are migrating to UNIX from MS-DOS, you may be wondering why each line ends with `0A` instead of `0D 0A`.
+This is because UNIX does not use the cr/lf convention, but a "new line" convention, which is `0A` in hexadecimal.
 ====
 
 Can we improve this? Well, for one, it is a bit confusing because once we have converted a line of text,
@@ -773,7 +755,7 @@ _start:
 ....
 
 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.
+We can do this safely because, unlike Microsoft Windows, UNIX system calls do not modify the value of any register they do not use to return a value in.
 
 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`.
@@ -914,7 +896,7 @@ It simply reserves the requested size of uninitialized memory for our use.
 
 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.
+This is also why the UNIX 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.
 
 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,
@@ -1159,7 +1141,7 @@ With this modification, you can call `ungetc` up to 17 times in a row safely (th
 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?
 
-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.
+Before a UNIX 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.
 
@@ -1175,7 +1157,7 @@ The `argv` list is followed by a NULL pointer, which is simply a `0`. There is m
 
 [NOTE]
 ====
-If you have come from the MS-DOS(R) programming environment, the main difference is that each argument is in a separate string.
+If you have come from the MS-DOS 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.
 ====
 
@@ -1389,9 +1371,9 @@ Here are a few ideas of what we could do:
 I shall leave these enhancements as an exercise to the reader: You already know everything you need to know to implement them.
 
 [[x86-environment]]
-== UNIX(R) Environment
+== UNIX Environment
 
-An important UNIX(R) concept is the environment, which is defined by _environment variables_.
+An important UNIX 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.
 
 [[x86-find-environment]]
@@ -1410,7 +1392,7 @@ We need to account for that possibility.
 [[x86-webvar]]
 === webvars
 
-I could just show you some code that prints the environment the same way the UNIX(R) env command does.
+I could just show you some code that prints the environment the same way the UNIX env command does.
 But I thought it would be more interesting to write a simple assembly language CGI utility.
 
 [[x86-cgi]]
@@ -1645,19 +1627,19 @@ If curious about the additional environment variables present in a password prot
 == Working with Files
 
 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.
+But UNIX 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.
 
 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.
 
-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).
+One of the first programs I wrote for UNIX was package:converters/tuc[tuc(1)], a text-to-UNIX file converter.
+It converts a text file from other operating systems to a UNIX text file.
+In other words, it changes from different kind of line endings to the newline convention of UNIX.
 It saves the output in a different file.
-Optionally, it converts a UNIX(R) text file to a DOS text file.
+Optionally, it converts a UNIX text file to a DOS text file.
 
-I have used tuc extensively, but always only to convert from some other OS to UNIX(R), never the other way.
+I have used tuc extensively, but always only to convert from some other OS to UNIX, 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:
 
@@ -1674,13 +1656,13 @@ It would be nice to have a ftuc, i.e., _fast tuc_, and use it like this:
 % ftuc myfile
 ....
 
-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.
+In this article, then, we will write ftuc in assembly language (the original tuc is in C), and study various file-oriented kernel services in the process.
 
 At first sight, such a file conversion is very simple: All you have to do is strip the carriage returns, right?
 
 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.
 
-The problem is that not all non UNIX(R) text files end their line with the carriage return / line feed sequence.
+The problem is that not all non-UNIX 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.
@@ -1730,7 +1712,7 @@ What our software does in this state again depends on the current input:
 * 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.
 
 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.
+This will happen when our file already is in UNIX 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:
 
 * 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.
@@ -1817,7 +1799,7 @@ I said _possibly_ because with the caching modern microprocessors do, either way
 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.
 
-UNIX(R) allows us to map a file, or a section of a file, into memory.
+UNIX 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:
@@ -1833,12 +1815,12 @@ 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.
 
 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.
+This is because of evolution of UNIX: 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.
+But new software uses the POSIX version, which is what we will use.
 
-The [.filename]#syscalls.master# lists the POSIX(R) version like this:
+The [.filename]#syscalls.master# lists the POSIX version like this:
 
 [.programlisting]
 ....
@@ -1868,8 +1850,8 @@ Because we need to tell `mmap` how many bytes of the file to map into the memory
 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.
 
-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:
+Again, [.filename]#syscalls.master# lists two versions of `fstat`, a traditional one (syscall 62), and a POSIX one (syscall 189).
+Naturally, we will use the POSIX version:
 
 [.programlisting]
 ....
@@ -2224,7 +2206,7 @@ align 4
 
 [WARNING]
 ====
-Do not use this program on files stored on a disk formatted by MS-DOS(R) or Windows(R).
+Do not use this program on files stored on a disk formatted by MS-DOS or Windows.
 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.
 ====
@@ -2234,12 +2216,12 @@ If the file is over a certain size, `mmap` will just fill the memory with zeros,
 
 As a student of Zen, I like the idea of a one-pointed mind: Do one thing at a time, and do it well.
 
-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.
+This, indeed, is very much how UNIX works as well.
+While a typical Windows application is attempting to do everything imaginable (and is, therefore, riddled with bugs), a typical UNIX program does only one thing, and it does it well.
 
-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.
+The typical UNIX 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.
 
-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.
+When writing your own UNIX 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.
 
 [[x86-csv]]
 === CSV
@@ -2256,7 +2238,7 @@ The rest of the file contains the data listed line by line, with values separate
 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.
 
 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:
+However, going with the UNIX spirit, I only needed to write a simple filter that would do the following:
 
 * Remove the first line from the file;
 * Change all unquoted commas to a different character;
@@ -2295,7 +2277,7 @@ 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.
 
 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.
+Defaults are [.filename]#stdin# and [.filename]#stdout#, so this is a regular UNIX filter.
 
 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.
@@ -2590,7 +2572,7 @@ 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.
 
-I have found a better solution for the interactive problem since I first started writing this chapter.
+I have found a better solution for the interactive problem since I first started writing this article.
 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.
 
@@ -2906,7 +2888,7 @@ The most important thing we need to know when building a pinhole camera is the d
 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.
 
-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.
+It is traditional in UNIX 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.
 
 Why have two ways of choosing?
 
@@ -4051,7 +4033,7 @@ It is converting the text representation of a number into that number: The text
 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.
 
-Everything else in this code should be quit eclear, providing you have read the entire chapter that precedes it.
+Everything else in this code should be quit eclear, providing you have read the entire article that precedes it.
 
 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.
@@ -4115,7 +4097,7 @@ You have probably seen shell _scripts_ that start with:
 
 ...because the blank space after the `#!` is optional.
 
-Whenever UNIX(R) is asked to run an executable file which starts with the `#!`, it assumes the file is a script.
+Whenever UNIX 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.
 
 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.
@@ -4148,7 +4130,7 @@ We can set its permissions to execute, and run it as if it were a program:
 % ./medium
 ....
 
-UNIX(R) will interpret that last command as:
+UNIX will interpret that last command as:
 
 [source,shell]
 ....
@@ -4177,7 +4159,7 @@ Now, let us enter:
 % ./medium -c
 ....
 
-UNIX(R) will treat that as:
+UNIX will treat that as:
 
 [source,shell]
 ....
@@ -4223,40 +4205,40 @@ focal length in millimeters,pinhole diameter in microns,F-number,normalized F-nu
 [[x86-caveats]]
 == Caveats
 
-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.
+Assembly language programmers who "grew up" under MS-DOS and Windows 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 are not frowned upon but considered the right thing to do.
 
-The reason? Both the PC BIOS and MS-DOS(R) are notoriously slow when performing these operations.
+The reason? Both the PC BIOS and MS-DOS are notoriously slow when performing these operations.
 
-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.
+You may be tempted to continue similar practices in the UNIX environment.
+For example, I have seen a web site which explains how to access the keyboard scan codes on a popular UNIX clone.
 
-That is generally a _very bad idea_ in UNIX(R) environment! Let me explain why.
+That is generally a _very bad idea_ in UNIX environment! Let me explain why.
 
 [[x86-protected]]
-=== UNIX(R) Is Protected
+=== UNIX Is Protected
 
 For one thing, it may simply not be possible.
-UNIX(R) runs in protected mode.
+UNIX 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.
+Perhaps a particular UNIX clone will let you read the keyboard scan codes, but chances are a real UNIX 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.
 
 [[x86-abstraction]]
-=== UNIX(R) Is an Abstraction
+=== UNIX Is an Abstraction
 
-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:
+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 like systems that let you do it:
 
-_UNIX(R) is an abstraction!_
+_UNIX is an abstraction!_
 
-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.
+There is a major difference in the philosophy of design between MS-DOS and UNIX.
+MS-DOS 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.
 
-This is NEVER guaranteed under UNIX(R).
-It is quite common for a UNIX(R) user to pipe and redirect program input and output:
+This is NEVER guaranteed under UNIX.
+It is quite common for a UNIX user to pipe and redirect program input and output:
 
 [source,shell]
 ....
@@ -4267,18 +4249,18 @@ If you have written program2, your input does not come from the keyboard but fro
 Similarly, your output does not go to the screen but becomes the input for program3 whose output, in turn, goes to [.filename]#file1#.
 
 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.
+It may be a Macintosh, or any other computer.
 
-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).
+Now you may be shaking your head: My software is in PC assembly language, how can it run on a Macintosh? But I did not say your software would be running on a Macintosh, only that its terminal may be a Macintosh.
 
-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.
+Under UNIX, 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 user in Australia connects to a UNIX 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!
 
 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.
 
-That is why under UNIX(R) you must never make any assumptions about where your data is coming from and going to.
+That is why under UNIX 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.
 
 [NOTE]
@@ -4286,14 +4268,14 @@ Always let the system handle the physical access to the hardware.
 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).
+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 form MS-DOS.
 Of course, creative people often break rules, and it is OK as long as they know they are breaking them and why.
 ====
 
 [[x86-acknowledgements]]
 == Acknowledgements
 
-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.
+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 system programming in general and FreeBSD in particular.
 
 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.
diff --git a/documentation/content/ru/articles/x86-assembly/_index.adoc b/documentation/content/ru/articles/x86-assembly/_index.adoc
index a7222e861b..94c8727391 100644
--- a/documentation/content/ru/articles/x86-assembly/_index.adoc
+++ b/documentation/content/ru/articles/x86-assembly/_index.adoc
@@ -2,7 +2,7 @@
 title: 'Программирование на языке ассемблера для x86'
 authors: ~
 description: 'Программирование на ассемблере x86'
-tags: ["x86", "assembly", "programming", "guide"]
+tags: ["assembly", "guide", "ia32", "ld", "llvm-as", "nasm", "programming", "x86"]
 ---
 
 [[x86]]


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6a0c72c6.3e5f4.635991d3>