home *** CD-ROM | disk | FTP | other *** search
/ The Datafile PD-CD 5 / DATAFILE_PDCD5.iso / utilities / f / forthmac / !Forthmacs / docs / ascii / armassem < prev    next >
Encoding:
Text File  |  1997-05-01  |  18.6 KB  |  574 lines

  1.  
  2. ARM Assembler
  3. *************
  4.  
  5.  
  6. Using the assembler
  7. ===================
  8.  
  9. Coding in ARM assembler is very straightforward.  If you have used an ARM 
  10. Assembler before, you will already know the instructions.  Otherwise I 
  11. recommend 
  12.  
  13. 'Acorn Risc Machine Family Data Manual, Prentice Hall, ISBN 0-13-781618-9' 
  14.  
  15. for further information.  It tells you everything about the ARM cpu you should 
  16. know and covers the whole instruction set plus lots of hardware details.  In 
  17. fact it was my only source of information at hand when starting this 
  18. RISC OS Forthmacs port.  
  19.  
  20. This documentation is by far not complete, but it covers most aspects.  If you 
  21. are writing code, just have a look at some kernel sources and see how it 
  22. works.  Whenever you are not sure about the produced code, have a look at it 
  23. by 
  24.     code demo ...... c;
  25.     see demo
  26. and you have the code just in front of you.  
  27.  
  28. Also there is a chapter "Assembler Tutorial".  
  29.  
  30. As most Forth assemblers are, this assembler is really just a vocabulary which 
  31. contains the words for assembling ARM code.  It is "activated" by adding the 
  32. assembler vocabulary to the search order.  There are also some common ways to 
  33. control assembly which do more than just put the assembler vocabulary in the 
  34. search order.  It also uses a 'data first - operand last' syntax as Forth 
  35. generally does.  
  36.  
  37. Lets now have a look at some kernel source and see what the syntax looks like 
  38. in the forth assembler syntax and in the original Acorn Syntax ( displayed by 
  39. the disassembler utility).  
  40.  
  41. code count      (s adr -- adr1 cnt ) 
  42.         r0      top     mov
  43.         top     r0 byte )+ ldr
  44.         r0      sp      push c;
  45. see count
  46. code count 
  47.  (   a148 )  mov     r0,r10
  48.  (   a14c )  ldrb    r10,[r0],#1
  49.  (   a150 )  str     r0,[r13,#-4]!
  50.  (   a154 )  ldr     pc,[r8],#4
  51.  
  52.  
  53. General syntax
  54. ==============
  55.  
  56. All instructions follow the general syntax: 
  57.  
  58.         ARM:        opcode  r-dest r-n operand
  59.         Forth:      r-dest r-nsrc operand modifiers  condition op-code
  60.  
  61.  
  62. The brackets and commas in the original assembler source are replaced by 
  63. spaces, 'addressing mode indicators' and macros.  The 
  64.  
  65. ia [r0],#4 will be )+ , indicating a postincrement by 1 or 4 according to 
  66. byte/word access.  
  67.  
  68. push is a macro meaning 
  69.     -( str.
  70.  
  71. c; at the end assembles a next instruction 
  72.     ldr     pc,[r8],#4
  73.     pc  ip )+  ldr
  74. and quits assembling.  
  75.  
  76. The operands ( registers or numbers ) must appear in the correct order 
  77. followed by modifiers.  
  78.  
  79.  
  80. Conditions
  81. ==========
  82.  
  83. All instructions can be conditionally executed on ARM cpus.  All condition 
  84. codes are implemented, they should be preferably written just before the 
  85. opcode itself.  You don't have to write down the AL condition, it is the 
  86. default.  
  87.  
  88. Note: According to ARM standards, NV is not implemented and should never be 
  89. used because of future instruction set extensions.  
  90.  
  91. Condition codes available : EQ NE CS CC MI PL VS VC HI LS GE LT GT LE AL 
  92.  
  93.  
  94. Shifts
  95. ======
  96.  
  97. There a numerous shifts for operators available, 
  98.  
  99. ASL #ASL LSL #LSL LSR #LSR ASR #ASR ROR #ROR RRX , 
  100.  
  101. all shift operator leaded by a # mean count of shift specified by a number, 
  102. otherwise by a register.  
  103.  
  104. This assembler is clever enough to find out shifted immediates itself, so you 
  105. don't have to worry about lines like 
  106.     top th f0 #  td 24 #lsl mov
  107. just write 
  108.     top th f0000000 # mov
  109. instead.  
  110.  
  111.  
  112. Register usage
  113. ==============
  114.  
  115. Registers R0 - R6 are available for use within code definitions.  Don't try to 
  116. use them for permanent storage, because they are used by many code words with 
  117. no attempt to preserve the previous contents.  
  118.  
  119.     r9      user area pointer       up
  120.     r10     top-of-stack register   top
  121.     r11     return stack pointer    rp
  122.     r12     instruction pointer     ip
  123.     r13     stack pointer           sp
  124.     r14     link register           lk
  125.     r15     pc + status + flags     pc
  126. Note: In future CPU Versions, the internal structure of the pc register will 
  127. be different, it seems to be better, to imagine pc and status register as two 
  128. registers.  The hardware-errors and the .registers instruction know about this 
  129. already.  
  130.  
  131.  
  132. Structured programming
  133. ======================
  134.  
  135. This assembler supports structured programming not by using labels but common 
  136. forth-like structures instead.  The structures do not have to fit on one line, 
  137. and they may be nested to any level.  The range of the branches assembled by 
  138. these structures is not restricted.  
  139.  
  140. Implemented structures are: 
  141.     set the flags                   \ produce the condition
  142.     condition if ...                \ if condition is met do this
  143.               else ...              \ otherwise this
  144.               then
  145.     
  146.     
  147.     
  148.     begin ....
  149.           set the flags             \ produce the condition
  150.     condition     while ...         \ do this when condition met
  151.           ( you may set the flags )
  152.     ( condition ) repeat            \ the repeat is normally always done
  153.                                     \ but you may also test for another
  154.                                     \ condition.
  155.     
  156.     
  157.     begin ...
  158.           set the flags             \ produce the condition
  159.     condition until                 \ leave the loop when condition is met
  160.     
  161.     
  162.     
  163.     begin ... again                 \ loop until whatever may happen
  164.  
  165.  
  166. Porting
  167. =======
  168.  
  169. The ARM assembler can be used also by other Forth systems, all hardware 
  170. specific parts are written portable and can be changed in case of problems 
  171. very easily.  So a 68k-Forthmacs can metacompile ARM code by this assembler 
  172. without any change.  In fact, the very first metacompilation of this 
  173. RISC OS Forthmacs took place on an ATARI-ST having 1MB Ram and a 720k disk.  
  174.  
  175.  
  176. Byte-sex
  177. ========
  178.  
  179. Both byte-sexes can be produced by this assembler, this allows portable 
  180. assembler code for all ARM CPUs.  LITTLE-ENDIAN and BIG-ENDIAN do the switch.  
  181.  
  182.  
  183. ARM2/3/6
  184. ========
  185.  
  186. The assembler takes care of some cpu dependent restrictions, ARM2 disallows 
  187. the more advanced instructions, ARM3 allows them.  
  188.  
  189.  
  190. Forth Virtual Machine Considerations
  191. ====================================
  192.  
  193. The Forth parameter stack is implemented with r13, but the name sp should be 
  194. used instead of r13, in case the virtual machine implementation should change.  
  195.  
  196. The return stack is implemented with r11, and the name rp should be used to 
  197. refer to it.  
  198.  
  199. The base address of the user area ( the user pointer) is r9 but should be 
  200. referred to as up. User variable number 124 (for instance) may be accessed 
  201. with the 
  202.     up td 124 d)
  203. addressing mode.  There is a macro 'user which will assemble this addressing 
  204. mode for you.  
  205.  
  206. The interpreter pointer ip is r12.  The interpreter is post-incrementing, so 
  207. when a code definition is being executed, ip points to the token after the one 
  208. being executed.  A "token" is the number that is compiled into the dictionary 
  209. for each Forth word in a definitions.  For RISC OS Forthmacs, a token is a 
  210. 32-bit absolute address.  
  211.  
  212.  
  213. Assembler Glossary 
  214. ===================
  215.  
  216.  
  217. ____ pc             ( -- n )                                
  218. portable name for the pc register 
  219. ____
  220.  
  221. ____ sp             ( -- n )                                
  222. portable name for the stack pointer 
  223. ____
  224.  
  225. ____ up             ( -- n )                                
  226. portable name for the user pointer 
  227. ____
  228.  
  229. ____ ip             ( -- n )                                
  230. portable name for the instruction pointer 
  231. ____
  232.  
  233. ____ rp             ( -- n )                                
  234. portable name for the return stack pointer 
  235. ____
  236.  
  237. ____ top            ( -- n )                                
  238. portable name for the top of stack register 
  239. ____
  240.  
  241. ____ 'user          ( --  )        'name'                   
  242. Executed in the form: 
  243.          top   'user <name>   ldr
  244. <name> is the name of a User variable.  Assembles the appropriate addressing 
  245. mode for accessing that User variable.  
  246.  
  247. In RISC OS Forthmacs, the addressing mode for User variables is 
  248.                  up #n d)
  249. where #n is the offset of that variable within the User area.  
  250. ____
  251.  
  252. ____ ;code          ( --  )                  C,I            semi-colon-code
  253.                     ( --  )
  254. Used in the form: 
  255.                  : <name>  ... create ... ;code ... c; (or end-code)
  256. Stops compilation, terminates the defining word <name>, executes 
  257. arm-assembler, and does do-entercode. 
  258.  
  259. When <name> is later executed in the form: 
  260.                  <name> <new-name>
  261. to define the word <new-name>, the later execution of <new-name> will cause 
  262. the machine code sequence following the ;code to be executed.  
  263. ____
  264. This is analogous to does>, except that the behavior of the defined words 
  265. <word-name> is specified in assembly language instead of high-level Forth.  
  266.  
  267. ;code calls do-entercode, this is implementation specific and used to assemble 
  268. some instructions to set the parameter-field-address on top the code needed to 
  269. start the assembler code with the body of the defined 
  270.          top     sp      push
  271.          top     lk      th fc000003 # bic
  272. From version 3.1/2.62 on this isn't the case any more, you have to write those 
  273. instructions yourself.  
  274.  
  275. See: code does> 
  276.  
  277.  
  278. ____ adr            ( rx addr --  )                         
  279. Assembler macro with the following effect: 
  280.  
  281. addr is moved to register rx.  Within short distances this is achieved by a 
  282. pcr instruction, otherwise it's more complicated.  
  283.  
  284. Note: The address will be relocated correctly! 
  285. ____
  286.  
  287. ____ aligning?      ( -- addr  )                            
  288. variable holding flag, true means assembler does aligning on its own.  
  289. Implemented for CPU independent metacompiling.  
  290. ____
  291.  
  292. ____ alu-instructions  ( r-dest r-op1 op2{r-op2|imm} --  )   
  293. Available instructions with this syntax: 
  294.  
  295. AND EOR SUB RSB ADD ADC SBC RSC TST TEQ CMP CMN ORR BIC  
  296.  
  297. These instructions all have two data-inputs to the alu, the register r-op1 and 
  298. the operand op2.  This can be another register or an 8-bit immediate.  
  299.  
  300. The register r-op2 can be "shifted" in any way specified by a shift specifier, 
  301. either a 5-bit integer or another register plus the shifted register.  The 
  302. immediate operand can be rotated right by 2*(4-bit-integer).  
  303.  
  304. If you give "large" literals as arguments, the assembler will generate the 
  305. correct shifts itself.  
  306.  
  307. The # modifier declares an immediate operand as in: \ top r0 3 # add 
  308.  
  309. The S modifier will set the flags according to the result, the instruction 
  310. will be ADDS instead of ADD .  
  311. ____
  312. MOV and MVN are somewhat different, the operand r-op1 isn't needed.  Also, 
  313. both can handle "big" immediates themselves, 
  314.          top th 12345678 # mov
  315. won't be a problem, MOV assembles all instructions needed.  
  316.  
  317. CMP and CMN can both handle negative immediate operandes, they try to find out 
  318. which operand is possible.  
  319.  
  320.  
  321. ____ asm-allot      ( n --  )                deferred       
  322. Allocates n bytes in the dictionary.  The address of the next available 
  323. dictionary location is adjusted accordingly.  
  324.  
  325. default allot, implemented for ( cpu independent ) metacompiling.  
  326. ____
  327.  
  328. ____ arm-assembler  ( --  )                                 
  329. Execution replaces the first vocabulary in the search order with the 
  330. arm-assembler vocabulary, making all the assembler words accessible.  
  331. ____
  332.  
  333. ____ big-endian     ( -- )                                  
  334. Switches assembler to big-endian target code 
  335. ____
  336.  
  337. ____ branch         ( addr --  )                            
  338. Assembles a branch instruction to here.  Can be modified by dolink and all 
  339. condition codes.  
  340. ____
  341.  
  342. ____ byte           ( -- )                                  
  343. modifier for the assembler, memory accesses mean byte wide access 
  344. ____
  345.  
  346. ____ code           ( --  )        'name'    M              
  347. A defining word executed in the form: 
  348.                  code <name> ... end-code or c;
  349. Creates a dictionary entry for <name> to be defined by a following sequence of 
  350. assembly language words.  Words thus defined are called code definitions or 
  351. primitives.  Executes arm-assembler and sets the opcode defaults .  
  352.  
  353. This is the most common way to begin assembly.  
  354.  
  355.  
  356. See: end-code c; 
  357. ____
  358.  
  359. ____ c;             ( --  )                                 c-semi-colon
  360. Terminates the current code definition and allows its name to be found in the 
  361. dictionary.  
  362.  
  363. Sets the context vocabulary to be same as the current vocabulary (which 
  364. removes the arm-assembler vocabulary from the search order, unless you have 
  365. explicitly done something funny to the search order while assembling the 
  366. code).  
  367.  
  368. Executes next to assemble the "next" routine at then end of the code word word 
  369. being defined.  The "next" routine causes the Forth interpreter to continue 
  370. execution with the next word.  
  371.  
  372.  
  373. This is the most common way to end assembly, calls end-code. 
  374. ____
  375.  
  376. ____ conditions     ( --  )                                 
  377. All instruction are executed only if the correct condition is met, the 
  378. assemblers default is AL (always), but these are also available: 
  379.  
  380. EQ NE CS CC MI PL VS VC HI LS GE LT GT LE AL 
  381. ____
  382.  
  383. ____ decr           ( reg n# --  )                          
  384. Macro, n# will be subtracted from reg.  
  385. ____
  386.  
  387. ____ dolink         ( --  )                                 
  388. modifier for branch instruction, the current pc will be saved to the link 
  389. register.  
  390. ____
  391.  
  392. ____ end-code       ( --  )                                 
  393. Terminates a code definition and allows the <name> of the corresponding code 
  394. definition to be found in the dictionary.  
  395.  
  396. The context vocabulary is set to the same as the current vocabulary (which 
  397. removes the arm-assembler vocabulary from the search order, unless you have 
  398. explicitly done something funny to the search order while assembling the 
  399. code).  
  400.  
  401. The next routine is not automatically added to the end of the code definition.  
  402. Usually you want next to be at the end of the definition, but sometimes the 
  403. last thing in the definition is a branch to somewhere else, so the next at the 
  404. end is not needed.  
  405.  
  406.  
  407. See: c; 
  408. ____
  409.  
  410. ____ entercode      ( --  )                                 
  411. Starts assembling after stack checking, setting the assembler defaults and 
  412. switching to arm-assembler. 
  413.  
  414. See: do-entercode ;code 
  415. ____
  416.  
  417. ____ get-link       ( -- reg --  )                          
  418. Assembler macro, equivalent for: 
  419.     lk fc000003 # bic
  420. this is useful to get the address after a branch instruction.  
  421.     xxxxx dolink branch  ---+
  422.       A) data ...           |
  423.                             |
  424.                             |
  425.       B) top get-link  <----+
  426. So after branching to B), top will be set to A) 
  427. ____
  428.  
  429. ____ incr           ( reg n# --  )                          
  430. Macro, n# will be added to reg.  
  431. ____
  432.  
  433. ____ label          ( --  )        'name'    F83            
  434. A defining word used in the form: 
  435.     label <name> ... end-code
  436.     label <name> ... c;
  437. Creates a dictionary entry for <name> consisting of a following sequence of 
  438. assembly language words.  When <name> is later executed, the address of the 
  439. first word of the assembly language sequence is left on the stack.  
  440.  
  441.  
  442. See: end-code 
  443. ____
  444.  
  445. ____ ldm            ( rx1 rx2 .. rxn  n#  r-adr --  )       
  446. Load multiple registers from the address pointed to by r-adr, an addressing 
  447. modes must be defined.  
  448.  
  449. The register list is given by all register names (don't name a register twice) 
  450. and the number of registers.  
  451.      r0 r1 r2 r3 4   sp ia! ldm
  452. This loads registers r0-r3 from the stack and sets the stack pointer to the 
  453. next stack entry.  
  454.  
  455.  
  456. See: ldr stm 
  457. ____
  458.  
  459. ____ ldr            ( r-data r-adr operand2 --  )           
  460. r-data is read from memory, the default is word (32-bit) wide, but the 
  461. modifier byte sets this byte-wide access.  
  462.  
  463. The address is calculated using r-adr and the operand2.  It can be another 
  464. register (the shift specified as usual by a 5-bit literal and a shift type) or 
  465. a 12-bit immediate offset.  
  466.  
  467. operand2 can be added to or subtracted from r-adr according to the addressing 
  468. mode defined by two letters.  The first tells whether (i)ncreasing or 
  469. (d)decreasing should be used, the second whether the in/decreasing takes place 
  470. (b)efore or (a)fter the memory access.  A "!" at the end tells "write-back" 
  471. will take place.  So these modes are possible 
  472.          da  ia  db  ib    \ decrease/increase after/before
  473.          da  ia! db! ib!   \ as above plus write-back
  474. ____
  475.  
  476. Some macros make live a bit more easy, they are somewhat 68k alike, and must 
  477. follow a byte modifier because an offset will be calculated by the assembler 
  478. itself.  
  479.  
  480.     : )      0 #   ib ;
  481.     : )+     @increment  ia ;
  482.     : )-     @increment  da ;
  483.     : -(     @increment  db! ;
  484.     : +(     @increment  ib! ;
  485.     
  486.     : d)     dup abs # offset?  swap 0<  if db  else ib  then ;
  487.     : d)!    dup abs # offset?  swap 0<  if db! else ib! then ;
  488.     : push   -( str ;
  489.     : pop    )+ ldr ;
  490. Examples: 
  491.       top  r6 byte )+ ldr
  492.       top  up 8 d)    ldr
  493.  
  494.  
  495. See: str 
  496.  
  497.  
  498. ____ little-endian  ( -- )                                  
  499. Switches assembler to little-endian target code 
  500. ____
  501.  
  502. ____ mla            ( r-dest r-op1 r-op2 r-add )            
  503. Assembles a multiply-and-accumulate instruction, r-dest is r-add + 
  504. (r-op1*rop2) 
  505. ____
  506.  
  507. ____ mul            ( r-dest r-op1 r-op2 )                  
  508. Assembles a multiply instruction.  
  509. ____
  510.  
  511. ____ next           ( --  )                                 
  512. Assembler macro which assembles the next routine, which is the Forth address 
  513. interpreter.  
  514.  
  515. In RISC OS Forthmacs this is one single instruction.  
  516.          pc  ip  )+  ldr
  517. ____
  518.  
  519. ____ nop            ( --  )                                 
  520. Assembler macro, equivalent to 
  521.     r0 r0 mov
  522. ____
  523.  
  524. ____ pcr            ( addr -- pc offset  )                  
  525. Assembler macro, expects an address on the stack and calculates its address 
  526. offset from pc. The addressing mode is also set.  
  527. ____
  528.  
  529. ____ return         ( --  )                                 
  530. macro for 
  531.     pc  lk  mov
  532. ____
  533.  
  534. ____ s              ( --  )                                 
  535. modifier, the instruction will set the flags according to the result.  default 
  536. for tst, teq tstp teqp cmp cmn cmpp cmnp.  
  537. ____
  538.  
  539. ____ stm            ( rx1 rx2 .. rxn  n#  r-adr --  )       
  540. Store multiple registers to the address pointed to by r-adr, an addressing 
  541. modes must be defined.  
  542.  
  543.  
  544. See: ldm for more details.  
  545. ____
  546.  
  547. ____ str            ( r-data r-adr operand2 --  )           
  548. r-data is stored to memory, the default is word (32-bit) wide, but the 
  549. modifier byte sets this byte-wide access.  
  550.  
  551.  
  552. See: ldr 
  553. ____
  554.  
  555. ____ swi            ( swi# --  )                            
  556. assembles a swi instruction, the number is swi#.  
  557. ____
  558.  
  559. ____ swix           ( swi# --  )                            
  560. assembles a swix instruction, the number is swi#.  
  561. ____
  562.  
  563. ____ swp            ( r-dest r-base r-source --  )          
  564. assembles a swp instruction if Arm3-code is allowed by ARM3 
  565. ____
  566.  
  567. ____ t              ( --  )                                 
  568. modifier, force -T pin.  
  569. ____
  570.  
  571. ____ ^              ( --  )                                 
  572. modifier, force access to user-mode registers.  
  573. ____
  574.