⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tandt.html

📁 关于ARM汇编的非常好的教程
💻 HTML
字号:
<!doctype html public "-//W3C//DTD HTML 3.2//EN"><html><head><title>Tips and Tricks</title><meta http-equiv="content-type" content="text/html; charset=ISO-8859-1" /><meta http-equiv="content-language" content="en" /><meta name="resource-type" content="document"><meta name="copyright" content="This document copyright 2001 by Richard Murray. Use for non-profit and education purposes explicitly granted."><meta name="author" content="Richard Murray"><meta name="rating" content="general"></head><!--  /assembler/tandt.html              --><!--                                     --><!--  (C) Copyright 2001 Richard Murray  --><!--  Designed by Richard Murray         --><!--  rmurray@heyrick.co.uk              --><!--                                     --><body bgcolor="#f0f0f0" text="#000000" link="#0022dd" vlink="#002288"><table border = "0" width="100%">  <tr>    <td align=center width=100>      <img src="arm3.gif" width=79 height=78 align = middle>    </td>    <td>      <h1 align="center"><font color="#800080">Tips and Tricks</font></h1>    </td>    <td align=center width=100>      <img src="arm3.gif" width=79 height=78 align = middle>    </td></table><p>&nbsp;<p><h4>Count down, rather than up</h4>When you count from zero to <i>n</i>, you will need code like:<pre>  MOV    R1, #0.loop  ...do something...  ADD    R1, R1, #1  CMP    R1, #255  BNE    loop</pre>That is braindead code to do something 255 times. You could replace that code with:<pre>  MOV    R1, #255.loop  ...do something...  SUBS   R1, R1, #1  BNE    loop</pre>What, no comparison - but a conditional?<br>Yup, that's right. The <code>SUB</code> operation has the <code>S</code> suffix, so it affectsthe flags. An <code>EQ</code> condition is when the Z bit is set, and a <code>NE</code> conditionis when the Z bit is unset. And the Z bit being set means....<i>zero!</i>.<br>So this loop looks after itself, really. When the countdown ends, the result is zero, the Z bitis set, the NE condition is no longer true, so the branching ceases.<p>&nbsp;<p><h4>Don't abuse the stack</h4>If you are programming APCS code, you will know that the APCS rules state that only registersa0 to a4 (R0-R3) are corruptable. That doesn't mean you should start your code with a<pre>  STMFD  R13!, {v1-v6, sl, fp, ip, sp, lr}</pre>unless you actually need to store those registers. If you can work your code in the first fourregisters with no branching, you don't need to store anything.<br>I was unable to find a reference to which registers should be saved in BASIC, so my code haserred on the generous side. I would suggest that R0-R7 are corruptable, the remainder should bepreserved. But again, if you only use R0 to R3 (or so), you don't need to preserve anything.<p>Say you use R0, R1 and R2, and you do a few <code>BL</code>s. Should you be pushing the linkregister to the stack?<br><pre>  LDMFD  R13!, {R14}  ...doing stuff...  STMFD  R13!, {PC}</pre>The code, above, is terribly wasteful. Not only do you use a multiple load/store instruction topreserve one register, but you waste stack space.<br>Even under APCS, this might be better:<pre>  MOV    R3, R14  ...doing stuff...  MOV    PC, R3</pre>The <code>S</code> suffix causes the PSR to be restored.<p>An optimisation, when it is required to store R14 (and <i>only</i> R14) to the stack is to dosomething like:<pre>  STR    R14, [R13, #-4]!  ...do stuff...  LDR    R14, [R13], #4  MOVS   PC, R14          <font color="red">(not 32bit compatible)</font></pre>The above version preserves the PSR. If preserving is not required, then reload directly into PCand omit the <code>MOVS</code> instruction.<p>&nbsp;<p><h4>Large numbers</h4>There are two ways to load a register with a large number (say, &amp;FFFF00FF).<p>1. Synthesise it<pre>  MOV    R0, #&amp;FF000000  ADD    R0, R0, #&amp;00FF0000  ADD    R0, R0, #&amp;000000FF</pre><p>2. Load it<pre>  ADR    R1, big_word  LDR    R0, [R1]  ....big_word  EQUD   &amp;FFFF00FF</pre>I prefer to use the Load method, as it tends to make the code clearer, especially when generatinglarge numbers involves trickery with <code>BIC</code>, <code>EOR</code>, and <code>TEQ</code>.<p>Loading may save program space - it depends upon how you generate your large number - but causesthe processor to jump around to load the word.<br>Execution speed depends upon the processor. For example, it has been reported that a load isfaster on a StrongARM, where an ARM 6 gets more speed out of generating the large value fromthree instructions.<p>&nbsp;<p><h4>Multiple IFs</h4><pre>IF x% = 4 OR x% = 1 THEN ...</pre>can be implemented as something like:<pre>  [we assume x% has been loaded into R0]  CMP    R0, #4  CMPNE  R0, #1  BEQ    ...the code to call when x% = 4 OR 1  ...the ELSE code</pre><p>&nbsp;<p><h4>Branch tables</h4>You can implement code such as:<pre>  CASE something% OF    WHEN  0 : PROCzero    WHEN  1 : PROCone    WHEN  2 : PROCtwo  OTHERWISE : PROCinvalid  ENDCASE</pre>in assembler by code such as (assuming something% is in R0):<pre>  CMP    R0, #2              ; The immediate value is the range  LDRLS  PC, [PC, R0, LSL#8]  ; Program Counter set to the first EQUD  B      invalid              ; We come here if R0 > 2  EQUD   zero  EQUD   one  EQUD   two</pre><p>Or an alternative method:<pre>.entry  CMP    R0, #((endoftable - table) / 4)  ADDCC  PC, PC, R0, LSL#2  B      invalid.table  B      zero  B      one  B      two.endoftable</pre><p>My personal favourite method is the latter, but both will have the desired effect.<p>&nbsp;<p>&nbsp;<p><hr size = 3><a href="index.html#06">Return to assembler index</a><hr size = 3><address>Copyright &copy; 2001 Richard Murray</address></body></html>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -