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

📄 modcode.html

📁 关于ARM汇编的非常好的教程
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<!doctype html public "-//W3C//DTD HTML 3.2//EN"><html><head><title>Writing module code</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/modcode.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">Writing module code</font></h1>    </td>    <td align=center width=100>      <img src="arm3.gif" width=79 height=78 align = middle>    </td></table><p>&nbsp;<p><h2>Modules</h2>If ARM assembler is the heart of the computer in physical terms, then modules are the heartof RISC OS.<br>With the exception of the &quot;RISC OS&quot; module and the &quot;UtilityModule&quot;,every other part of RISC OS is replacable...<p><ul>  <li> You can softload a new Draw module.       <br>&nbsp;<br>  <li> There was a development version of the big-discs filecore floating around the clan       members, which could be softloaded.       <br>&nbsp;<br>  <li> You can upgrade your internet stack, if you have the old one, by softloading the new       one.       <br>&nbsp;<br>  <li> RISC OS 3.10 users will probably have softloaded <i>ADFSUtils</i>, <i>NetUtils</i>,       and <i>SerialUtils</i>.       <br>&nbsp;<br>  <li> I was, for a few days, running a copy of the RISC OS 4 FileCore 3.20 and ADFS 3.30 under       RISC OS 3.7. Because we all know it is <i>simply not possible</i> to do that...<br>       It didn't seem to offer much over RISC OS 3.7's, besides a whole bunch of dynamic areas,       so I've deleted it. I guess it's only really an issue if you have stupidly large discs       and plan to have stupidly large partitions. Pretty much counts me out then... :-)       <br>&nbsp;<br>  <li> Who isn't running WindowManager 3.98?</ul><p>The major benefit of modules is that they can link into parts of the operating system toprovide new SWI calls, handle ServiceCalls, deal with exceptions, or simply sit on anevent waiting for something to happen. For example, on my current setup:<p><ul>  <li> FPEmulator<br>       This one sits on the Undefined Instruction hardware vector, and if it recognises the       instructions as being one of its own, it provides a software-emulated maths       co-processor (<a href="fpops.html">click for more information</a>).       <br>&nbsp;<br>  <li> DiscAccess<br>       This sits on a variety of filing system vectors and blinks the Scroll Lock key when       something happens - an emulated harddisc indicator light!<br>       <a href="exa7.html">Refer to example 7 for source</a><br>       <font size = -1>(this was written in France using my A3000 - I don't use DiscAccess on       the RiscPC as it has an HD indicator!)</font>       <br>&nbsp;<br>  <li> HotBlanker<br>       This module, by DizzyWizard Software, sits on the Event vector, and waits for Right       Alt and Right Ctrl to be pressed together. When they are, it kicks in the screenblanker.       <br>&nbsp;<br>  <li> DrawFile<br>       This module makes the display of Draw files so much easier, with a single * command to       render a Draw file, or a few SWIs if you would like more control without the hassle of       using Draw directly.<br>       <font size = -1>(this is included in RISC OS 3.5 and later)</font>       <br>&nbsp;<br>  <li> FreeMem<br>       This provides a tiny Wimp application which sits on the iconbar and tells you how       much memory is free.<br>       The massive advantage of a module WIMP task is that it uses memory in the RMA and       in self-claimed RMA blocks. It does not (normally) use application memory, and is       therefore not constrained to having a 32K slot for a 4K program.<br>       The general exceptions to this rule are task modules written in a high-level language.       A task module written in C will install itself as a regular task. Sorry, but this is one       thing that should be done in assembler.</ul><p>&nbsp;<p><h2>The RISC OS module?</h2>There is a hidden module on all machines. In Arthur, it was called &quot;Arthur&quot;. InRISC OS, it is called - nonsurprisingly - &quot;RISC OS&quot;.<br>This module will not show up with <code>*Modules</code> or <code>*ROMModules</code>. If youtry <code>*Help Commands</code> then you will see it listed first.<p>A quick perusal of the Arthur 1.20 module gives us the following error messages:<br><ul>  <li> Can't initialise heap  <li> Bad heap descriptor  <li> No more incarnations of that module  <li> Podule chunk is not a relocatable module  <li> No room in RMA  <li> Bad vector number  <li> System heap full  <li> Unable to move memory  <li> !!!! CAM Map Corrupt !!!!  <li> Sys$ReturnCode  <li> Buffer overflow</ul><p>RISC OS 3.7 offers messages such as:<ul>  <li> Base address not on page boundary  <li> Unable to allocate logical address space  <li> No room on supervisor stack  <li> No L2PT for page being removed  <li> Physical address not found  <li> Unable to allocate page tables for area</ul><p>RISC OS 4 apparently includes references to chocolate. <tt>:-)</tt><p>This isn't listed as a module as it isn't a module, really. It has no start code, initialisationcode, finalisation code, service call handler... It doesn't need any, it is the base level ofRISC OS.<p>Upon this, all the other modules are loaded. These all come together to form the operatingsystem known as RISC OS.<p>&nbsp;<p><h2>SWIs</h2>A SWI is a SoftWare Interrupt. It causes the system to search for a chunk of code pertainingto the SWI call numbered (name to number translation is a language-dependent issue). Theexact mechanics of how this works <a href="swi.html">is described here</a>. What you need toknow is when the user calls your SWI, the OS calls your SWI handler with a number from 0 to63 corresponding with that requested by the user.<p>All modules have a chunk address. This is divisible by 64, and means that each module canhave 64 SWIs. The WindowManager has many, the UtilityModule has none.<p>The chunk numbers are, typically, allocated on a request basis. As far as I am aware, youcan complete the required entries in <i>!Allocate</i>, and email it to RISC OS Ltd (I think theaddress is <a href="mailto:allocate@riscos.com">allocate@riscos.com</a>), and they will replyyes or no.<br>It is entirely possible to allocate the chunks yourself on an ad-hoc basis (I tend to reusethe &amp;16F00 chunk for development code), but you should not complain if it clashes withsomething, neither should you <b>EVER</b> release such a module - it could cause untoldchaos.<p>&nbsp;<p><h2>32-bit issues</h2>When running in 32-bit, a 32-bit version of RISC OS will make no use of 26-bit modes (if theyare available, newer processors such a Xscale (StrongARM 2) don't support 26-bit at all).Although a 26-bit mode may be available, there will be no run-time selection of which mode isto be used, and the memory mapping may preclude the use of 26-bit mode.<p>An effective way to handle mode issues is to use a macro. Code can therefore be compiled for26-bit only, or 32-bit only simply by using the macros. Then, in (say) an obey file, you canchoose which module version to load depending upon what OS is running. If a 32-bit OS is running,you load the 32-bit module, and so on.<p>The general API is pretty much the same. The main difference is that R14 on entry is just thereturn address, with no flags. To preserve flags, CPSR should be stacked on entry and restoredon exit. Note that you are now <i>preserving</i> flags across the duration of your call, ratherthan <i>restoring</i> the caller's flags (which were previously passed in R14).<p>SWIs are no longer required to preserve N, Z, and C. They may still set/clear to return results,but 32-bit code shouldn't assume that SWIs preserve flags. Requiring SWIs to do so would imposean unacceptable delay on the SWI system. This, incidentally, respecifies ALL of the SWIs, and itmakes it impossible for non-kernel SWIs to depend on NZCV flags on entry.<p>Many existing APIs don't actually require flag preservation, so you can usually get away with:<ul>  <li> <code>MOVS PC, ...</code><br>       becomes<br>       <code>MOV&nbsp;&nbsp;PC, ...<code>       <br>&nbsp;<br>  <li> <code>LDM R13!, {...}^<br>       becomes<br>       <code>LDM R13!, {...}<code></ul><p>More 32-bit issues are included for each module entry point.<p>Any given system will be either 26-bit or 32-bit. It won't vary from one mode to another. Thusit is suggested that if your code supports both modes internally, you need only check the currentmode in the initialisation code, rather then at the start of each entry point.<p>A snippet of code to check if you are in a 26-bit mode or a 32-bit mode is:<pre>  TEQ     PC, PC</pre>This sets the flags so a comparison is EQ if in a 32-bit mode (because the PC is only the PC,thus it is equal), and NE if in a 26-bit mode (because one PC is purely the PC, the other is PCwith flags, thus the two are not equal).<br>To clarify:<pre>  ; Check processor mode  TEQ     PC, PC  BEQ     mode_32bit ; branch to 32-bit code  ; else we are in 26-bit mode</pre><p>&nbsp;<p><h2>Instantation</h2>A word used very often when talking about modules.<br>It is important, because a well written module will offer several instantations of itself, so itis performing the same task in several ways, with only one copy of the module code loaded intomemory.<br>The best example of this is the FileCore module. If you type <code>*Modules</code>, you arelikely to see:<pre>  FileCore%ADFS  FileCore%RAMFS  FileCore%IDEFS  FileCore%Base</pre>This shows us that FileCore is providing services to three different filing systems, using threedifferent instantations of itself. With only one FileCore module loaded.<p>&nbsp;<p><h2>Workspace</h2>RISC OS generously allocates one word of workspace to each module instantation. Usually, themodule will require more workspace, so it is expected that you will claim using OS_Module toallocate a chunk of the RMA, setting your private word to be a pointer to the claimed workspace.When the module is called through an entry point, RISC OS sets R12 to point to this private word,so you can easily figure out the true workspace address using:<pre>  LDR  R12, [R12]</pre>RISC OS works on the above assumption, and provides a few default actions for you. For example,when a module is killed RISC OS will attempt to free claimed workspace using the private wordafter your finalisation code has been called.<br>Additionally, it alters your workspace pointer following reallocation with RMTidy (though, thisisn't really important as RMTidy has never really worked in practice - modules get <i>really</i>upset.<p>Please note that workspace allocated through <code>OS_Module, 6</code> will always start at address &amp;xxxxxxx4. The PRM says: &quot;<i>This enables code written for time-criticalsoftware (eg sound voice generators and FIQ handlers) to be aligned within the modulebody</i>&quot;. Try it. Type <code>*Modules</code> and look at the workspace column. I'veprogrammed RISC OS for over a decade and never realised that before!<p>&nbsp;<p><h2>Errors</h2>You must obey certain rules, namely:<ul>  <li> Always call X-form SWIs and check for errors       <br>&nbsp;<br>  <li> If no error has occurred, you must preserve the appropriate registers (for the entry       point in question) and the V flag must be clear.       <br>&nbsp;<br>  <li> If an error <i>has</i> occured:       <ul>         <li> Set R0 to point to the error block         <li> Preserve appropriate registers         <li> Set the processor's overflow (V) flag         <li> Return to caller       </ul></ul><p>&nbsp;<p><h2>The module header</h2>A module is defined by a set of words at the very start. These are:<table>  <tr>    <td bgcolor="#cfcfcf"> <u>Offset</u>&nbsp;&nbsp;    <td bgcolor="#cfcfcf"> <u>Contains offset to</u>  <tr>    <td colspan=2> &nbsp;  <tr>    <td> &amp;00    <td> <a href="#start">Start code</a>  <tr>    <td> &amp;04    <td> <a href="#init">Initialisation code</a>  <tr>    <td> &amp;08    <td> <a href="#fini">Finalisation code</a>  <tr>    <td> &amp;0C    <td> <a href="#svccl">Service call handler</a>  <tr>    <td> &amp;10    <td> <a href="#title">Title string</a>  <tr>    <td> &amp;14    <td> <a href="#help">Help string</a>  <tr>    <td> &amp;18    <td> <a href="#cmnd">Help and command keyword table</a>  <tr>    <td> &amp;1C    <td> <a href="#swichunk">SWI chunk base number (<i>optional</i>)</a>

⌨️ 快捷键说明

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