"Fossies" - the Fresh Open Source Software Archive

Member "nasm-2.15.05/doc/html/nasmdo12.html" (28 Aug 2020, 9997 Bytes) of package /linux/misc/nasm-2.15.05-xdoc.tar.xz:

As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) HTML source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file.

    1 <?xml version="1.0" encoding="UTF-8" standalone="no" ?>
    2 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    3 <html xmlns="http://www.w3.org/1999/xhtml">
    4 <head>
    5 <title>NASM - The Netwide Assembler</title>
    6 <link href="nasmdoc.css" rel="stylesheet" type="text/css" />
    7 <link href="local.css" rel="stylesheet" type="text/css" />
    8 </head>
    9 <body>
   10 <ul class="navbar">
   11 <li class="first"><a class="prev" href="nasmdo11.html">Chapter 11</a></li>
   12 <li><a class="next" href="nasmdo13.html">Chapter 13</a></li>
   13 <li><a class="toc" href="nasmdoc0.html">Contents</a></li>
   14 <li class="last"><a class="index" href="nasmdoci.html">Index</a></li>
   15 </ul>
   16 <div class="title">
   17 <h1>NASM - The Netwide Assembler</h1>
   18 <span class="subtitle">version 2.15.05</span>
   19 </div>
   20 <div class="contents"
   21 >
   22 <h2 id="chapter-12">Chapter 12: Writing 64-bit Code (Unix, Win64)</h2>
   23 <p>This chapter attempts to cover some of the common issues involved when
   24 writing 64-bit code, to run under Win64 or Unix. It covers how to write
   25 assembly code to interface with 64-bit C routines, and how to write
   26 position-independent code for shared libraries.</p>
   27 <p>All 64-bit code uses a flat memory model, since segmentation is not
   28 available in 64-bit mode. The one exception is the <code>FS</code> and
   29 <code>GS</code> registers, which still add their bases.</p>
   30 <p>Position independence in 64-bit mode is significantly simpler, since the
   31 processor supports <code>RIP</code>&ndash;relative addressing directly; see
   32 the <code>REL</code> keyword (<a href="nasmdoc3.html#section-3.3">section
   33 3.3</a>). On most 64-bit platforms, it is probably desirable to make that
   34 the default, using the directive <code>DEFAULT REL</code>
   35 (<a href="nasmdoc7.html#section-7.2">section 7.2</a>).</p>
   36 <p>64-bit programming is relatively similar to 32-bit programming, but of
   37 course pointers are 64 bits long; additionally, all existing platforms pass
   38 arguments in registers rather than on the stack. Furthermore, 64-bit
   39 platforms use SSE2 by default for floating point. Please see the ABI
   40 documentation for your platform.</p>
   41 <p>64-bit platforms differ in the sizes of the C/C++ fundamental datatypes,
   42 not just from 32-bit platforms but from each other. If a specific size data
   43 type is desired, it is probably best to use the types defined in the
   44 standard C header <code>&lt;inttypes.h&gt;</code>.</p>
   45 <p>All known 64-bit platforms except some embedded platforms require that
   46 the stack is 16-byte aligned at the entry to a function. In order to
   47 enforce that, the stack pointer (<code>RSP</code>) needs to be aligned on
   48 an <code>odd</code> multiple of 8 bytes before the <code>CALL</code>
   49 instruction.</p>
   50 <p>In 64-bit mode, the default instruction size is still 32 bits. When
   51 loading a value into a 32-bit register (but not an 8- or 16-bit register),
   52 the upper 32 bits of the corresponding 64-bit register are set to zero.</p>
   53 <h3 id="section-12.1">12.1 Register Names in 64-bit Mode</h3>
   54 <p>NASM uses the following names for general-purpose registers in 64-bit
   55 mode, for 8-, 16-, 32- and 64-bit references, respectively:</p>
   56 <pre>
   57      AL/AH, CL/CH, DL/DH, BL/BH, SPL, BPL, SIL, DIL, R8B-R15B 
   58      AX, CX, DX, BX, SP, BP, SI, DI, R8W-R15W 
   59      EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI, R8D-R15D 
   60      RAX, RCX, RDX, RBX, RSP, RBP, RSI, RDI, R8-R15
   61 </pre>
   62 <p>This is consistent with the AMD documentation and most other assemblers.
   63 The Intel documentation, however, uses the names <code>R8L-R15L</code> for
   64 8-bit references to the higher registers. It is possible to use those names
   65 by definiting them as macros; similarly, if one wants to use numeric names
   66 for the low 8 registers, define them as macros. The standard macro package
   67 <code>altreg</code> (see <a href="nasmdoc6.html#section-6.1">section
   68 6.1</a>) can be used for this purpose.</p>
   69 <h3 id="section-12.2">12.2 Immediates and Displacements in 64-bit Mode</h3>
   70 <p>In 64-bit mode, immediates and displacements are generally only 32 bits
   71 wide. NASM will therefore truncate most displacements and immediates to 32
   72 bits.</p>
   73 <p>The only instruction which takes a full 64-bit immediate is:</p>
   74 <pre>
   75      MOV reg64,imm64
   76 </pre>
   77 <p>NASM will produce this instruction whenever the programmer uses
   78 <code>MOV</code> with an immediate into a 64-bit register. If this is not
   79 desirable, simply specify the equivalent 32-bit register, which will be
   80 automatically zero-extended by the processor, or specify the immediate as
   81 <code>DWORD</code>:</p>
   82 <pre>
   83      mov rax,foo             ; 64-bit immediate 
   84      mov rax,qword foo       ; (identical) 
   85      mov eax,foo             ; 32-bit immediate, zero-extended 
   86      mov rax,dword foo       ; 32-bit immediate, sign-extended
   87 </pre>
   88 <p>The length of these instructions are 10, 5 and 7 bytes, respectively.</p>
   89 <p>If optimization is enabled and NASM can determine at assembly time that
   90 a shorter instruction will suffice, the shorter instruction will be emitted
   91 unless of course <code>STRICT QWORD</code> or <code>STRICT DWORD</code> is
   92 specified (see <a href="nasmdoc3.html#section-3.7">section 3.7</a>):</p>
   93 <pre>
   94      mov rax,1               ; Assembles as "mov eax,1" (5 bytes) 
   95      mov rax,strict qword 1  ; Full 10-byte instruction 
   96      mov rax,strict dword 1  ; 7-byte instruction 
   97      mov rax,symbol          ; 10 bytes, not known at assembly time 
   98      lea rax,[rel symbol]    ; 7 bytes, usually preferred by the ABI
   99 </pre>
  100 <p>Note that <code>lea rax,[rel symbol]</code> is position-independent,
  101 whereas <code>mov rax,symbol</code> is not. Most ABIs prefer or even
  102 require position-independent code in 64-bit mode. However, the
  103 <code>MOV</code> instruction is able to reference a symbol anywhere in the
  104 64-bit address space, whereas <code>LEA</code> is only able to access a
  105 symbol within within 2 GB of the instruction itself (see below.)</p>
  106 <p>The only instructions which take a full 64-bit <em>displacement</em> is
  107 loading or storing, using <code>MOV</code>, <code>AL</code>,
  108 <code>AX</code>, <code>EAX</code> or <code>RAX</code> (but no other
  109 registers) to an absolute 64-bit address. Since this is a relatively rarely
  110 used instruction (64-bit code generally uses relative addressing), the
  111 programmer has to explicitly declare the displacement size as
  112 <code>ABS QWORD</code>:</p>
  113 <pre>
  114      default abs 
  116      mov eax,[foo]           ; 32-bit absolute disp, sign-extended 
  117      mov eax,[a32 foo]       ; 32-bit absolute disp, zero-extended 
  118      mov eax,[qword foo]     ; 64-bit absolute disp 
  120      default rel 
  122      mov eax,[foo]           ; 32-bit relative disp 
  123      mov eax,[a32 foo]       ; d:o, address truncated to 32 bits(!) 
  124      mov eax,[qword foo]     ; error 
  125      mov eax,[abs qword foo] ; 64-bit absolute disp
  126 </pre>
  127 <p>A sign-extended absolute displacement can access from &ndash;2 GB to +2
  128 GB; a zero-extended absolute displacement can access from 0 to 4 GB.</p>
  129 <h3 id="section-12.3">12.3 Interfacing to 64-bit C Programs (Unix)</h3>
  130 <p>On Unix, the 64-bit ABI as well as the x32 ABI (32-bit ABI with the CPU
  131 in 64-bit mode) is defined by the documents at:</p>
  132 <p>
  133 <a href="http://www.nasm.us/abi/unix64"><code>http://www.nasm.us/abi/unix64</code></a></p>
  134 <p>Although written for AT&amp;T-syntax assembly, the concepts apply
  135 equally well for NASM-style assembly. What follows is a simplified summary.</p>
  136 <p>The first six integer arguments (from the left) are passed in
  137 <code>RDI</code>, <code>RSI</code>, <code>RDX</code>, <code>RCX</code>,
  138 <code>R8</code>, and <code>R9</code>, in that order. Additional integer
  139 arguments are passed on the stack. These registers, plus <code>RAX</code>,
  140 <code>R10</code> and <code>R11</code> are destroyed by function calls, and
  141 thus are available for use by the function without saving.</p>
  142 <p>Integer return values are passed in <code>RAX</code> and
  143 <code>RDX</code>, in that order.</p>
  144 <p>Floating point is done using SSE registers, except for
  145 <code>long double</code>, which is 80 bits (<code>TWORD</code>) on most
  146 platforms (Android is one exception; there <code>long double</code> is 64
  147 bits and treated the same as <code>double</code>.) Floating-point arguments
  148 are passed in <code>XMM0</code> to <code>XMM7</code>; return is
  149 <code>XMM0</code> and <code>XMM1</code>. <code>long double</code> are
  150 passed on the stack, and returned in <code>ST0</code> and <code>ST1</code>.</p>
  151 <p>All SSE and x87 registers are destroyed by function calls.</p>
  152 <p>On 64-bit Unix, <code>long</code> is 64 bits.</p>
  153 <p>Integer and SSE register arguments are counted separately, so for the
  154 case of</p>
  155 <pre>
  156      void foo(long a, double b, int c)
  157 </pre>
  158 <p><code>a</code> is passed in <code>RDI</code>, <code>b</code> in
  159 <code>XMM0</code>, and <code>c</code> in <code>ESI</code>.</p>
  160 <h3 id="section-12.4">12.4 Interfacing to 64-bit C Programs (Win64)</h3>
  161 <p>The Win64 ABI is described by the document at:</p>
  162 <p>
  163 <a href="http://www.nasm.us/abi/win64"><code>http://www.nasm.us/abi/win64</code></a></p>
  164 <p>What follows is a simplified summary.</p>
  165 <p>The first four integer arguments are passed in <code>RCX</code>,
  166 <code>RDX</code>, <code>R8</code> and <code>R9</code>, in that order.
  167 Additional integer arguments are passed on the stack. These registers, plus
  168 <code>RAX</code>, <code>R10</code> and <code>R11</code> are destroyed by
  169 function calls, and thus are available for use by the function without
  170 saving.</p>
  171 <p>Integer return values are passed in <code>RAX</code> only.</p>
  172 <p>Floating point is done using SSE registers, except for
  173 <code>long double</code>. Floating-point arguments are passed in
  174 <code>XMM0</code> to <code>XMM3</code>; return is <code>XMM0</code> only.</p>
  175 <p>On Win64, <code>long</code> is 32 bits; <code>long long</code> or
  176 <code>_int64</code> is 64 bits.</p>
  177 <p>Integer and SSE register arguments are counted together, so for the case
  178 of</p>
  179 <pre>
  180      void foo(long long a, double b, int c)
  181 </pre>
  182 <p><code>a</code> is passed in <code>RCX</code>, <code>b</code> in
  183 <code>XMM1</code>, and <code>c</code> in <code>R8D</code>.</p>
  184 </div>
  185 </body>
  186 </html>