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

📄 psr.html

📁 关于ARM汇编的非常好的教程
💻 HTML
📖 第 1 页 / 共 2 页
字号:
</dl><p><dl>  <dt> AL : Always  <dd> The default condition, so does not need to be explicity stated.</dl><p><dl>  <dt> NV : Never  <dd> Not particularly useful, it states that the instruction should never be executed. A kind       of Poor Mans' NOP.<br>       NV was included for completeness (as the reverse of AL), but you should not use it in your       own code.</dl>There is a final conditional code which works in the reverse way. <code>S</code>, when appliedto an instruction, causes the status flags to be updated. This does <i>not</i> happenautomatically - except for those instructions whose purpose is to set the status.For example:<pre>  ADD     R0, R0, R1  ADDS    R0, R0, R1  ADDEQS  R0, R0, R1</pre>The first example shows us a basic addition (adding the value of R1 to R0) which does not affectthe status registers.<p>The second example shows us the same addition, only this time it will cause the status registersto be updated.<p>The last example shows us the addition again, updating the status registers. The difference hereis that it is a conditional instruction. It will only be executed if the result of a previousoperation was EQual (if the Z flag is set).<p>&nbsp;<p>&nbsp;<p>Here is an example of conditional execution at work. You want to compare register zero with thecontents of something stored in register ten. If not equal to R10, then call a softwareinterrupt, increment and branch back to do it again. Otherwise clear R10 and return to a callingpiece of code (whose address is stored in R14).<pre>  \ An example of conditional execution  .loop                           ; Mark the loop start position  CMP     R0, R10                 ; Compare R0 with R10  SWINE   &40017                  ; Not equal: Call SWI &40017  ADDNE   R0, R0, #1              ;            Add 1 to R0  BNE     loop                    ;            Branch to 'loop'  MOV     R10, #0                 ; Equal    : Set R10 to zero  LDMFD   R13!, {R0-R12,PC}       ;            Return to caller</pre>Notes:<ul>  <li> The SWI number was made up as I was writing this. Under RISC OS, it is the number for       <i>Econet_DoImmediate</i>. Don't take it literally, its only an example!  <li> If you've not see <code>LDMFD</code> before, it loads multiple registers from the stack.       In this example, we are loading R0 to R12 and R14 from a fully descending stack. Refer to       <a href="str.html"><i>str.html</i></a> for more on register loading and storing.  <li> Yes, I did just say we load R14. So why put it in the PC? Because the value of R14 when       stored contains the return address. We can give happily:<br>       <code>LDMFD&nbsp;&nbsp;&nbsp;R13!, {R0-R12,R14}<br>MOV&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;PC,       R14</code><br>       However by reloading straight into PC, we can omit the <code>MOV</code> statement.  <li> Finally, it is very likely that registers will be corrupted by a SWI call (dependant upon       the code executed during the call), so you might like to push the important registers on       the stack, to restore them later.</ul><p>&nbsp;<p>&nbsp;<p><a name="32bit"></a><h2>The 32 bit PSR</h2>As described in <a href = "32bit.html">this document</a>, processors after the ARM 3 provide a32 bit addressing space by moving the PSR out of R15 and giving R15 a full 32 bits in which tostore the address of the current position.<br>Currently, RISC OS works in 26 bit mode, except for a few special cases which is unlikely to beencountered.<br>The 32 bit mode is important because 26 bits (as in the old PSR) restricts the maximum amount ofaddressable memory per-application to 28Mb. That is why you can't drag the Next slot beyond 28Mbirrespective of how much memory you have installed.<p>The allocation of the bits within the CPSR (and the SPSR registers to which it is saved) is:<pre>  31 30 29 28  ---   7   6   -   4   3   2   1   0  N  Z  C  V         I   F       M4  M3  M2  M1  M0                                 0   0   0   0   0     User26 mode                                 0   0   0   0   1     FIQ26 mode                                 0   0   0   1   0     IRQ26 mode                                 0   0   0   1   1     SVC26 mode                                 1   0   0   0   0     User mode                                 1   0   0   0   1     FIQ mode                                 1   0   0   1   0     IRQ mode                                 1   0   0   1   1     SVC mode                                 1   0   1   1   1     ABT mode                                 1   1   0   1   1     UND mode</pre><p>&nbsp;<p>Typically, the processor will be operating in User26, FIQ26, IRQ26 or SVC26 mode. It is possibleto enter a 32 bit mode, but extreme care must be taken. RISC OS won't expect it, and will sulkgreatly if it finds itself in it!<p>You cannot use <code>MOVS PC, R14</code> or <code>LDMFD R13!, {<i>registers</i>, PC}^</code> in32 bit code. Neither can you use <code>ORRS PC, R14, #1&lt;&lt;28</code> to set the V flag.<br>All of this is now possible using <code>MRS</code> and <code>MSR</code>.<p><pre>Copy a register into the PSR  MSR     CPSR, R0                ; Copy R0 into CPSR  MSR     SPSR, R0                ; Copy R0 into SPSR  MSR     CPSR_flg, R0            ; Copy flag bits of R0 into CPSR  MSR     CPSR_flg, #1&lt;&lt;28        ; Copy flag bits (immediate) into CPSR</pre><pre>Copy the PSR into a register  MRS     R0, CPSR                ; Copy CPSR into R0  MRS     R0, SPSR                ; Copy SPSR into R0</pre>You have two PSRs - <code>CPSR</code> which is the Current Program Status Register and<code>SPSR</code> which is the Saved Program Status Register (the previous processor mode's PSR).<br>Each privileged mode has its own PSR, so the total available selection of PSR is:<ul>  <li> CPSR_all - current  <li> SPSR_svc - saved, SVC(32) mode  <li> SPSR_irq - saved, IRQ(32) mode  <li> SPSR_abt - saved, ABT(32) mode  <li> SPSR_und - saved, UND(32) mode  <li> SPSR_fiq - saved, FIQ(32) mode</ul>It appears as if you cannot explicitly specify to save the current PSR in, say, SPSR_fiq.Instead, you should change to FIQ mode and then save to SPSR. In other words, you can only alterthe SPSR of the mode you are in.<br>Using the <code>_flg</code> suffix allows you to alter the flag bits without affecting thecontrol bits.<p>In user(32) mode, the control bits of CPSR are protected, you can only alter the condition flags.In other modes, the entire CPSR is available. You should not specify R15 as a source ordestination register. And finally, you must not attempt to access the SPSR in user(32) mode asit doesn't exist!<p>To set the V flag:<pre>  MSR     CPSR_flg, #&10000000</pre>This sets the V flag and doesn't affect the control bits.<p>To change mode:<pre>  MRS     R0, CPSR_all            ; Copy the PSR  BIC     R0, R0, #&1F            ; Clear the mode bits  ORR     R0, R0, #new_mode       ; Set bits for new mode  MSR     CPSR_all, R0            ; write PSR back, changing mode</pre><p>&nbsp;<p>What we shall do now is to enter the SVC32 mode and set the Z flag. Then we'll return to SVC26mode and 'test' if the Z flag is set.<br>RISC OS will not be expecting to find itself in 32 bit mode, so we'll disable all interrupts andkeep them that way. Though this code should execute fast enough, we don't want to take anychances...<p>Before we begin, I just want to say that you <i>will</i> need Darren Salt's<code>ExtBASICasm</code> module to allow BASIC to assemble the MSR/MRS instructions. It isentirely possible to insert these instructions using EQUD, but it is messy and hard to follow.<br>If you use !Zap, you'll find it as <i>!Zap.Code.Extensions.ExtAsm</i>, in the v1.40 distribution.<p><pre><font size = 2>REM &gt;32bittestREMREM Short example to go into 32 bit mode, set theREM Z flag, and return to a conditional based uponREM this.REMREM Downloaded from http://www.heyrick.co.uk/assembler/REMREM We need to ensure the required hardware is present...emsg$ = &quot;Sorry, you'll need a RiscPC or later, with a 32 bit capable &quot;emsg$+= &quot;processor in order to use this software.&quot;ON ERROR SYS &quot;OS_PrettyPrint&quot;, emsg$ : PRINT : ENDSYS &quot;OS_Memory&quot;, 6ON ERROR PRINT REPORT$+&quot; at &quot;+STR$(ERL/10) : ENDDIM code% 1024PRINT &quot;Assembling code&quot;FOR l% = 0 TO 2 STEP 2  P% = code%  [  OPT l%     EXT 1                      ; Enable ExtBASICAsm     \ Preserve our R14 and then enter SVC mode     STMFD   R13!, {R14}     SWI     &quot;OS_EnterOS&quot;     ADR     R0, entering     SWI     &quot;OS_Write0&quot;     SWI     &quot;OS_NewLine&quot;     \ Turn off all interrupts, because RISC OS won't be expecting 32 bit mode!     SWI     &quot;OS_IntOff&quot;     \ User32 code     MOV     R0, #%10011     MSR     CPSR_all, R0       ; Select CPSR mode, clear all the bits     MOV     R0, R0          MRS     R0, CPSR_all       ; Read CPSR     BIC     R0, R0, #&amp;F0000000 ; Clear the flag bits     BIC     R0, R0, #&amp;1F       ; Clear the mode bits     ORR     R0, R0, #1&lt;&lt;30     ; Set the Z flag     ORR     R0, R0, #%11       ; Set SVC26 mode     MSR     CPSR_all, R0       ; Do it!     MOV     R0, R0     \ Turn interrupts back on again.     SWI     &quot;OS_IntOn&quot;     ADR     R0, exiting     SWI     &quot;OS_Write0&quot;     SWI     &quot;OS_NewLine&quot;     \ If Z set, print Z set else print Z unset     ADR     R0, zunset     ADREQ   R0, zset     SWI     &quot;OS_Write0&quot;     SWI     &quot;OS_NewLine&quot;     \ Return to USR mode     BIC     R14, PC, #3     TEQP    R14, #0     MOV     R0, R0     \ And get out of here.     LDMFD   R13!, {PC}  .zunset     EQUS    &quot;  Z flag is not set (this ain't right!)&quot;     EQUB    0     ALIGN  .zset     EQUS    &quot;  Z flag is set (as expected!)&quot;     EQUB    0     ALIGN  .entering     EQUS    &quot;  About to enter 32 bit mode, cross your fingers!&quot;     EQUB    0     ALIGN  .exiting     EQUS    &quot;  Returned to 26 bit mode. Phew!&quot;     EQUB    0     ALIGN  ]NEXTPRINT &quot;Executing code&quot;CALL code%PRINT &quot;Finished&quot;END</font></pre><div align = right><a href="sw/32bittest.basic"><i>Download this example</i></a></div><p>You might have got the idea that 32 bit code is not terribly useful. Under current versions ofRISC OS, this is true. In fact, as far as I'm aware, the only thing that 32 bit mode will giveyou is:<ul>  <li> Access to areas larger than 28Mb. Never really been much of an issue on RISC OS, where       a web browser fits into a meg or two and serious art programs provide their own virtual       memory system for those seriously huge images.</ul><p>The original version of this document, and the original ARM assembler guide includes...<ul>  <li> The StrongARM provides two instructions (UMUL and UMLA, IIRC) which deal with 64 bit       multiplication. This is only available in 32 bit mode.</ul>This is <i>incorrect</i>. The extended multiply can be used from 26 bit mode; it's how the MP3decoders use it!<p>While the benefits may not seem to be an awful lot, newer processors (such as Xscale) do notsupport 26 bit mode, so RISC OS and it's applications will need to be modified to work in 32 bitenvironment.<br>It may not sound like much, but given that <i>all</i> references to amending/altering the PSRbits in R15 have to be changed to refer to a seperate PSR not in R15, it suddenly becomes a muchbigger issue. Also, you can no longer restore the PSR and branch back to the caller in oneinstruction, as these are now two seperate operations. For that reason, code must be rewritten.You can't simply bodge in another instruction...<p>&nbsp;<p>&nbsp;<p><hr size = "3"><a href="index.html#02">Return to assembler index</a><hr size = "3"><address>Copyright &copy; 2001 Richard Murray</address></body></html>

⌨️ 快捷键说明

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