📄 intro.html
字号:
<!doctype html public "-//W3C//DTD HTML 3.2//EN"><html><head><title>Introduction to assembler programming</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/intro.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">Introduction to <br>ASSEMBLER</font></h1> </td> <td align=center width=100> <img src="arm3.gif" width=79 height=78 align = middle> </td></table><p> <p>26th September 2000:<br>In the first release of this assembler programming tutorial, I missed out on a vital piece ofinformation. Why the hell would you want to do this in the first place?<br>That, I cannot answer. Everybody has their reasons. Maybe your boss wants you to make somethingthat little bit faster and more efficient. Maybe you have been given the source to a programthat you often use, and it is up to you to update it. Maybe you are just doing this 'cos youthink it might be a worthwhile hobby.<p>One thing that is important is the psychology of it all. Here, in this section, I have examinedmy motives, my feelings. I'd never really thought about it before, but it makes for interestingreading.<br>I won't repeat it all here, but the two principal documents you should have a look at are:<ul> <li> <a href = "program.html">On being a programmer</a> <br> <br> <li> <a href = "hints.html">Programming hints</a></ul><p>Now, on with our scheduled documentation.....<p> <p> <p>If you want to knock up a quick little program, then you can't pick much better than BASIC.<br><pre> PRINT "HeyRick!"</pre><p>If you want to write a less-hackable program with large speed benefits, you should pick C or C++.For speed concerns, the old CastAVote vote editor (written in BASIC) took around 20 to 30 secondsto delete a vote at the beginning of a full file. The new vote editor tasks this out toVoteModule (written in C). It does it in a second.<pre> printf("HeyRick\n");</pre>If you want the ultimate speed and flexibility with the ability to perform low-level hackery,you should be looking to assembler.<br>On the left, BASIC's assembler (we'll cover this a lot); on the right, the same thing written forAcorn's <i>objasm</i> assembler...<pre> GET h.SWIs AREA |asm$$code|, CODE, READONLY ADR R0, text ENTRY SWI "OS_PrettyPrint" SWI "OS_NewLine" ADR r0, text MOV PC, R14 SWI OS_PrettyPrint SWI OS_NewLine .text MOV pc, r14 EQUS "HeyRick" EQUB 0 text DCB "HeyRick", 0 ALIGN ALIGN</pre>As you can see, assembler is much more involved. There are quicker ways to write the above, butit is a reasonable example.<p>You may know that it is possible to call BASIC functions in assembler, provided you are usingthe BASIC assembler to compile your code:<pre> MOV R0, #RND(64)</pre>But if you plan to write a fully-assembler application, you'll need to know how to write the RNDcode.<p>Lets take that example and expand it into a fully fledged application...<p><pre>REM Assembler demo #1:DIM code% 64FOR pass%=0 TO 2 STEP 2P%=code%[ OPT pass% ADR R0, text SWI "OS_PrettyPrint" SWI "OS_NewLine" MOV PC, R14 .text EQUS "HeyRick" EQUB 0 ALIGN]NEXTCALL code%</pre><div align = right><a href="sw/introdemo.basic"><i>Download this example</i></a></div><p>Let's work through the program. The first line is "<code>DIM code% 64</code>".This reserves enough memory for your program. BASIC ensures that your memory begins on a wordboundary.<p>The next line is "<code>FOR pass%=0 TO 2 STEP 2</code>". This is important, as thefirst time through, the assembler cannot resolve all the references. Therefore, in conjuctionwith the <code>OPT</code> statement, the code is actually passed twice.<br>The first time through, all errors are ignored. Then, once all references should have been setup, the code is passed again and references can be recognised.<br>Read <a href = "opt.html"><i>opt.html</i></a> for details of the available <code>OPT</code>ions.<br>If you want to see the assembly taking place, amend the line to say:<pre> FOR pass%=1 TO 3 STEP 2</pre><p>The third line, "<code>P%=code%</code>" tells the assembler where to compile the code.The variable <code>P%</code> is assumed to be the pointer to the code - so you must set it topoint to the start of the memory block before each pass.<br>Do not forget to set P% if you are cobbling together some test code in, say, a TaskWindow.Because P% is likely to be initialised to zero, and trying to compile code over the hardwarevectors is not good for the health of your data, or you...<br>If you are using offset assembly, <code>P%</code> is set to zero and the pointer to memory blockis placed in <code>O%</code> instead. This is demonstrated later on.<p><a name="opt"></a>"<code>[ OPT pass%</code>" is an important line. The opening square bracket denotesthe following code are assembler instructions. The "<code>OPT</code>" then specifieswhich compilation options are to be used this time in (refer to<a href = "opt.html"><i>opt.html</i></a> for details of the options available).<p>"<code>ADR</code>" is not a real instruction. What it does is place the address of thespecified value into the given register. In this line ("<code>ADR R0, text</code>") itplaces the address of <i>text</i> into register zero.<br><a href="pseudo.html#adr">Read this for more on ADR</a>.<p>Next, two SWIs are called. This is similar to BASIC's SYS command. Firstly "<code>SWI"OS_PrettyPrint"</code>" prints the text, and automatically wraps it to fitnicely in the available space. Secondly, "<code>SWI "OS_NewLine"</code>"prints a newline character. Unlike BASIC, this is not implicit.<p>Many registers exist, and some of them have special functions. This is detailed in<a href="regs.html"><i>regs.html</i></a>. However I shall tell you here that register 15 (alsoknown as "PC") is the program counter. When a program is started, or when a branchwith link occurs, the return address is stored in register 14 - the link register.<br>Therefore is becomes easier to understand the line "<code>MOV PC, R14</code>". Itplaces the value of R14 (currently holding the return address back to BASIC) into the programcounter. Hey presto, we are back!<p>Lastly the block "<code>.frobnicate_text</code>" defines a zero terminated string andaligns the tail end so it is on a word boundary. The definition is marked by a label following aperiod. The data follows, and is a regular instruction - thus it can be either active code, orsimply statements to load data into the current memory location.<p>The closing square bracket marks the end of an assembler section. Unlike in BASIC, a closingstatement does not mean the end of the routine. You must explicitly return before closing up, asshown in this example.<p>The "<code>NEXT</code>" matches the "<code>FOR</code>" (above).<p>Finally, we "<code>CALL code%</code>", or in other words we branch to the address ofthe variable code% and begin execution there - hence we execute the assembler section.<br>We DO NOT call <code>P%</code> as it is incremented as each instruction is compiled. Only<code>code%</code> points to the start of the assembler code.<p>Try it.<p> <p> <p>Another thing to note is that assembler is a "compiled language" similar to C, but inthe loosest sense of the concept. You cannot usually type assembler at the BASIC prompt and getit to run. Programs are written by the following steps:<ol> <li> Program coded in !Edit, or some other kind of editor. <li> Assembler is <i>compiled</i> into a machine code file. <li> Machine code file can then be executed.</ol>The sheer power of BASIC's assembler means that you can insert small sections of code into aprogram which are compiled at program initialisation, and can then be used in the program. TheBASIC language can also be used as a rather powerful macro assembler.<p>There is another way of writing assembler - the APCS specification. This method is used to linkassembler with other high-level compiled languages (such as C or Pascal), or to take advantageof Acorn's Desktop Development Environment. You can read about it<a href="apcsintro.html">here</a>, but you are advised to become familiar with assembler beforeventuring on to APCS.<p> <p> <p>The last thing to say is the notation that is used in this section. It will be familiar toBASIC coders, but may seem confusing to others...<p><pre> & Denotes a hexadecimal number. For example &16F is the number 367 in hex. Other ways of denoting hexadecimal are: $16F 0x16F 16Fh H16F >> Binary shift right, has the effect of dividing a number by the shift amount. Thus: 12 >> 1 equals 6 and: 128 >> 3 equals 16. Work this out in binary if you are unsure. << Binary shift left, has the effect of multiplying a number by the shift amount. Thus: 12 << 1 equals 24 and: 3 << 8 equals 768 % Denotes a binary number. For example %11010010 is 210 represented in binary.</pre>If you have not come across binary before, you should at least know that a computer representsdata (text, pictures, etc) as a series of bytes. These bytes themselves are comprised of eightbits. These bits reflect the ON/OFF patterns used by the computer. Binary is a way ofrepresenting these patterns is a readable form.<br>When you get the hang of binary, it is really quite simple. Binary reads from the rightmost 'bit'(called bit zero, NOT bit one) to the leftmost. The rightmost bit is equal to '1'. The secondbit is '2', and so on multiplying each time. For example:<pre> %1 1 1 0 0 1 1 1 1 1 1 1 2048 1024 512 256 128 64 32 16 8 4 2 1</pre>The upper row is an example binary number. The lower row shows the values associated with eachbit. To calculate value of the binary number, simply add it all up! As you can see, bits sevenand eight are zero, so skip them when adding...<br><center>1 + 2 + 4 + 8 + 16 + 32 + 64 + 512 + 1024 + 2048 = 3711</center><p>Finally, here's a quick tip for converting binary to hexadecimal.<br>People are not good at remembering large number sequences (well, except Carol Vorderman) andtrying to get %1011111011101111000100000110 right will prove difficult, especially if you aretrying to remember other stuff at the same time.<br>You can, however, convert between binary and hex extremely easily, and you only need to countup to 15 in binary.<br><pre>Chop the number into groups of four, remember to begin onthe right hand side: 1011 1110 1110 1111 0001 0000 0110Then convert each group of four into a single denary number: 1011 1110 1110 1111 0001 0000 0110 =11 =14 =14 =15 =1 =0 =6And convert that denary number into hex: 1011 1110 1110 1111 0001 0000 0110 11 14 14 15 1 0 6 =B E E F 1 0 6Which tells us that %1011111011101111000100000110 can bebetter remembered as &BEEF106.This process works in reverse too.Unfortunately you cannot stop at the denary version as thereis no direct co-relation between base 2 or base 16 and base10. In case you are interested, that number is 200208646.:-)</pre><hr size = "3"><a href="index.html#01">Return to assembler index</a><hr size = "3"><address>Copyright © 1999 Richard Murray</address></body></html>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -