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

📄 exa5.html

📁 关于ARM汇编的非常好的教程
💻 HTML
字号:
<!doctype html public "-//W3C//DTD HTML 3.2//EN"><html><head><title>Example 5: A mouse test</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/exa5.html               --><!--                                     --><!--  (C) Copyright 2000 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">Example 5<br>A mouse test</font></h1>    </td>    <td align=center width=100>      <img src="arm3.gif" width=79 height=78 align = middle>    </td></table><p>&nbsp;<p>For this example, we are going to implement a simple program...<p><pre>10 MODE 12  20 OFF  30 MOUSE ON  40  50 REPEAT  60   MOUSE X%, Y%, Z%  70   PRINT TAB(0,0);X%, y%, Z%  80 UNTIL Z% = 7  90 MOUSE OFF 100 END</pre>But why stop there? Let's have a little fun. Include the following...<pre>  75 IF Z% = 4 OR Z% = 1 THEN PROCplot 110 : 120 DEFPROCplot 130 IF Z% = 4 THEN colour = 3 ELSE colour = 0 140 GCOL colour 150 POINT X%, Y% 160 ENDPROC</pre>Now, holding down SELECT will draw yellow dots, and ADJUST will draw black dots (a sort of primative 'erase').<p>&nbsp;<p>Okay, no BASIC, so you can forget about the DIMs and the OPT and the FOR NEXT loop.<br>Ready?<p>&nbsp;<p>&nbsp;<p><pre>; mousetest;; Version 0.01  8th July 2000; by Richard Murray;; Downloaded from http://www.heyrick.co.uk/assembler/;</pre>Always write a header to tell you what is going on. Some people include version changes in theheader but I prefer a seperate file. Personal choice really, if I had 2Mb of comments, the finalprogram wouldn't be affected - but I might need a pretty beefy computer to assemble it all!<p><pre>a1 RN 0a2 RN 1a3 RN 2a4 RN 3v6 RN 9sp RN 13lr RN 14pc RN 15</pre>Definitions for the registers that we shall be using.<br>a1 to a4 (R0-R3) are general purpose registers.<br>v6 (R9) is a pointer to the storage area.<br>sp, lr, and pc (R13, R14 and R15) have the expected usage.<p><pre>            AREA    |asmcode|, CODE, READONLY            ENTRY</pre>Defines the area, and sets this as the program entry point.<br>Note that this is, in fact, an error. The code area is defined as READONLY but later on we writeto it (for the storage area and the string). However, it seems the system is pretty relaxedabout things like this - however it is useful to keep an eye out for such things. Don't juststick in a standard area definition without thinking...like I just did.<br>(I shall consider myself bollocked, then, shall I? &lt;grin&gt;)<p><pre>            ; Store registers that must be preserved            MOV     sp, a2            STMFD   sp!, {v6, lr}</pre>The initial value of the stack pointer is passed to the application in R1. Actually, this is theRAM limit for the application (refer to OS_GetEnv), but it works for a fully descending stacksuch as that which is used by convention on RISC OS.<br>Remember, you are 'real' assembler programmer when you move away from BASIC. You cannot justassume the the stack pointer actually points to anything.<br>This, incidently, applies for pure assembler code written in BASIC but run in a stand-alonefashion - such as the <a href="exa2.html">compressed image loader</a>.<p>By now, you should be able to follow assembler without so many descriptions, so here goes...<pre>            ; Set v6 to point to variable storage            ADR     v6, storage            ; Select MODE 12   (VDU 22, 12)            SWI     256 + 22            SWI     256 + 12            ; OFF            SWI     &amp;36             ; OS_RemoveCursors            ; MOUSE ON            MOV     a1, #106        ; Set mouse state            MOV     a2, #1          ; 1 = on            SWI     &amp;06             ; OS_Byte            ; REPEATrepeat            ; MOUSE x%, y%, z%            SWI     &amp;1C             ; OS_Mouse            STMIA   v6, {a1-a3}     ; Store X%, Y%, Z%            ; PRINT TAB(0,0);            SWI     256 + 31        ; VDU 31, 0, 0            SWI     256            SWI     256            ; PRINT x%, y%, z%            LDR     a1, [v6, #0]    ; Retrieve X%            BL      print_integer            LDR     a1, [v6, #4]    ; Retrieve Y%            BL      print_integer            LDR     a1, [v6, #8]    ; Retrieve Z%            BL      print_integer            ; Something extra...            LDR     a1, [v6, #8]    ; Retrieve Z%            CMP     a1, #4          ; Is it 4? [SELECT]            CMPNE   a1, #1          ; If not, is it 1? [ADJUST]            BLEQ    plot            ; If either, then go to plot            ; UNTIL z% = 7    (all buttons pressed)            LDR     a1, [v6, #8]    ; Retrieve Z%            CMP     a1, #7          ; Is it 7? [SELECT, MENU, ADJUST]            BLNE    check_escape    ; If not, check for Esc press            BNE     repeat          ; If not, repeat            ; MOUSE OFF            MOV     a1, #106        ; Set mouse state            MOV     a2, #0          ; 0 = off            SWI     &amp;06             ; OS_Byte            ; END            SWI     &amp;37             ; OS_RestoreCursors            LDMFD   sp!, {v6, pc}             SWI     &amp;11             ; OS_Exit (only, we shouldn't come to here...)</pre>Of note, in this lot, are:<ul>  <li> OS_WriteC optimisations, calling OS_WriteI+ASCII. Does the same thing in only one       instruction.       <br>&nbsp;<br>  <li> The button check optimisation. Is button SELECT? If not, is it ADJUST? If either, plot.       So we implemented <code>IF Z% = 4 OR Z% = 1 THEN PROCplot</code> in only four       instructions.  <li> The '^' in the LDM instruction. This causes the PSR bits to be restored, thus the program       exits with the processor in the same state that it was in when it was entered. Though,       you won't often be calling programs in a processor mode other than User mode.</ul><p><pre>storage            DCD     0            DCD     0            DCD     0string            DCD     0            DCD     0</pre>Storage. Roughly in the middle, so it doesn't get too far for an ADR instruction to cope with.I'm not sure if <i>objasm</i> automatically does long ADRs, but it is something to be aware of asother assemblers may require an ADRL instruction instead, if they do it at all.<p>This next routine prints an integer in much the same way that BASIC does when you tell it to<code>PRINT X%</code>.<p><pre>print_integer            ADR     a2, string      ; Get address of buffer            MOV     a3, #8          ; Length of buffer            SWI     &amp;28             ; OS_BinaryToDecimal            ; Integer has been converted to a string, a3 gives size.            RSBS    a4, a3, #10     ; How many spaces left?            BEQ     no_spaces            ; print leading spaces            MOV     a1, #32         ; ASCII 32 = spacespaces_loop            SWI     &amp;00             ; OS_WriteC            SUBS    a4, a4, #1      ; Print until none left            BNE     spaces_loopno_spaces            ADR     a2, string            ; print_loop            LDRB    a1, [a2], #1            SWI     &amp;00             ; OS_WriteC            SUBS    a3, a3, #1            BNE     print_loop            MOV     pc, lr</pre>This code might seem odd, why not simply OS_Write0?<br>The string conversion SWI doesn't terminate the string, it instead gives a length count. Youcould OS_WriteN with a count, or you could do the above...<p>Because we aren't in BASIC any more, we can't rely on an Escape press having any effect. While itis inefficient to check the escape state in every loop, it isn't that much faster to maintain aloop count and do it every X times round. So, in the spirit of keeping things simple...<p><pre>check_escape            SWI     &amp;2C             ; OS_ReadEscapeState            BCS     escape_code     ; If Carry (Esc pressed), abort.            MOV     pc, lrerrblock            DCD     17            =       &quot;Escape&quot;, 0            ALIGNescape_code            MOV     a1, #126        ; Ack. Escape condition            SWI     &amp;06             ; OS_Byte            SWI     &amp;37             ; OS_RestoreCursors            ADR     a1, errblock            SWI     &amp;2B             ; OS_GenerateError</pre>Our way out is through OS_GenerateError. That causes the stored entry point to be restored (thisis done by RISC OS, and used for things like when OS_Exit is called).<p>Next comes the plot routine.<pre>plot            MOVEQ   a2, #256        ; Set colour to be black            CMP     a1, #4          ; If SELECT pressed,            ADDEQ   a2, a2, #3      ; Set colour to be yellow.            SWI     256 + 18        ; Set graphics colour            SWI     256            MOV     a1, a2            SWI     &amp;00             ; OS_WriteC            MOV     a1, #69         ; Point, absolute, foreground            LDMIA   v6, {a2-a3}     ; Load X% and Y% for plot            SWI     &amp;45             ; OS_Plot            MOV     pc, lr</pre>And, guess what? That's it!<pre>            END</pre>To make a program:<ol>  <li> Load !ObjAsm  <li> Load !Link  <li> Ensure the 'o' subdirectory exists. Create it if it doesn't.  <li> Drag your source to ObjAsm. Switch off ThrowBack if you don't have a capable editor       loaded.  <li> Click on Run.  <li> Drag the Data file that appears into the 'o' subdirectory.  <li> Now, get that Data file and drag it to Link.  <li> Click on Run.  <li> Save the Absolute file that appears.</ol>This can be automated partially with an Obey file, or automated more using a MakeFile. However,this is'nt so important at this time - when you have an application with twenty odd sources invarious languages - that is when you really need a MakeFile!<p>&nbsp;<p><div align = right><a href="sw/mousetest.txt"><i>Download example: mousetest.txt</i></a></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 + -