asm.html 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
  1. <!--{
  2. "Title": "A Quick Guide to Go's Assembler",
  3. "Path": "/doc/asm"
  4. }-->
  5. <h2 id="introduction">A Quick Guide to Go's Assembler</h2>
  6. <p>
  7. This document is a quick outline of the unusual form of assembly language used by the <code>gc</code> Go compiler.
  8. The document is not comprehensive.
  9. </p>
  10. <p>
  11. The assembler is based on the input style of the Plan 9 assemblers, which is documented in detail
  12. <a href="https://9p.io/sys/doc/asm.html">elsewhere</a>.
  13. If you plan to write assembly language, you should read that document although much of it is Plan 9-specific.
  14. The current document provides a summary of the syntax and the differences with
  15. what is explained in that document, and
  16. describes the peculiarities that apply when writing assembly code to interact with Go.
  17. </p>
  18. <p>
  19. The most important thing to know about Go's assembler is that it is not a direct representation of the underlying machine.
  20. Some of the details map precisely to the machine, but some do not.
  21. This is because the compiler suite (see
  22. <a href="https://9p.io/sys/doc/compiler.html">this description</a>)
  23. needs no assembler pass in the usual pipeline.
  24. Instead, the compiler operates on a kind of semi-abstract instruction set,
  25. and instruction selection occurs partly after code generation.
  26. The assembler works on the semi-abstract form, so
  27. when you see an instruction like <code>MOV</code>
  28. what the toolchain actually generates for that operation might
  29. not be a move instruction at all, perhaps a clear or load.
  30. Or it might correspond exactly to the machine instruction with that name.
  31. In general, machine-specific operations tend to appear as themselves, while more general concepts like
  32. memory move and subroutine call and return are more abstract.
  33. The details vary with architecture, and we apologize for the imprecision; the situation is not well-defined.
  34. </p>
  35. <p>
  36. The assembler program is a way to parse a description of that
  37. semi-abstract instruction set and turn it into instructions to be
  38. input to the linker.
  39. If you want to see what the instructions look like in assembly for a given architecture, say amd64, there
  40. are many examples in the sources of the standard library, in packages such as
  41. <a href="/pkg/runtime/"><code>runtime</code></a> and
  42. <a href="/pkg/math/big/"><code>math/big</code></a>.
  43. You can also examine what the compiler emits as assembly code
  44. (the actual output may differ from what you see here):
  45. </p>
  46. <pre>
  47. $ cat x.go
  48. package main
  49. func main() {
  50. println(3)
  51. }
  52. $ GOOS=linux GOARCH=amd64 go tool compile -S x.go # or: go build -gcflags -S x.go
  53. --- prog list "main" ---
  54. 0000 (x.go:3) TEXT main+0(SB),$8-0
  55. 0001 (x.go:3) FUNCDATA $0,gcargs·0+0(SB)
  56. 0002 (x.go:3) FUNCDATA $1,gclocals·0+0(SB)
  57. 0003 (x.go:4) MOVQ $3,(SP)
  58. 0004 (x.go:4) PCDATA $0,$8
  59. 0005 (x.go:4) CALL ,runtime.printint+0(SB)
  60. 0006 (x.go:4) PCDATA $0,$-1
  61. 0007 (x.go:4) PCDATA $0,$0
  62. 0008 (x.go:4) CALL ,runtime.printnl+0(SB)
  63. 0009 (x.go:4) PCDATA $0,$-1
  64. 0010 (x.go:5) RET ,
  65. ...
  66. </pre>
  67. <p>
  68. The <code>FUNCDATA</code> and <code>PCDATA</code> directives contain information
  69. for use by the garbage collector; they are introduced by the compiler.
  70. </p>
  71. <!-- Commenting out because the feature is gone but it's popular and may come back.
  72. <p>
  73. To see what gets put in the binary after linking, add the <code>-a</code> flag to the linker:
  74. </p>
  75. <pre>
  76. $ go tool 6l -a x.6 # or: go build -ldflags -a x.go
  77. codeblk [0x2000,0x1d059) at offset 0x1000
  78. 002000 main.main | (3) TEXT main.main+0(SB),$8
  79. 002000 65488b0c25a0080000 | (3) MOVQ 2208(GS),CX
  80. 002009 483b21 | (3) CMPQ SP,(CX)
  81. 00200c 7707 | (3) JHI ,2015
  82. 00200e e83da20100 | (3) CALL ,1c250+runtime.morestack00
  83. 002013 ebeb | (3) JMP ,2000
  84. 002015 4883ec08 | (3) SUBQ $8,SP
  85. 002019 | (3) FUNCDATA $0,main.gcargs·0+0(SB)
  86. 002019 | (3) FUNCDATA $1,main.gclocals·0+0(SB)
  87. 002019 48c7042403000000 | (4) MOVQ $3,(SP)
  88. 002021 | (4) PCDATA $0,$8
  89. 002021 e8aad20000 | (4) CALL ,f2d0+runtime.printint
  90. 002026 | (4) PCDATA $0,$-1
  91. 002026 | (4) PCDATA $0,$0
  92. 002026 e865d40000 | (4) CALL ,f490+runtime.printnl
  93. 00202b | (4) PCDATA $0,$-1
  94. 00202b 4883c408 | (5) ADDQ $8,SP
  95. 00202f c3 | (5) RET ,
  96. ...
  97. </pre>
  98. -->
  99. <h3 id="constants">Constants</h3>
  100. <p>
  101. Although the assembler takes its guidance from the Plan 9 assemblers,
  102. it is a distinct program, so there are some differences.
  103. One is in constant evaluation.
  104. Constant expressions in the assembler are parsed using Go's operator
  105. precedence, not the C-like precedence of the original.
  106. Thus <code>3&amp;1<<2</code> is 4, not 0—it parses as <code>(3&amp;1)<<2</code>
  107. not <code>3&amp;(1<<2)</code>.
  108. Also, constants are always evaluated as 64-bit unsigned integers.
  109. Thus <code>-2</code> is not the integer value minus two,
  110. but the unsigned 64-bit integer with the same bit pattern.
  111. The distinction rarely matters but
  112. to avoid ambiguity, division or right shift where the right operand's
  113. high bit is set is rejected.
  114. </p>
  115. <h3 id="symbols">Symbols</h3>
  116. <p>
  117. Some symbols, such as <code>R1</code> or <code>LR</code>,
  118. are predefined and refer to registers.
  119. The exact set depends on the architecture.
  120. </p>
  121. <p>
  122. There are four predeclared symbols that refer to pseudo-registers.
  123. These are not real registers, but rather virtual registers maintained by
  124. the toolchain, such as a frame pointer.
  125. The set of pseudo-registers is the same for all architectures:
  126. </p>
  127. <ul>
  128. <li>
  129. <code>FP</code>: Frame pointer: arguments and locals.
  130. </li>
  131. <li>
  132. <code>PC</code>: Program counter:
  133. jumps and branches.
  134. </li>
  135. <li>
  136. <code>SB</code>: Static base pointer: global symbols.
  137. </li>
  138. <li>
  139. <code>SP</code>: Stack pointer: top of stack.
  140. </li>
  141. </ul>
  142. <p>
  143. All user-defined symbols are written as offsets to the pseudo-registers
  144. <code>FP</code> (arguments and locals) and <code>SB</code> (globals).
  145. </p>
  146. <p>
  147. The <code>SB</code> pseudo-register can be thought of as the origin of memory, so the symbol <code>foo(SB)</code>
  148. is the name <code>foo</code> as an address in memory.
  149. This form is used to name global functions and data.
  150. Adding <code>&lt;&gt;</code> to the name, as in <span style="white-space: nowrap"><code>foo&lt;&gt;(SB)</code></span>, makes the name
  151. visible only in the current source file, like a top-level <code>static</code> declaration in a C file.
  152. Adding an offset to the name refers to that offset from the symbol's address, so
  153. <code>foo+4(SB)</code> is four bytes past the start of <code>foo</code>.
  154. </p>
  155. <p>
  156. The <code>FP</code> pseudo-register is a virtual frame pointer
  157. used to refer to function arguments.
  158. The compilers maintain a virtual frame pointer and refer to the arguments on the stack as offsets from that pseudo-register.
  159. Thus <code>0(FP)</code> is the first argument to the function,
  160. <code>8(FP)</code> is the second (on a 64-bit machine), and so on.
  161. However, when referring to a function argument this way, it is necessary to place a name
  162. at the beginning, as in <code>first_arg+0(FP)</code> and <code>second_arg+8(FP)</code>.
  163. (The meaning of the offset—offset from the frame pointer—distinct
  164. from its use with <code>SB</code>, where it is an offset from the symbol.)
  165. The assembler enforces this convention, rejecting plain <code>0(FP)</code> and <code>8(FP)</code>.
  166. The actual name is semantically irrelevant but should be used to document
  167. the argument's name.
  168. It is worth stressing that <code>FP</code> is always a
  169. pseudo-register, not a hardware
  170. register, even on architectures with a hardware frame pointer.
  171. </p>
  172. <p>
  173. For assembly functions with Go prototypes, <code>go</code> <code>vet</code> will check that the argument names
  174. and offsets match.
  175. On 32-bit systems, the low and high 32 bits of a 64-bit value are distinguished by adding
  176. a <code>_lo</code> or <code>_hi</code> suffix to the name, as in <code>arg_lo+0(FP)</code> or <code>arg_hi+4(FP)</code>.
  177. If a Go prototype does not name its result, the expected assembly name is <code>ret</code>.
  178. </p>
  179. <p>
  180. The <code>SP</code> pseudo-register is a virtual stack pointer
  181. used to refer to frame-local variables and the arguments being
  182. prepared for function calls.
  183. It points to the top of the local stack frame, so references should use negative offsets
  184. in the range [−framesize, 0):
  185. <code>x-8(SP)</code>, <code>y-4(SP)</code>, and so on.
  186. </p>
  187. <p>
  188. On architectures with a hardware register named <code>SP</code>,
  189. the name prefix distinguishes
  190. references to the virtual stack pointer from references to the architectural
  191. <code>SP</code> register.
  192. That is, <code>x-8(SP)</code> and <code>-8(SP)</code>
  193. are different memory locations:
  194. the first refers to the virtual stack pointer pseudo-register,
  195. while the second refers to the
  196. hardware's <code>SP</code> register.
  197. </p>
  198. <p>
  199. On machines where <code>SP</code> and <code>PC</code> are
  200. traditionally aliases for a physical, numbered register,
  201. in the Go assembler the names <code>SP</code> and <code>PC</code>
  202. are still treated specially;
  203. for instance, references to <code>SP</code> require a symbol,
  204. much like <code>FP</code>.
  205. To access the actual hardware register use the true <code>R</code> name.
  206. For example, on the ARM architecture the hardware
  207. <code>SP</code> and <code>PC</code> are accessible as
  208. <code>R13</code> and <code>R15</code>.
  209. </p>
  210. <p>
  211. Branches and direct jumps are always written as offsets to the PC, or as
  212. jumps to labels:
  213. </p>
  214. <pre>
  215. label:
  216. MOVW $0, R1
  217. JMP label
  218. </pre>
  219. <p>
  220. Each label is visible only within the function in which it is defined.
  221. It is therefore permitted for multiple functions in a file to define
  222. and use the same label names.
  223. Direct jumps and call instructions can target text symbols,
  224. such as <code>name(SB)</code>, but not offsets from symbols,
  225. such as <code>name+4(SB)</code>.
  226. </p>
  227. <p>
  228. Instructions, registers, and assembler directives are always in UPPER CASE to remind you
  229. that assembly programming is a fraught endeavor.
  230. (Exception: the <code>g</code> register renaming on ARM.)
  231. </p>
  232. <p>
  233. In Go object files and binaries, the full name of a symbol is the
  234. package path followed by a period and the symbol name:
  235. <code>fmt.Printf</code> or <code>math/rand.Int</code>.
  236. Because the assembler's parser treats period and slash as punctuation,
  237. those strings cannot be used directly as identifier names.
  238. Instead, the assembler allows the middle dot character U+00B7
  239. and the division slash U+2215 in identifiers and rewrites them to
  240. plain period and slash.
  241. Within an assembler source file, the symbols above are written as
  242. <code>fmt·Printf</code> and <code>math∕rand·Int</code>.
  243. The assembly listings generated by the compilers when using the <code>-S</code> flag
  244. show the period and slash directly instead of the Unicode replacements
  245. required by the assemblers.
  246. </p>
  247. <p>
  248. Most hand-written assembly files do not include the full package path
  249. in symbol names, because the linker inserts the package path of the current
  250. object file at the beginning of any name starting with a period:
  251. in an assembly source file within the math/rand package implementation,
  252. the package's Int function can be referred to as <code>·Int</code>.
  253. This convention avoids the need to hard-code a package's import path in its
  254. own source code, making it easier to move the code from one location to another.
  255. </p>
  256. <h3 id="directives">Directives</h3>
  257. <p>
  258. The assembler uses various directives to bind text and data to symbol names.
  259. For example, here is a simple complete function definition. The <code>TEXT</code>
  260. directive declares the symbol <code>runtime·profileloop</code> and the instructions
  261. that follow form the body of the function.
  262. The last instruction in a <code>TEXT</code> block must be some sort of jump, usually a <code>RET</code> (pseudo-)instruction.
  263. (If it's not, the linker will append a jump-to-itself instruction; there is no fallthrough in <code>TEXTs</code>.)
  264. After the symbol, the arguments are flags (see below)
  265. and the frame size, a constant (but see below):
  266. </p>
  267. <pre>
  268. TEXT runtime·profileloop(SB),NOSPLIT,$8
  269. MOVQ $runtime·profileloop1(SB), CX
  270. MOVQ CX, 0(SP)
  271. CALL runtime·externalthreadhandler(SB)
  272. RET
  273. </pre>
  274. <p>
  275. In the general case, the frame size is followed by an argument size, separated by a minus sign.
  276. (It's not a subtraction, just idiosyncratic syntax.)
  277. The frame size <code>$24-8</code> states that the function has a 24-byte frame
  278. and is called with 8 bytes of argument, which live on the caller's frame.
  279. If <code>NOSPLIT</code> is not specified for the <code>TEXT</code>,
  280. the argument size must be provided.
  281. For assembly functions with Go prototypes, <code>go</code> <code>vet</code> will check that the
  282. argument size is correct.
  283. </p>
  284. <p>
  285. Note that the symbol name uses a middle dot to separate the components and is specified as an offset from the
  286. static base pseudo-register <code>SB</code>.
  287. This function would be called from Go source for package <code>runtime</code> using the
  288. simple name <code>profileloop</code>.
  289. </p>
  290. <p>
  291. Global data symbols are defined by a sequence of initializing
  292. <code>DATA</code> directives followed by a <code>GLOBL</code> directive.
  293. Each <code>DATA</code> directive initializes a section of the
  294. corresponding memory.
  295. The memory not explicitly initialized is zeroed.
  296. The general form of the <code>DATA</code> directive is
  297. <pre>
  298. DATA symbol+offset(SB)/width, value
  299. </pre>
  300. <p>
  301. which initializes the symbol memory at the given offset and width with the given value.
  302. The <code>DATA</code> directives for a given symbol must be written with increasing offsets.
  303. </p>
  304. <p>
  305. The <code>GLOBL</code> directive declares a symbol to be global.
  306. The arguments are optional flags and the size of the data being declared as a global,
  307. which will have initial value all zeros unless a <code>DATA</code> directive
  308. has initialized it.
  309. The <code>GLOBL</code> directive must follow any corresponding <code>DATA</code> directives.
  310. </p>
  311. <p>
  312. For example,
  313. </p>
  314. <pre>
  315. DATA divtab&lt;&gt;+0x00(SB)/4, $0xf4f8fcff
  316. DATA divtab&lt;&gt;+0x04(SB)/4, $0xe6eaedf0
  317. ...
  318. DATA divtab&lt;&gt;+0x3c(SB)/4, $0x81828384
  319. GLOBL divtab&lt;&gt;(SB), RODATA, $64
  320. GLOBL runtime·tlsoffset(SB), NOPTR, $4
  321. </pre>
  322. <p>
  323. declares and initializes <code>divtab&lt;&gt;</code>, a read-only 64-byte table of 4-byte integer values,
  324. and declares <code>runtime·tlsoffset</code>, a 4-byte, implicitly zeroed variable that
  325. contains no pointers.
  326. </p>
  327. <p>
  328. There may be one or two arguments to the directives.
  329. If there are two, the first is a bit mask of flags,
  330. which can be written as numeric expressions, added or or-ed together,
  331. or can be set symbolically for easier absorption by a human.
  332. Their values, defined in the standard <code>#include</code> file <code>textflag.h</code>, are:
  333. </p>
  334. <ul>
  335. <li>
  336. <code>NOPROF</code> = 1
  337. <br>
  338. (For <code>TEXT</code> items.)
  339. Don't profile the marked function. This flag is deprecated.
  340. </li>
  341. <li>
  342. <code>DUPOK</code> = 2
  343. <br>
  344. It is legal to have multiple instances of this symbol in a single binary.
  345. The linker will choose one of the duplicates to use.
  346. </li>
  347. <li>
  348. <code>NOSPLIT</code> = 4
  349. <br>
  350. (For <code>TEXT</code> items.)
  351. Don't insert the preamble to check if the stack must be split.
  352. The frame for the routine, plus anything it calls, must fit in the
  353. spare space at the top of the stack segment.
  354. Used to protect routines such as the stack splitting code itself.
  355. </li>
  356. <li>
  357. <code>RODATA</code> = 8
  358. <br>
  359. (For <code>DATA</code> and <code>GLOBL</code> items.)
  360. Put this data in a read-only section.
  361. </li>
  362. <li>
  363. <code>NOPTR</code> = 16
  364. <br>
  365. (For <code>DATA</code> and <code>GLOBL</code> items.)
  366. This data contains no pointers and therefore does not need to be
  367. scanned by the garbage collector.
  368. </li>
  369. <li>
  370. <code>WRAPPER</code> = 32
  371. <br>
  372. (For <code>TEXT</code> items.)
  373. This is a wrapper function and should not count as disabling <code>recover</code>.
  374. </li>
  375. <li>
  376. <code>NEEDCTXT</code> = 64
  377. <br>
  378. (For <code>TEXT</code> items.)
  379. This function is a closure so it uses its incoming context register.
  380. </li>
  381. </ul>
  382. <h3 id="runtime">Runtime Coordination</h3>
  383. <p>
  384. For garbage collection to run correctly, the runtime must know the
  385. location of pointers in all global data and in most stack frames.
  386. The Go compiler emits this information when compiling Go source files,
  387. but assembly programs must define it explicitly.
  388. </p>
  389. <p>
  390. A data symbol marked with the <code>NOPTR</code> flag (see above)
  391. is treated as containing no pointers to runtime-allocated data.
  392. A data symbol with the <code>RODATA</code> flag
  393. is allocated in read-only memory and is therefore treated
  394. as implicitly marked <code>NOPTR</code>.
  395. A data symbol with a total size smaller than a pointer
  396. is also treated as implicitly marked <code>NOPTR</code>.
  397. It is not possible to define a symbol containing pointers in an assembly source file;
  398. such a symbol must be defined in a Go source file instead.
  399. Assembly source can still refer to the symbol by name
  400. even without <code>DATA</code> and <code>GLOBL</code> directives.
  401. A good general rule of thumb is to define all non-<code>RODATA</code>
  402. symbols in Go instead of in assembly.
  403. </p>
  404. <p>
  405. Each function also needs annotations giving the location of
  406. live pointers in its arguments, results, and local stack frame.
  407. For an assembly function with no pointer results and
  408. either no local stack frame or no function calls,
  409. the only requirement is to define a Go prototype for the function
  410. in a Go source file in the same package. The name of the assembly
  411. function must not contain the package name component (for example,
  412. function <code>Syscall</code> in package <code>syscall</code> should
  413. use the name <code>·Syscall</code> instead of the equivalent name
  414. <code>syscall·Syscall</code> in its <code>TEXT</code> directive).
  415. For more complex situations, explicit annotation is needed.
  416. These annotations use pseudo-instructions defined in the standard
  417. <code>#include</code> file <code>funcdata.h</code>.
  418. </p>
  419. <p>
  420. If a function has no arguments and no results,
  421. the pointer information can be omitted.
  422. This is indicated by an argument size annotation of <code>$<i>n</i>-0</code>
  423. on the <code>TEXT</code> instruction.
  424. Otherwise, pointer information must be provided by
  425. a Go prototype for the function in a Go source file,
  426. even for assembly functions not called directly from Go.
  427. (The prototype will also let <code>go</code> <code>vet</code> check the argument references.)
  428. At the start of the function, the arguments are assumed
  429. to be initialized but the results are assumed uninitialized.
  430. If the results will hold live pointers during a call instruction,
  431. the function should start by zeroing the results and then
  432. executing the pseudo-instruction <code>GO_RESULTS_INITIALIZED</code>.
  433. This instruction records that the results are now initialized
  434. and should be scanned during stack movement and garbage collection.
  435. It is typically easier to arrange that assembly functions do not
  436. return pointers or do not contain call instructions;
  437. no assembly functions in the standard library use
  438. <code>GO_RESULTS_INITIALIZED</code>.
  439. </p>
  440. <p>
  441. If a function has no local stack frame,
  442. the pointer information can be omitted.
  443. This is indicated by a local frame size annotation of <code>$0-<i>n</i></code>
  444. on the <code>TEXT</code> instruction.
  445. The pointer information can also be omitted if the
  446. function contains no call instructions.
  447. Otherwise, the local stack frame must not contain pointers,
  448. and the assembly must confirm this fact by executing the
  449. pseudo-instruction <code>NO_LOCAL_POINTERS</code>.
  450. Because stack resizing is implemented by moving the stack,
  451. the stack pointer may change during any function call:
  452. even pointers to stack data must not be kept in local variables.
  453. </p>
  454. <p>
  455. Assembly functions should always be given Go prototypes,
  456. both to provide pointer information for the arguments and results
  457. and to let <code>go</code> <code>vet</code> check that
  458. the offsets being used to access them are correct.
  459. </p>
  460. <h2 id="architectures">Architecture-specific details</h2>
  461. <p>
  462. It is impractical to list all the instructions and other details for each machine.
  463. To see what instructions are defined for a given machine, say ARM,
  464. look in the source for the <code>obj</code> support library for
  465. that architecture, located in the directory <code>src/cmd/internal/obj/arm</code>.
  466. In that directory is a file <code>a.out.go</code>; it contains
  467. a long list of constants starting with <code>A</code>, like this:
  468. </p>
  469. <pre>
  470. const (
  471. AAND = obj.ABaseARM + obj.A_ARCHSPECIFIC + iota
  472. AEOR
  473. ASUB
  474. ARSB
  475. AADD
  476. ...
  477. </pre>
  478. <p>
  479. This is the list of instructions and their spellings as known to the assembler and linker for that architecture.
  480. Each instruction begins with an initial capital <code>A</code> in this list, so <code>AAND</code>
  481. represents the bitwise and instruction,
  482. <code>AND</code> (without the leading <code>A</code>),
  483. and is written in assembly source as <code>AND</code>.
  484. The enumeration is mostly in alphabetical order.
  485. (The architecture-independent <code>AXXX</code>, defined in the
  486. <code>cmd/internal/obj</code> package,
  487. represents an invalid instruction).
  488. The sequence of the <code>A</code> names has nothing to do with the actual
  489. encoding of the machine instructions.
  490. The <code>cmd/internal/obj</code> package takes care of that detail.
  491. </p>
  492. <p>
  493. The instructions for both the 386 and AMD64 architectures are listed in
  494. <code>cmd/internal/obj/x86/a.out.go</code>.
  495. </p>
  496. <p>
  497. The architectures share syntax for common addressing modes such as
  498. <code>(R1)</code> (register indirect),
  499. <code>4(R1)</code> (register indirect with offset), and
  500. <code>$foo(SB)</code> (absolute address).
  501. The assembler also supports some (not necessarily all) addressing modes
  502. specific to each architecture.
  503. The sections below list these.
  504. </p>
  505. <p>
  506. One detail evident in the examples from the previous sections is that data in the instructions flows from left to right:
  507. <code>MOVQ</code> <code>$0,</code> <code>CX</code> clears <code>CX</code>.
  508. This rule applies even on architectures where the conventional notation uses the opposite direction.
  509. </p>
  510. <p>
  511. Here follow some descriptions of key Go-specific details for the supported architectures.
  512. </p>
  513. <h3 id="x86">32-bit Intel 386</h3>
  514. <p>
  515. The runtime pointer to the <code>g</code> structure is maintained
  516. through the value of an otherwise unused (as far as Go is concerned) register in the MMU.
  517. A OS-dependent macro <code>get_tls</code> is defined for the assembler if the source includes
  518. a special header, <code>go_asm.h</code>:
  519. </p>
  520. <pre>
  521. #include "go_asm.h"
  522. </pre>
  523. <p>
  524. Within the runtime, the <code>get_tls</code> macro loads its argument register
  525. with a pointer to the <code>g</code> pointer, and the <code>g</code> struct
  526. contains the <code>m</code> pointer.
  527. The sequence to load <code>g</code> and <code>m</code> using <code>CX</code> looks like this:
  528. </p>
  529. <pre>
  530. get_tls(CX)
  531. MOVL g(CX), AX // Move g into AX.
  532. MOVL g_m(AX), BX // Move g.m into BX.
  533. </pre>
  534. <p>
  535. Addressing modes:
  536. </p>
  537. <ul>
  538. <li>
  539. <code>(DI)(BX*2)</code>: The location at address <code>DI</code> plus <code>BX*2</code>.
  540. </li>
  541. <li>
  542. <code>64(DI)(BX*2)</code>: The location at address <code>DI</code> plus <code>BX*2</code> plus 64.
  543. These modes accept only 1, 2, 4, and 8 as scale factors.
  544. </li>
  545. </ul>
  546. <p>
  547. When using the compiler and assembler's
  548. <code>-dynlink</code> or <code>-shared</code> modes,
  549. any load or store of a fixed memory location such as a global variable
  550. must be assumed to overwrite <code>CX</code>.
  551. Therefore, to be safe for use with these modes,
  552. assembly sources should typically avoid CX except between memory references.
  553. </p>
  554. <h3 id="amd64">64-bit Intel 386 (a.k.a. amd64)</h3>
  555. <p>
  556. The two architectures behave largely the same at the assembler level.
  557. Assembly code to access the <code>m</code> and <code>g</code>
  558. pointers on the 64-bit version is the same as on the 32-bit 386,
  559. except it uses <code>MOVQ</code> rather than <code>MOVL</code>:
  560. </p>
  561. <pre>
  562. get_tls(CX)
  563. MOVQ g(CX), AX // Move g into AX.
  564. MOVQ g_m(AX), BX // Move g.m into BX.
  565. </pre>
  566. <h3 id="arm">ARM</h3>
  567. <p>
  568. The registers <code>R10</code> and <code>R11</code>
  569. are reserved by the compiler and linker.
  570. </p>
  571. <p>
  572. <code>R10</code> points to the <code>g</code> (goroutine) structure.
  573. Within assembler source code, this pointer must be referred to as <code>g</code>;
  574. the name <code>R10</code> is not recognized.
  575. </p>
  576. <p>
  577. To make it easier for people and compilers to write assembly, the ARM linker
  578. allows general addressing forms and pseudo-operations like <code>DIV</code> or <code>MOD</code>
  579. that may not be expressible using a single hardware instruction.
  580. It implements these forms as multiple instructions, often using the <code>R11</code> register
  581. to hold temporary values.
  582. Hand-written assembly can use <code>R11</code>, but doing so requires
  583. being sure that the linker is not also using it to implement any of the other
  584. instructions in the function.
  585. </p>
  586. <p>
  587. When defining a <code>TEXT</code>, specifying frame size <code>$-4</code>
  588. tells the linker that this is a leaf function that does not need to save <code>LR</code> on entry.
  589. </p>
  590. <p>
  591. The name <code>SP</code> always refers to the virtual stack pointer described earlier.
  592. For the hardware register, use <code>R13</code>.
  593. </p>
  594. <p>
  595. Condition code syntax is to append a period and the one- or two-letter code to the instruction,
  596. as in <code>MOVW.EQ</code>.
  597. Multiple codes may be appended: <code>MOVM.IA.W</code>.
  598. The order of the code modifiers is irrelevant.
  599. </p>
  600. <p>
  601. Addressing modes:
  602. </p>
  603. <ul>
  604. <li>
  605. <code>R0-&gt;16</code>
  606. <br>
  607. <code>R0&gt;&gt;16</code>
  608. <br>
  609. <code>R0&lt;&lt;16</code>
  610. <br>
  611. <code>R0@&gt;16</code>:
  612. For <code>&lt;&lt;</code>, left shift <code>R0</code> by 16 bits.
  613. The other codes are <code>-&gt;</code> (arithmetic right shift),
  614. <code>&gt;&gt;</code> (logical right shift), and
  615. <code>@&gt;</code> (rotate right).
  616. </li>
  617. <li>
  618. <code>R0-&gt;R1</code>
  619. <br>
  620. <code>R0&gt;&gt;R1</code>
  621. <br>
  622. <code>R0&lt;&lt;R1</code>
  623. <br>
  624. <code>R0@&gt;R1</code>:
  625. For <code>&lt;&lt;</code>, left shift <code>R0</code> by the count in <code>R1</code>.
  626. The other codes are <code>-&gt;</code> (arithmetic right shift),
  627. <code>&gt;&gt;</code> (logical right shift), and
  628. <code>@&gt;</code> (rotate right).
  629. </li>
  630. <li>
  631. <code>[R0,g,R12-R15]</code>: For multi-register instructions, the set comprising
  632. <code>R0</code>, <code>g</code>, and <code>R12</code> through <code>R15</code> inclusive.
  633. </li>
  634. <li>
  635. <code>(R5, R6)</code>: Destination register pair.
  636. </li>
  637. </ul>
  638. <h3 id="arm64">ARM64</h3>
  639. <p>
  640. The ARM64 port is in an experimental state.
  641. </p>
  642. <p>
  643. <code>R18</code> is the "platform register", reserved on the Apple platform.
  644. To prevent accidental misuse, the register is named <code>R18_PLATFORM</code>.
  645. <code>R27</code> and <code>R28</code> are reserved by the compiler and linker.
  646. <code>R29</code> is the frame pointer.
  647. <code>R30</code> is the link register.
  648. </p>
  649. <p>
  650. Instruction modifiers are appended to the instruction following a period.
  651. The only modifiers are <code>P</code> (postincrement) and <code>W</code>
  652. (preincrement):
  653. <code>MOVW.P</code>, <code>MOVW.W</code>
  654. </p>
  655. <p>
  656. Addressing modes:
  657. </p>
  658. <ul>
  659. <li>
  660. <code>R0-&gt;16</code>
  661. <br>
  662. <code>R0&gt;&gt;16</code>
  663. <br>
  664. <code>R0&lt;&lt;16</code>
  665. <br>
  666. <code>R0@&gt;16</code>:
  667. These are the same as on the 32-bit ARM.
  668. </li>
  669. <li>
  670. <code>$(8&lt;&lt;12)</code>:
  671. Left shift the immediate value <code>8</code> by <code>12</code> bits.
  672. </li>
  673. <li>
  674. <code>8(R0)</code>:
  675. Add the value of <code>R0</code> and <code>8</code>.
  676. </li>
  677. <li>
  678. <code>(R2)(R0)</code>:
  679. The location at <code>R0</code> plus <code>R2</code>.
  680. </li>
  681. <li>
  682. <code>R0.UXTB</code>
  683. <br>
  684. <code>R0.UXTB&lt;&lt;imm</code>:
  685. <code>UXTB</code>: extract an 8-bit value from the low-order bits of <code>R0</code> and zero-extend it to the size of <code>R0</code>.
  686. <code>R0.UXTB&lt;&lt;imm</code>: left shift the result of <code>R0.UXTB</code> by <code>imm</code> bits.
  687. The <code>imm</code> value can be 0, 1, 2, 3, or 4.
  688. The other extensions include <code>UXTH</code> (16-bit), <code>UXTW</code> (32-bit), and <code>UXTX</code> (64-bit).
  689. </li>
  690. <li>
  691. <code>R0.SXTB</code>
  692. <br>
  693. <code>R0.SXTB&lt;&lt;imm</code>:
  694. <code>SXTB</code>: extract an 8-bit value from the low-order bits of <code>R0</code> and sign-extend it to the size of <code>R0</code>.
  695. <code>R0.SXTB&lt;&lt;imm</code>: left shift the result of <code>R0.SXTB</code> by <code>imm</code> bits.
  696. The <code>imm</code> value can be 0, 1, 2, 3, or 4.
  697. The other extensions include <code>SXTH</code> (16-bit), <code>SXTW</code> (32-bit), and <code>SXTX</code> (64-bit).
  698. </li>
  699. <li>
  700. <code>(R5, R6)</code>: Register pair for <code>LDAXP</code>/<code>LDP</code>/<code>LDXP</code>/<code>STLXP</code>/<code>STP</code>/<code>STP</code>.
  701. </li>
  702. </ul>
  703. <p>
  704. Reference: <a href="/pkg/cmd/internal/obj/arm64">Go ARM64 Assembly Instructions Reference Manual</a>
  705. </p>
  706. <h3 id="ppc64">64-bit PowerPC, a.k.a. ppc64</h3>
  707. <p>
  708. The 64-bit PowerPC port is in an experimental state.
  709. </p>
  710. <p>
  711. Addressing modes:
  712. </p>
  713. <ul>
  714. <li>
  715. <code>(R5)(R6*1)</code>: The location at <code>R5</code> plus <code>R6</code>. It is a scaled
  716. mode as on the x86, but the only scale allowed is <code>1</code>.
  717. </li>
  718. <li>
  719. <code>(R5+R6)</code>: Alias for (R5)(R6*1)
  720. </li>
  721. </ul>
  722. <h3 id="s390x">IBM z/Architecture, a.k.a. s390x</h3>
  723. <p>
  724. The registers <code>R10</code> and <code>R11</code> are reserved.
  725. The assembler uses them to hold temporary values when assembling some instructions.
  726. </p>
  727. <p>
  728. <code>R13</code> points to the <code>g</code> (goroutine) structure.
  729. This register must be referred to as <code>g</code>; the name <code>R13</code> is not recognized.
  730. </p>
  731. <p>
  732. <code>R15</code> points to the stack frame and should typically only be accessed using the
  733. virtual registers <code>SP</code> and <code>FP</code>.
  734. </p>
  735. <p>
  736. Load- and store-multiple instructions operate on a range of registers.
  737. The range of registers is specified by a start register and an end register.
  738. For example, <code>LMG</code> <code>(R9),</code> <code>R5,</code> <code>R7</code> would load
  739. <code>R5</code>, <code>R6</code> and <code>R7</code> with the 64-bit values at
  740. <code>0(R9)</code>, <code>8(R9)</code> and <code>16(R9)</code> respectively.
  741. </p>
  742. <p>
  743. Storage-and-storage instructions such as <code>MVC</code> and <code>XC</code> are written
  744. with the length as the first argument.
  745. For example, <code>XC</code> <code>$8,</code> <code>(R9),</code> <code>(R9)</code> would clear
  746. eight bytes at the address specified in <code>R9</code>.
  747. </p>
  748. <p>
  749. If a vector instruction takes a length or an index as an argument then it will be the
  750. first argument.
  751. For example, <code>VLEIF</code> <code>$1,</code> <code>$16,</code> <code>V2</code> will load
  752. the value sixteen into index one of <code>V2</code>.
  753. Care should be taken when using vector instructions to ensure that they are available at
  754. runtime.
  755. To use vector instructions a machine must have both the vector facility (bit 129 in the
  756. facility list) and kernel support.
  757. Without kernel support a vector instruction will have no effect (it will be equivalent
  758. to a <code>NOP</code> instruction).
  759. </p>
  760. <p>
  761. Addressing modes:
  762. </p>
  763. <ul>
  764. <li>
  765. <code>(R5)(R6*1)</code>: The location at <code>R5</code> plus <code>R6</code>.
  766. It is a scaled mode as on the x86, but the only scale allowed is <code>1</code>.
  767. </li>
  768. </ul>
  769. <h3 id="mips">MIPS, MIPS64</h3>
  770. <p>
  771. General purpose registers are named <code>R0</code> through <code>R31</code>,
  772. floating point registers are <code>F0</code> through <code>F31</code>.
  773. </p>
  774. <p>
  775. <code>R30</code> is reserved to point to <code>g</code>.
  776. <code>R23</code> is used as a temporary register.
  777. </p>
  778. <p>
  779. In a <code>TEXT</code> directive, the frame size <code>$-4</code> for MIPS or
  780. <code>$-8</code> for MIPS64 instructs the linker not to save <code>LR</code>.
  781. </p>
  782. <p>
  783. <code>SP</code> refers to the virtual stack pointer.
  784. For the hardware register, use <code>R29</code>.
  785. </p>
  786. <p>
  787. Addressing modes:
  788. </p>
  789. <ul>
  790. <li>
  791. <code>16(R1)</code>: The location at <code>R1</code> plus 16.
  792. </li>
  793. <li>
  794. <code>(R1)</code>: Alias for <code>0(R1)</code>.
  795. </li>
  796. </ul>
  797. <p>
  798. The value of <code>GOMIPS</code> environment variable (<code>hardfloat</code> or
  799. <code>softfloat</code>) is made available to assembly code by predefining either
  800. <code>GOMIPS_hardfloat</code> or <code>GOMIPS_softfloat</code>.
  801. </p>
  802. <p>
  803. The value of <code>GOMIPS64</code> environment variable (<code>hardfloat</code> or
  804. <code>softfloat</code>) is made available to assembly code by predefining either
  805. <code>GOMIPS64_hardfloat</code> or <code>GOMIPS64_softfloat</code>.
  806. </p>
  807. <h3 id="unsupported_opcodes">Unsupported opcodes</h3>
  808. <p>
  809. The assemblers are designed to support the compiler so not all hardware instructions
  810. are defined for all architectures: if the compiler doesn't generate it, it might not be there.
  811. If you need to use a missing instruction, there are two ways to proceed.
  812. One is to update the assembler to support that instruction, which is straightforward
  813. but only worthwhile if it's likely the instruction will be used again.
  814. Instead, for simple one-off cases, it's possible to use the <code>BYTE</code>
  815. and <code>WORD</code> directives
  816. to lay down explicit data into the instruction stream within a <code>TEXT</code>.
  817. Here's how the 386 runtime defines the 64-bit atomic load function.
  818. </p>
  819. <pre>
  820. // uint64 atomicload64(uint64 volatile* addr);
  821. // so actually
  822. // void atomicload64(uint64 *res, uint64 volatile *addr);
  823. TEXT runtime·atomicload64(SB), NOSPLIT, $0-12
  824. MOVL ptr+0(FP), AX
  825. TESTL $7, AX
  826. JZ 2(PC)
  827. MOVL 0, AX // crash with nil ptr deref
  828. LEAL ret_lo+4(FP), BX
  829. // MOVQ (%EAX), %MM0
  830. BYTE $0x0f; BYTE $0x6f; BYTE $0x00
  831. // MOVQ %MM0, 0(%EBX)
  832. BYTE $0x0f; BYTE $0x7f; BYTE $0x03
  833. // EMMS
  834. BYTE $0x0F; BYTE $0x77
  835. RET
  836. </pre>