Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.

223 linhas
9.9KB

  1. <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
  2. <html>
  3. <!-- This file documents the GNU Assembler "as".
  4. Copyright (C) 1991-2020 Free Software Foundation, Inc.
  5. Permission is granted to copy, distribute and/or modify this document
  6. under the terms of the GNU Free Documentation License, Version 1.3
  7. or any later version published by the Free Software Foundation;
  8. with no Invariant Sections, with no Front-Cover Texts, and with no
  9. Back-Cover Texts. A copy of the license is included in the
  10. section entitled "GNU Free Documentation License".
  11. -->
  12. <!-- Created by GNU Texinfo 6.5, http://www.gnu.org/software/texinfo/ -->
  13. <head>
  14. <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  15. <title>ARM Unwinding Tutorial (Using as)</title>
  16. <meta name="description" content="ARM Unwinding Tutorial (Using as)">
  17. <meta name="keywords" content="ARM Unwinding Tutorial (Using as)">
  18. <meta name="resource-type" content="document">
  19. <meta name="distribution" content="global">
  20. <meta name="Generator" content="makeinfo">
  21. <link href="index.html#Top" rel="start" title="Top">
  22. <link href="AS-Index.html#AS-Index" rel="index" title="AS Index">
  23. <link href="index.html#SEC_Contents" rel="contents" title="Table of Contents">
  24. <link href="ARM_002dDependent.html#ARM_002dDependent" rel="up" title="ARM-Dependent">
  25. <link href="AVR_002dDependent.html#AVR_002dDependent" rel="next" title="AVR-Dependent">
  26. <link href="ARM-Mapping-Symbols.html#ARM-Mapping-Symbols" rel="prev" title="ARM Mapping Symbols">
  27. <style type="text/css">
  28. <!--
  29. a.summary-letter {text-decoration: none}
  30. blockquote.indentedblock {margin-right: 0em}
  31. blockquote.smallindentedblock {margin-right: 0em; font-size: smaller}
  32. blockquote.smallquotation {font-size: smaller}
  33. div.display {margin-left: 3.2em}
  34. div.example {margin-left: 3.2em}
  35. div.lisp {margin-left: 3.2em}
  36. div.smalldisplay {margin-left: 3.2em}
  37. div.smallexample {margin-left: 3.2em}
  38. div.smalllisp {margin-left: 3.2em}
  39. kbd {font-style: oblique}
  40. pre.display {font-family: inherit}
  41. pre.format {font-family: inherit}
  42. pre.menu-comment {font-family: serif}
  43. pre.menu-preformatted {font-family: serif}
  44. pre.smalldisplay {font-family: inherit; font-size: smaller}
  45. pre.smallexample {font-size: smaller}
  46. pre.smallformat {font-family: inherit; font-size: smaller}
  47. pre.smalllisp {font-size: smaller}
  48. span.nolinebreak {white-space: nowrap}
  49. span.roman {font-family: initial; font-weight: normal}
  50. span.sansserif {font-family: sans-serif; font-weight: normal}
  51. ul.no-bullet {list-style: none}
  52. -->
  53. </style>
  54. </head>
  55. <body lang="en">
  56. <a name="ARM-Unwinding-Tutorial"></a>
  57. <div class="header">
  58. <p>
  59. Previous: <a href="ARM-Mapping-Symbols.html#ARM-Mapping-Symbols" accesskey="p" rel="prev">ARM Mapping Symbols</a>, Up: <a href="ARM_002dDependent.html#ARM_002dDependent" accesskey="u" rel="up">ARM-Dependent</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="AS-Index.html#AS-Index" title="Index" rel="index">Index</a>]</p>
  60. </div>
  61. <hr>
  62. <a name="Unwinding"></a>
  63. <h4 class="subsection">9.4.7 Unwinding</h4>
  64. <p>The ABI for the ARM Architecture specifies a standard format for
  65. exception unwind information. This information is used when an
  66. exception is thrown to determine where control should be transferred.
  67. In particular, the unwind information is used to determine which
  68. function called the function that threw the exception, and which
  69. function called that one, and so forth. This information is also used
  70. to restore the values of callee-saved registers in the function
  71. catching the exception.
  72. </p>
  73. <p>If you are writing functions in assembly code, and those functions
  74. call other functions that throw exceptions, you must use assembly
  75. pseudo ops to ensure that appropriate exception unwind information is
  76. generated. Otherwise, if one of the functions called by your assembly
  77. code throws an exception, the run-time library will be unable to
  78. unwind the stack through your assembly code and your program will not
  79. behave correctly.
  80. </p>
  81. <p>To illustrate the use of these pseudo ops, we will examine the code
  82. that G++ generates for the following C++ input:
  83. </p>
  84. <pre class="verbatim">void callee (int *);
  85. int
  86. caller ()
  87. {
  88. int i;
  89. callee (&amp;i);
  90. return i;
  91. }
  92. </pre>
  93. <p>This example does not show how to throw or catch an exception from
  94. assembly code. That is a much more complex operation and should
  95. always be done in a high-level language, such as C++, that directly
  96. supports exceptions.
  97. </p>
  98. <p>The code generated by one particular version of G++ when compiling the
  99. example above is:
  100. </p>
  101. <pre class="verbatim">_Z6callerv:
  102. .fnstart
  103. .LFB2:
  104. @ Function supports interworking.
  105. @ args = 0, pretend = 0, frame = 8
  106. @ frame_needed = 1, uses_anonymous_args = 0
  107. stmfd sp!, {fp, lr}
  108. .save {fp, lr}
  109. .LCFI0:
  110. .setfp fp, sp, #4
  111. add fp, sp, #4
  112. .LCFI1:
  113. .pad #8
  114. sub sp, sp, #8
  115. .LCFI2:
  116. sub r3, fp, #8
  117. mov r0, r3
  118. bl _Z6calleePi
  119. ldr r3, [fp, #-8]
  120. mov r0, r3
  121. sub sp, fp, #4
  122. ldmfd sp!, {fp, lr}
  123. bx lr
  124. .LFE2:
  125. .fnend
  126. </pre>
  127. <p>Of course, the sequence of instructions varies based on the options
  128. you pass to GCC and on the version of GCC in use. The exact
  129. instructions are not important since we are focusing on the pseudo ops
  130. that are used to generate unwind information.
  131. </p>
  132. <p>An important assumption made by the unwinder is that the stack frame
  133. does not change during the body of the function. In particular, since
  134. we assume that the assembly code does not itself throw an exception,
  135. the only point where an exception can be thrown is from a call, such
  136. as the <code>bl</code> instruction above. At each call site, the same saved
  137. registers (including <code>lr</code>, which indicates the return address)
  138. must be located in the same locations relative to the frame pointer.
  139. </p>
  140. <p>The <code>.fnstart</code> (see <a href="ARM-Directives.html#arm_005ffnstart">.fnstart pseudo op</a>) pseudo
  141. op appears immediately before the first instruction of the function
  142. while the <code>.fnend</code> (see <a href="ARM-Directives.html#arm_005ffnend">.fnend pseudo op</a>) pseudo
  143. op appears immediately after the last instruction of the function.
  144. These pseudo ops specify the range of the function.
  145. </p>
  146. <p>Only the order of the other pseudos ops (e.g., <code>.setfp</code> or
  147. <code>.pad</code>) matters; their exact locations are irrelevant. In the
  148. example above, the compiler emits the pseudo ops with particular
  149. instructions. That makes it easier to understand the code, but it is
  150. not required for correctness. It would work just as well to emit all
  151. of the pseudo ops other than <code>.fnend</code> in the same order, but
  152. immediately after <code>.fnstart</code>.
  153. </p>
  154. <p>The <code>.save</code> (see <a href="ARM-Directives.html#arm_005fsave">.save pseudo op</a>) pseudo op
  155. indicates registers that have been saved to the stack so that they can
  156. be restored before the function returns. The argument to the
  157. <code>.save</code> pseudo op is a list of registers to save. If a register
  158. is &ldquo;callee-saved&rdquo; (as specified by the ABI) and is modified by the
  159. function you are writing, then your code must save the value before it
  160. is modified and restore the original value before the function
  161. returns. If an exception is thrown, the run-time library restores the
  162. values of these registers from their locations on the stack before
  163. returning control to the exception handler. (Of course, if an
  164. exception is not thrown, the function that contains the <code>.save</code>
  165. pseudo op restores these registers in the function epilogue, as is
  166. done with the <code>ldmfd</code> instruction above.)
  167. </p>
  168. <p>You do not have to save callee-saved registers at the very beginning
  169. of the function and you do not need to use the <code>.save</code> pseudo op
  170. immediately following the point at which the registers are saved.
  171. However, if you modify a callee-saved register, you must save it on
  172. the stack before modifying it and before calling any functions which
  173. might throw an exception. And, you must use the <code>.save</code> pseudo
  174. op to indicate that you have done so.
  175. </p>
  176. <p>The <code>.pad</code> (see <a href="ARM-Directives.html#arm_005fpad">.pad</a>) pseudo op indicates a
  177. modification of the stack pointer that does not save any registers.
  178. The argument is the number of bytes (in decimal) that are subtracted
  179. from the stack pointer. (On ARM CPUs, the stack grows downwards, so
  180. subtracting from the stack pointer increases the size of the stack.)
  181. </p>
  182. <p>The <code>.setfp</code> (see <a href="ARM-Directives.html#arm_005fsetfp">.setfp pseudo op</a>) pseudo op
  183. indicates the register that contains the frame pointer. The first
  184. argument is the register that is set, which is typically <code>fp</code>.
  185. The second argument indicates the register from which the frame
  186. pointer takes its value. The third argument, if present, is the value
  187. (in decimal) added to the register specified by the second argument to
  188. compute the value of the frame pointer. You should not modify the
  189. frame pointer in the body of the function.
  190. </p>
  191. <p>If you do not use a frame pointer, then you should not use the
  192. <code>.setfp</code> pseudo op. If you do not use a frame pointer, then you
  193. should avoid modifying the stack pointer outside of the function
  194. prologue. Otherwise, the run-time library will be unable to find
  195. saved registers when it is unwinding the stack.
  196. </p>
  197. <p>The pseudo ops described above are sufficient for writing assembly
  198. code that calls functions which may throw exceptions. If you need to
  199. know more about the object-file format used to represent unwind
  200. information, you may consult the <cite>Exception Handling ABI for the
  201. ARM Architecture</cite> available from <a href="http://infocenter.arm.com">http://infocenter.arm.com</a>.
  202. </p>
  203. <hr>
  204. <div class="header">
  205. <p>
  206. Previous: <a href="ARM-Mapping-Symbols.html#ARM-Mapping-Symbols" accesskey="p" rel="prev">ARM Mapping Symbols</a>, Up: <a href="ARM_002dDependent.html#ARM_002dDependent" accesskey="u" rel="up">ARM-Dependent</a> &nbsp; [<a href="index.html#SEC_Contents" title="Table of contents" rel="contents">Contents</a>][<a href="AS-Index.html#AS-Index" title="Index" rel="index">Index</a>]</p>
  207. </div>
  208. </body>
  209. </html>