path: root/doc/latex/src/64bit.tex
diff options
authorCyrill Gorcunov <gorcunov@gmail.com>2019-03-31 19:33:08 +0300
committerCyrill Gorcunov <gorcunov@gmail.com>2019-03-31 19:34:50 +0300
commita384068a04a5cf92a4564fa39b061b7539cb94f9 (patch)
tree711eb1fdc3892eb6f966b5418d3f2a4917aa078b /doc/latex/src/64bit.tex
parent982186a1a3139763f2aa2710b32236009f64270d (diff)
doc: latex -- Initial importlatex
It is an initial import for conversion of our documentation to latex format. Note that latex additional packages needs to be preinstalled, xelatex is used for pdf generation. While I've been very carefull while converting the docs there is a big probability that some indices might be screwed so we need to review everything once again. Then we need to create a converter for html backend, I started working on it but didn't successed yet and I fear won't have enough spare time in near future. Also we need to autogenerate instruction table and warnings from insns.dat and probably from scanning nasm sources. To build nasm.pdf just run make -C doc/latex/ it doesn't require configuration and rather a standalone builder out of our traditional build engine. Signed-off-by: Cyrill Gorcunov <gorcunov@gmail.com>
Diffstat (limited to 'doc/latex/src/64bit.tex')
1 files changed, 204 insertions, 0 deletions
diff --git a/doc/latex/src/64bit.tex b/doc/latex/src/64bit.tex
new file mode 100644
index 00000000..5aaf20f6
--- /dev/null
+++ b/doc/latex/src/64bit.tex
@@ -0,0 +1,204 @@
+% vim: ts=4 sw=4 et
+\xchapter{64bit}{Writing 64-bit Code (Unix, Win64)}
+This chapter attempts to cover some of the common issues involved when
+writing 64-bit code, to run under \textindex{Win64} or Unix. It covers
+how to write assembly code to interface with 64-bit C routines, and
+how to write position-independent code for shared libraries.
+All 64-bit code uses a flat memory model, since segmentation is not
+available in 64-bit mode. The one exception is the \code{FS} and
+\code{GS} registers, which still add their bases.
+Position independence in 64-bit mode is significantly simpler, since
+the processor supports \code{RIP}-relative addressing directly; see the
+\code{REL} keyword (\nref{effaddr}). On most 64-bit platforms,
+it is probably desirable to make that the default, using the directive
+\code{DEFAULT REL} (\nref{default}).
+64-bit programming is relatively similar to 32-bit programming, but
+of course pointers are 64 bits long; additionally, all existing
+platforms pass arguments in registers rather than on the stack.
+Furthermore, 64-bit platforms use SSE2 by default for floating point.
+Please see the ABI documentation for your platform.
+64-bit platforms differ in the sizes of the C/C++ fundamental
+datatypes, not just from 32-bit platforms but from each other. If a
+specific size data type is desired, it is probably best to use the
+types defined in the standard C header \code{<inttypes.h>}.
+All known 64-bit platforms except some embedded platforms require that
+the stack is 16-byte aligned at the entry to a function. In order to
+enforce that, the stack pointer (\code{RSP}) needs to be aligned on an
+\code{odd} multiple of 8 bytes before the \code{CALL} instruction.
+In 64-bit mode, the default instruction size is still 32 bits. When
+loading a value into a 32-bit register (but not an 8- or 16-bit
+register), the upper 32 bits of the corresponding 64-bit register are
+set to zero.
+\xsection{reg64}{Register Names in 64-bit Mode}
+NASM uses the following names for general-purpose registers in 64-bit
+mode, for 8-, 16-, 32- and 64-bit references, respectively:
+AX, CX, DX, BX, SP, BP, SI, DI, R8W-R15W
+This is consistent with the AMD documentation and most other
+assemblers. The Intel documentation, however, uses the names
+\code{R8L-R15L} for 8-bit references to the higher registers. It is
+possible to use those names by definiting them as macros; similarly,
+if one wants to use numeric names for the low 8 registers, define them
+as macros. The standard macro package \code{altreg} (see
+\nref{pkgaltreg}) can be used for this purpose.
+\xsection{id64}{Immediates and Displacements in 64-bit Mode}
+In 64-bit mode, immediates and displacements are generally only 32
+bits wide. NASM will therefore truncate most displacements and
+immediates to 32 bits.
+The only instruction which takes a full \textindex{64-bit immediate} is:
+mov reg64,imm64
+NASM will produce this instruction whenever the programmer uses
+\code{MOV} with an immediate into a 64-bit register. If this is not
+desirable, simply specify the equivalent 32-bit register, which will
+be automatically zero-extended by the processor, or specify the
+immediate as \code{DWORD}:
+mov rax,foo ; 64-bit immediate
+mov rax,qword foo ; (identical)
+mov eax,foo ; 32-bit immediate, zero-extended
+mov rax,dword foo ; 32-bit immediate, sign-extended
+The length of these instructions are 10, 5 and 7 bytes, respectively.
+If optimization is enabled and NASM can determine at assembly time
+that a shorter instruction will suffice, the shorter instruction will
+be emitted unless of course \code{STRICT QWORD} or \code{STRICT DWORD}
+is specified (see \nref{strict}):
+mov rax,1 ; Assembles as "mov eax,1" (5 bytes)
+mov rax,strict qword 1 ; Full 10-byte instruction
+mov rax,strict dword 1 ; 7-byte instruction
+mov rax,symbol ; 10 bytes, not known at assembly time
+lea rax,[rel symbol] ; 7 bytes, usually preferred by the ABI
+Note that \code{lea rax,[rel symbol]} is position-independent, whereas
+\code{mov rax,symbol} is not. Most ABIs prefer or even require
+position-independent code in 64-bit mode. However, the \code{MOV}
+instruction is able to reference a symbol anywhere in the 64-bit
+address space, whereas \code{LEA} is only able to access a symbol within
+within 2 GB of the instruction itself (see below.)
+The only instructions which take a full \textindex{64-bit displacement}
+is loading or storing, using \code{MOV}, \code{AL}, \code{AX}, \code{EAX}
+or \code{RAX} (but no other registers) to an absolute 64-bit address.
+Since this is a relatively rarely used instruction (64-bit code
+generally uses relative addressing), the programmer has to explicitly
+declare the displacement size as \code{ABS QWORD}:
+default abs
+mov eax,[foo] ; 32-bit absolute disp, sign-extended
+mov eax,[a32 foo] ; 32-bit absolute disp, zero-extended
+mov eax,[qword foo] ; 64-bit absolute disp
+default rel
+mov eax,[foo] ; 32-bit relative disp
+mov eax,[a32 foo] ; d:o, address truncated to 32 bits(!)
+mov eax,[qword foo] ; error
+mov eax,[abs qword foo] ; 64-bit absolute disp
+A sign-extended absolute displacement can access from -2 GB to +2 GB;
+a zero-extended absolute displacement can access from 0 to 4 GB.
+\xsection{unix64}{Interfacing to 64-bit C Programs (Unix)}
+On Unix, the 64-bit ABI as well as the x32 ABI (32-bit ABI with the
+CPU in 64-bit mode) is defined by the documents at
+Although written for AT\&T-syntax assembly, the concepts apply equally
+well for NASM-style assembly. What follows is a simplified summary.
+The first six integer arguments (from the left) are passed in \code{RDI},
+\code{RSI}, \code{RDX}, \code{RCX}, \code{R8}, and \code{R9}, in that
+order. Additional integer arguments are passed on the stack. These
+registers, plus \code{RAX}, \code{R10} and \code{R11} are destroyed
+by function calls, and thus are available for use by the function
+without saving.
+Integer return values are passed in \code{RAX} and \code{RDX},
+in that order.
+Floating point is done using SSE registers, except for \code{long double},
+which is 80 bits (\code{TWORD}) on most platforms (Android is
+one exception; there \code{long double} is 64 bits and treated the same
+as \code{double}.) Floating-point arguments are passed in \code{XMM0} to
+\code{XMM7}; return is \code{XMM0} and \code{XMM1}. \code{long double}
+are passed on the stack, and returned in \code{ST0} and \code{ST1}.
+All SSE and x87 registers are destroyed by function calls.
+On 64-bit Unix, \code{long} is 64 bits.
+Integer and SSE register arguments are counted separately, so
+for the case of
+void foo(long a, double b, int c)
+\code{a} is passed in \code{RDI}, \code{b} in \code{XMM0},
+and \code{c} in \code{ESI}.
+\xsection{win64}{Interfacing to 64-bit C Programs (Win64)}
+The Win64 ABI is described by the document at
+What follows is a simplified summary.
+The first four integer arguments are passed in \code{RCX}, \code{RDX},
+\code{R8} and \code{R9}, in that order. Additional integer arguments are
+passed on the stack. These registers, plus \code{RAX}, \code{R10} and
+\code{R11} are destroyed by function calls, and thus are available for
+use by the function without saving.
+Integer return values are passed in \code{RAX} only.
+Floating point is done using SSE registers, except for \code{long
+double}. Floating-point arguments are passed in \code{XMM0}
+to \code{XMM3}; return is \code{XMM0} only.
+On Win64, \code{long} is 32 bits; \code{long long} or \code{\_int64}
+is 64 bits.
+Integer and SSE register arguments are counted together, so
+for the case of
+void foo(long long a, double b, int c)
+\code{a} is passed in \code{RCX}, \code{b} in \code{XMM1},
+and \code{c} in \code{R8D}.