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

📄 exa6.html

📁 关于ARM汇编的非常好的教程
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<code>extern blah function_name(blah, blah)</code> statement.<p>Unlike coding when you are writing a little assembler program, there are solid rules that shouldbe obeyed here:<ul>  <li> Registers <code>a1</code> to <code>a4</code> (R0-R3) are alterable. You can corrupt these       without worry.<br>       <i>All other registers <b>must</b> be preserved.</i> The compiler may have placed values       in these registers, such as loop counters, and failure to restore them could have       devastating consequences.  <li> You <i>should</i> implement an APCS stack frame if your function is likely to call other       functions, or is quite large (or if you don't quite trust your code yet - but shhhh, you       didn't hear me saying that!).<br>       I, personally, find it useful to put in stack frames into most of my development code.       Then, if something should go wrong, I can know better where to look.  <li> And the one that caught me out, when you use <code>SWI OS_WriteS</code>, always ensure       that your strings are null terminated. Otherwise the OS will carry on printing stuff       until it reaches a null - some of that stuff having been your instructions!</ul>You will see that we have defined a macro called <code>HEAD</code>. This inserts a functionname just before the APCS stack frame. You can see it in action in the <code>|fix_picture|</code>definition. The macro should be called <i>immediately</i> prior to the code which sets up thestack frame, and it should be before the procedure entry point - as it is not executed. Exactlyas shown. If you enter your function with code before the stack frame is set up (which, initself, is highly unorthodox), you must <tt>B</tt>ranch beyond, as shown:<pre>|my_routine|   ...your pre-entry code here...   B      skip_head_my_routine   HEAD   ("my_routine")skip_head_my_routine   MOV    ip, sp   STMFD  sp!, {a1, a2, fp, ip, lr, pc}   SUB    fp, ip, #4   ...your routine code...   LDMEA  fp, {fp, sp, pc}^</pre><font color="red">This is not 32-bit friendly.</font><p>I suppose, at a pinch, such breaking of the rules would be allowed for handlers which need toexit in a real hurry. A sort of <code>CMP a1, #somevalue</code> then <code>MOVNE pc, lr</code>.<p>I should explain, that registers <code>a1</code> and <code>a2</code> contain data passed to thefunction, so they are saved on the stack frame. Also, the value of <code>pc</code> is stored,so it may be evaluated during a backtrace. We don't want to restore it though, so the framepointer value is subtracted by four. <code>ip</code> is used to refer to the original positionof the stack pointer, so write-back doesn't mess it up - this is later restored so the entirestack frame can be easily dumped.For a full explanation of how this stuff works, you will needto consult the PRMs.<p>The code is lightly commented, so no in-line comments will be given. If you are attempting this,it is assumed that you have worked through the earlier examples so can follow my coding...<p><font color = "red">This is not 32-bit friendly.</font><p><pre>; picfixer;; Assembler code for &quot;fixpiccy&quot; utility.;;; Version 0.01  Saturday, 15th July 2000; by Richard Murray;; Downloaded from http://www.heyrick.co.uk/assembler/;a1 RN 0a2 RN 1a3 RN 2a4 RN 3v1 RN 4v2 RN 5v3 RN 6fp RN 11ip RN 12sp RN 13lr RN 14pc RN 15        ; Our code area is &lt;C$$code&gt;, created by the compiler        AREA  |C$$code|, CODE, READONLY        ; Only one procedure to export - the piccy fixer        EXPORT |fix_picture|        ; This macro sets up the APCS backtrace 'name'        MACRO        HEAD     $name        =        $name, 0        ALIGN        &amp;        &amp;FF000000 :OR: (:LEN: $name + 4 :AND: -4)        MEND; &quot;fix_picture&quot;;; Entry:;   R0 = Pointer to full filename;   R1 = '1' if quiet mode.;; Uses:;  R4 = Preserved copy of filename pointer;  R5 = Preserved copy of quiet mode flag;  R6 = File handle;; On exit, registers preserved.;        HEAD    (&quot;fix_picture&quot;)|fix_picture|        MOV     ip, sp        STMFD   sp!, {a1, a2, fp, ip, lr, pc}        SUB     fp, ip, #4        STMFD   sp!, {v1-v3}        MOV     v1, a1                          ; Preserve filename pointer        MOV     v2, a2                          ; Preserve '-quiet' status        MOV     v3, #0        ; Open sprite file        MOV     a2, a1        MOV     a1, #&amp;CF                        ; Open for update (read/write)        SWI     &amp;2000D                          ; XOS_Find        BVS     error_opening        CMP     a1, #0                          ; Valid file handle?        BEQ     error_opening        MOV     v3, a1                          ; Preserve file handle        ; Set file pointer to 52        MOV     a1, #1        MOV     a2, v3        MOV     a3, #52        SWI     &amp;20009                          ; XOS_Args        ; Read byte        MOV     a2, v3        SWI     &amp;2000A                          ; XOS_BGet        BCS     read_error        CMP     a1, #28                         ; MODE 28?        BEQ     is_mode28        CMP     a1, #21                         ; MODE 21?        BEQ     is_mode21        ; Else, some other mode...        CMP     v2, #1        BEQ     close_file                      ; If quiet, return silently        SWI     &amp;01                             ; OS_WriteS        =       &quot;  Sprite is MODE &quot;, 0        ALIGN        ADR     a2, mode_buffer        MOV     a3, #4        SWI     &amp;DA                             ; OS_ConvertInteger2        SWI     &amp;02                             ; OS_Write0        SWI     &amp;01                             ; OS_WriteS        =       &quot;, cannot convert this&quot;, 13, 10, 13, 10, 0        ALIGNclose_file        MOV     a1, #0                          ; Close file        MOV     a2, v3        MOV     a3, #0        CMP     v3, #0                          ; Don't do it if file=0 (close all)        SWINE   &amp;2000D                          ; XOS_Findreturn        LDMFD   sp!, {v1-v3}        LDMEA   fp, {fp, sp, pc}^mode_buffer        DCD     0        DCD     0error_opening        CMP     v2, #1        BEQ     return                          ; If quiet, return silently        SWI     &amp;01                             ; OS_WriteS        =       &quot;  Unable to open file &quot;, 34, 0        ALIGN        MOV     a1, v1        SWI     &amp;02                             ; OS_Write0        SWI     &amp;01                             ; OS_WriteS        =       34, 13, 10, 13, 10, 0        ALIGN        B       returnread_error        CMP     v2, #1        BEQ     close_file                      ; If quiet, return silently        SWI     &amp;01                             ; OS_WriteS        =       &quot;  Unable to read from file &quot;, 34, 0        ALIGN        MOV     a1, v1        SWI     &amp;02                             ; OS_Write0        SWI     &amp;01                             ; OS_WriteS        =       34, 13, 10, 13, 10, 0        ALIGN        B       close_filewrite_error        CMP     v2, #1        BEQ     close_file                      ; If quiet, return silently        SWI     &amp;01                             ; OS_WriteS        =       &quot;  Unable to write to file &quot;, 34, 0        ALIGN        MOV     a1, v1        SWI     &amp;02                             ; OS_Write0        SWI     &amp;01                             ; OS_WriteS        =       34, 13, 10, 13, 10, 0        ALIGN        B       close_fileis_mode28        CMP     v2, #1        BEQ     close_file                      ; If quiet, return silently        SWI     &amp;01                             ; OS_WriteS        =       &quot;  Sprite is MODE 28, no conversion necessary&quot;, 13, 10, 13, 10, 0        ALIGN        B       close_fileis_mode21        MOV     a1, #1                          ; Setting file pointer back to 52        MOV     a2, v3        MOV     a3, #52        SWI     &amp;20009                          ; XOS_Args        MOV     a1, #28        MOV     a2, v3        SWI     &amp;2000B                          ; XOS_BPut        BVS     write_error        CMP     v2, #1        BEQ     close_file                      ; If quiet, return silently        SWI     &amp;01                             ; OS_WriteS        =       &quot;  Sprite converted to MODE 28&quot;, 13, 10, 13, 10, 0        ALIGN        B       close_file        END</pre><p><hr size = 3><div align=right><a href="sw/fixpiccy.zip"><i>Download example sources: fixpiccy.zip</i></a><br><font size=-2><i>This code requires <i>objasm</i> and (optionally) Norcroft C</i></font></div><p><hr size = 3><a href="index.html#15">Return to assembler index</a><hr size = 3><address>Copyright &copy; 2000 Richard Murray</address></body></html>

⌨️ 快捷键说明

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