Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
manual:chapter5:asm [2019/11/26 15:15]
jojo1973 Expanded and reformatted (part 2)
manual:chapter5:asm [2019/12/05 14:03]
jojo1973 [Simple assignments with operators] Added a particular syntax regarding register R
Line 27: Line 27:
 **Instructions** are divided in the following classes: ​ **Instructions** are divided in the following classes: ​
  
-^ Assignment ​operators ​ ^ Math operators ​ ^ Math functions ​ ^ Flow control ​ ^ Data manipulation ​ ^ +^ Assignment ​ ^ Math (oper.) ​ ^ Math (functions)  ^ Tests  ^ Flow control ​ ^ Data manipulation ​ ^ 
-| ''​='' ​ | ''​+'' ​ | ''​IP'' ​ | ''​CMP'' ​ | ''​GET'' ​ | +| ''​='' ​ | ''​+'' ​ | ''​IP'' ​ | ''​CMP'' ​ | ''​SKIP'' ​ | ''​GET'' ​ | 
-| ''​+='' ​ | ''​-'' ​ | ''​LN'' ​ | ''​SKIP'' ​ | ''​PUT'' ​ | +| ''​+='' ​ | ''​-'' ​ | ''​LN'' ​ | ''​CHK''  ​| ''​LOOP'' ​  | ''​PUT'' ​ | 
-| ''​-='' ​ | ''​*'' ​ | ''​EXP'' ​ | ''​LOOP'' ​ | ''​PUSH'' ​ | +| ''​-='' ​ | ''​*'' ​ | ''​EXP'' ​ | ''​AND''  ​|    ​| ''​PUSH'' ​ | 
-| ''​*='' ​ | ''/'' ​ | ''​SQRT'' ​ | ''​FPUSH'' ​ | ''​RPUSH'' ​ | +| ''​*='' ​ | ''/'' ​ | ''​SQRT'' ​ | ''​OR''  ​|    ​| ''​RPUSH'' ​ | 
-| ''/​='' ​ | ''​^'' ​ | ''​SIN'' ​ |  :::  | ''​POP'' ​ | +| ''/​='' ​ | ''​^'' ​ | ''​SIN'' ​ | ''​XOR'' ​ |  :::  | ''​POP'' ​ | 
- :::  ​ :::  ​| ''​COS'' ​ |  :::  | ''​RPOP'' ​ | +      | ''​COS''  ​|    ​|  :::  | ''​RPOP'' ​ | 
-|  :::  |  :::  | ''​TAN''​ |  :::  | ''​MIN'' ​ | +|  :::  |  :::  | ''​TAN'' ​|  :::  ​|  :::  | ''​MIN'' ​ | 
-|  :::  |  :::  | ''​ASIN'' ​ |  :::  | ''​MAX'' ​ | +|  :::  |  :::  | ''​ASIN'' ​ ​| ​ :::  ​| ​ :::  | ''​MAX'' ​ | 
-|  :::  |  :::  | ''​ACOS'' ​ |  :::  | ''​RND'' ​ | +|  :::  |  :::  | ''​ACOS'' ​ ​| ​ :::  ​| ​ :::  | ''​RND'' ​ | 
-|  :::  |  :::  | ''​ATAN''​ |  :::  |  :::  | +|  :::  |  :::  | ''​ATAN''​ |  :::  |  :::  | ''​CLR'' ​ | 
-|  :::  |  :::  | ''​SINH'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​SINH'' ​ |  :::  |  :::  ​|   
-|  :::  |  :::  | ''​COSH'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​COSH'' ​ |  :::  |  :::  ​|    ​
-|  :::  |  :::  | ''​TANH'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​TANH'' ​ ​| ​ :::  ​| ​ :::  |  :::  | 
-|  :::  |  :::  | ''​ASINH'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​ASINH'' ​ ​| ​ :::  ​| ​ :::  |  :::  | 
-|  :::  |  :::  | ''​ACOSH'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​ACOSH'' ​ ​| ​ :::  ​| ​ :::  |  :::  | 
-|  :::  |  :::  | ''​ATANH'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​ATANH'' ​ ​| ​ :::  ​| ​ :::  |  :::  | 
-|  :::  |  :::  | ''​FP'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​FP'' ​ ​| ​ :::  ​| ​ :::  |  :::  | 
-|  :::  |  :::  | ''​ABS'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​ABS'' ​ ​| ​ :::  ​| ​ :::  |  :::  | 
-|  :::  |  :::  | ''​ARG'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​ARG'' ​ ​| ​ :::  ​| ​ :::  |  :::  | 
-|  :::  |  :::  | ''​RE'' ​ |  :::  |  :::  | +|  :::  |  :::  | ''​RE'' ​ ​| ​ :::  ​| ​ :::  |  :::  | 
-|  :::  |  :::  | ''​IM'' ​ |  :::  |  :::  |+|  :::  |  :::  | ''​IM'' ​ ​| ​ :::  ​| ​ :::  |  :::  |
  
-**Literals** are integer constants from ''​0''​ to ''​15''​. They can optionally prefixed with a hash (''#''​) or expressed in hexadecimal (''#​0H''​-''#​FH''​). In the latter case the leading ''#''​ and trailing ''​H''​ are compulsory.+**Literals** are integer constants from ''​0''​ to ''​15''​. They can optionally ​be prefixed with a hash (''#''​) or expressed in hexadecimal (''#​0H''​-''#​FH''​). In the latter case the leading ''#''​ and trailing ''​H''​ are compulsory.
  
 **Statements** are divided in two categories: **Statements** are divided in two categories:
Line 58: Line 58:
     * an optional //​assignment operator// (''​='',​ ''​+='',​ ''​-='',​ ''​*=''​ or ''/​=''​);​     * an optional //​assignment operator// (''​='',​ ''​+='',​ ''​-='',​ ''​*=''​ or ''/​=''​);​
     * a //math operator//, a //math function// or a //data manipulation command//: operators are __infix__, functions and commands are __prefix__;     * a //math operator//, a //math function// or a //data manipulation command//: operators are __infix__, functions and commands are __prefix__;
-    * 1 or 2 arguments to the operator or function. Arguments can be either a (pseudo-)register (''​A''​-''​H'',​ ''​S1''​-''​S7''​),​ a reference (''​R''​) or a literal. The context makes clear if the arguments are to be interpreted as //direct// (e.g. register ''​A''​) or //​indirect//​ (e.g. the stack level referenced by register ''​A''​).+    * 1 or 2 arguments to the operator or function. Arguments can be either a (pseudo-)register (''​A''​-''​H'',​ ''​S1''​-''​S7''​),​ a reference (''​R''​) or a literal. ​
  
   * **Commands**,​ which may be   * **Commands**,​ which may be
     * a //​comparison//​ command, followed by the two arguments to be compared;     * a //​comparison//​ command, followed by the two arguments to be compared;
     * a //flow control// command, followed by the condition to be tested;     * a //flow control// command, followed by the condition to be tested;
-    * a //data manipulation//​ command, ​followied ​by two arguments defining the extent of the manipulation;​ +    * a //data manipulation//​ command, ​followed ​by two arguments defining the extent of the manipulation;​ 
-    * arguments can be either a register (''​A''​-''​H'',​ ''​S1''​-''​S7''​),​ a reference (''​R''​) or a literal.  The context makes clear if the arguments are to be interpreted as //direct// (e.g. register ''​A''​) or //​indirect//​ (e.g. the stack level referenced by register ''​A''​).+    * arguments can be either a register (''​A''​-''​H'',​ ''​S1''​-''​S7''​),​ a reference (''​R''​) or a literal.
  
 ==== Simple assignments with operators ==== ==== Simple assignments with operators ====
Line 73: Line 73:
 | '':​A=S2''​ '':​S2=S1''​ '':​S1=A'' ​ | Swap stack level 1 with level 2 using register ''​A''​ as temporary storage. An error is raised if the stack contains less than 2 levels ​ | | '':​A=S2''​ '':​S2=S1''​ '':​S1=A'' ​ | Swap stack level 1 with level 2 using register ''​A''​ as temporary storage. An error is raised if the stack contains less than 2 levels ​ |
 | '':​C+=B^#​2'' ​ | Square the value register ''​B''​ and adds the result to register ''​C'' ​ | | '':​C+=B^#​2'' ​ | Square the value register ''​B''​ and adds the result to register ''​C'' ​ |
 +| '':​B=R^#​2 π'' ​ | Assign ''​%%'​%%π^2%%'​%%''​ to register B. This example shows that register ''​R''​ must not necessarily be the second argument of a binary operator ​ |
  
 ==== Assignment with math functions ==== ==== Assignment with math functions ====
Line 80: Line 81:
 | '':​D=ATANH.R %%'​e^2'​%%''​ | Assign the hyperbolic arctangent of ''​%%'​e^2'​%%''​ to register ''​D'' ​ | | '':​D=ATANH.R %%'​e^2'​%%''​ | Assign the hyperbolic arctangent of ''​%%'​e^2'​%%''​ to register ''​D'' ​ |
  
-==== Testing ​====+==== Tests ==== 
 + 
 +Test instructions will, when the result is not stored or assigned to any register, affect two system flags: flag [[manual:​appendix:​flags#​flag-58|-58]] if the result of the test was zero (in the case of ''​CMP'',​ if the two arguments are equal) and flag [[manual:​appendix:​flags#​flag-59|-59]] if the result is negative (in the case of ''​CMP'',​ when the first argument is less than the second). 
 + 
 +The ''​CMP''​ command is equivalent to the **newRPL** ''​[[manual:​chapter6:​operators:​cmd_ovr_cmp|CMP]]''​ operator and accepts the same type of arguments. ​
  
 | '':​CMP.A.#​1'' ​ | Compare register ''​A''​ and literal ''​1'',​ setting internal flags accordingly ​ | | '':​CMP.A.#​1'' ​ | Compare register ''​A''​ and literal ''​1'',​ setting internal flags accordingly ​ |
 +| '':​C=CMP.A.#​1'' ​ | Compare register ''​A''​ and literal ''​1'',​ store the result of the comparison in ''​C''​. In this case internal flags will **not** be set.  |
 +| '':​AND.A.#​1'' ​ | Logical ''​AND''​ between ''​A''​ and literal ''​1''​ (always true), therefore resulting in ''​0''​ (false) if ''​A''​ is false, true otherwise. Internal flags will be set accordingly. ​ |
 +| '':​C=AND.A.#​1'' ​ | Same as above, store the result of the test (true/​false) in ''​C''​. In this case internal flags will **not** be set.  |
  
-The ''​CMP''​ command is equivalent to the **newRPL** ''​[[manual:​chapter6:​operators:​cmd_ovr_cmp|CMP]]''​ operator and accepts the same type of arguments, but instead of returning a value representing the result of the comparison it merely sets two system flags: flag [[manual:​appendix:​flags#​flag-58|-58]] if the two arguments are equal and flag [[manual:​appendix:​flags#​flag-59|-59]] if the first argument is less than the second. 
  
 ==== Flow control ==== ==== Flow control ====
Line 93: Line 100:
 | ''​AL'' ​   | Always ​                | ---       | ---       | | ''​AL'' ​   | Always ​                | ---       | ---       |
 | ''​LT'' ​   | Less Than              | ---       | Set       | | ''​LT'' ​   | Less Than              | ---       | Set       |
-| ''​EQ'' ​   | Equals ​                | Set       | ---       | +| ''​EQ'' ​or ''​Z''  ​| Equals ​                | Set       | ---       | 
-| ''​LTE'' ​  ​| Less Than or Equals ​   | ---       | Set       |+| ''​LE'' ​   | Less Than or Equals ​   | ---       | Set       |
 | :::       | :::                    | Set       | ---       | | :::       | :::                    | Set       | ---       |
 | ''​NA'' ​   | Never                  | ---       | ---       | | ''​NA'' ​   | Never                  | ---       | ---       |
-| ''​GTE'' ​  ​| Greater Than or Equals | ---       | Clear     | +| ''​GE'' ​   | Greater Than or Equals | ---       | Clear     | 
-| ''​NE'' ​   | Not Equals ​            | Clear     | ---       |+| ''​NE'' ​or ''​NZ''  ​| Not Equals ​            | Clear     | ---       |
 | ''​GT'' ​   | Greater Than           | Clear     | Clear     | | ''​GT'' ​   | Greater Than           | Clear     | Clear     |
  
 ---- ----
  
-| '':​SKIP.EQ'' ​ | Skip next instruction if the result ​of last comparison ​was //​Equals// ​ | +| '':​SKIP.EQ'' ​ | Skip next instruction if the state of the flags was //​Equals// ​ | 
-| '':​LOOP.LTE'' ​ | Must be followed by a program ''​« ... »''​ or a secondary ''::​ ... ;''​. Repeat the object that follows while the result ​of the last comparison ​is //Less Than or Equals//. Notice the program or secondary that follows **must** update the internal flags with a '':​CMP.[Y].[Z]''​ statement or it will loop indefintely ​ | +| '':​LOOP.LE'' ​ | Must be followed by a program ''​« ... »''​ or a secondary ''::​ ... ;''​. Repeat the object that follows while the state of the flags is //Less Than or Equals//. Notice the program or secondary that follows **must** update the internal flags with a '':​CMP.[Y].[Z]'' ​or other test statement or it will loop indefinitely ​ | 
-| '':​FPUSH.GT'' ​ | Push True (''​1''​) ​to the stack if the result ​of the last comparison ​is //Greater Than//, otherwise ​push False (''​0''​) ​ |+| '':​A=CHK.GT'' ​ | Results in true (''​1''​) if the state of flags is //Greater Than//, otherwise ​results in False (''​0''​). Result may be stored into a register or pseudo-register. If the result is not stored, flags will be affected accordingly ​ |
  
-The ''​FPUSH''​ command is useful to combine assembly-like statements into **newRPL** flow control structures. For example<​code>​+The ''​CHK''​ command is useful to combine assembly-like statements into **newRPL** flow control structures. For example<​code>​
 « IF  « IF 
-    :CMP.A.#0 +    :CMP.A.#3    @@ COMPARE A WITH 3 
-    :FPUSH.EQ+    :P=CHK.EQ    @@ AND CHECK IF IT'S EQUAL, PUSHING TRUE/FALSE TO THE STACK
   THEN   THEN
     ...     ...
Line 127: Line 134:
 | '':​PUSH.A.#​3''​ | Reverse of '':​POP''​. In this example will do '':​P=C'',​ '':​P=B''​ and '':​P=A'' ​ | | '':​PUSH.A.#​3''​ | Reverse of '':​POP''​. In this example will do '':​P=C'',​ '':​P=B''​ and '':​P=A'' ​ |
 | '':​RPUSH.A.#​3'' ​ | Reverse of '':​RPOP''​. In this example will do '':​P=A'',​ '':​P=B'',​ and '':​P=C'' ​ | | '':​RPUSH.A.#​3'' ​ | Reverse of '':​RPOP''​. In this example will do '':​P=A'',​ '':​P=B'',​ and '':​P=C'' ​ |
 +| '':​CLR.A.#​3''​ | Set registers to zero (clear) starting with ''​A'',​ and as many registers as requested. In this example will do '':​A=0'',​ '':​B=0''​ and '':​C=0'' ​ |
  
 +==== Example code ====
 +
 +The following programs show the Assembly-like Instruction Set features in action: they are meant to be didactic rather than clever.
 +
 +----
 +
 +  * ''​Q2''​ is an almost line-per-line translation of the program presented in chapter 2 of the //HP-42S Programming Examples and Techniques//​ manual.
 +
 +<​code>​
 +« @@ Q2: Solve aX^2+bX+c=0 where a≠0, c≠0
 +  -103 SF             @ Complex results
 +  :​A=RPOP.S1.#​3 ​      @ Store coefficients in registers
 +  :​AND.A.C ​           @ Are either zero?
 +  :​SKIP.NZ ​           @ Skip next seco if both A and C were non-zero
 +  :: "Zero Input Invalid"​
 +     ​DOERR ​           @ Abort with error
 +  ;
 +  :​D=#​0-B ​            @ -B
 +  :​E=B*B ​             @ B^2
 +  :F=#4*A :F*=C       @ 4*A*C
 +  :E-=F   :​E=SQRT.E ​  @ √(B^2-4*A*C)
 +  ​
 +  :CMP.B.#0
 +  :SKIP.GE :​F=D+E ​    @ -B+√(B^2-4*A*C) when B<=0
 +  :SKIP.LT :​F=D-E ​    @ -B-√(B^2-4*A*C) when B>0
 +  ​
 +  :​E=A*#​2 ​            @ 2*A
 +  :​P=F/​E ​             @ (-B-SIGN(B)*√(B^2-4*A*C))/​2/​A is R1, the largest root in absolute value
 +  :​P=C/​A ​             @ R1, C/A
 +  :​S1/​=S2 ​            @ C/(R1*A) is R2, the other root
 +»
 +</​code>​
 +
 +----
 +
 +  * ''​STRAIGHT''​ computes the equation of the straight line passing through the points p<​sub>​1</​sub>​=(x<​sub>​1</​sub>,​y<​sub>​1</​sub>​) and p<​sub>​2</​sub>​=(x<​sub>​2</​sub>,​y<​sub>​2</​sub>​).
 +<​code>​
 +« @@ STRAIGHT: compute aX+bY+c passing through p1 and p2
 +  → p1 p2         @ Get the two points
 +  « p1 C→R        @ Split the first
 +    p2 C→R        @ Split the second
 +    :​C=RPOP.S1.#​4 @ Store x1, y1, x2 and y2 in C, D, E and F registers
 +    :A=R '​X' ​     @ Registers can store anything
 +    :B=R '​Y' ​     @ if '​R'​ pseudo-register is used
 +    :B-=D         @ B='​Y-y1'​
 +    :A-=C         @ A='​X-x1'​
 +    :F-=D         @ F=y2-y1
 +    :E-=C         @ E=x2-x1
 +    :B*=E         @ B='​(Y-y1)*(x2-x1)'​
 +    :F*=A         @ F='​(y2-y1)*(X-x1)'​
 +    :B-=F         @ B='​(Y-y1)*(x2-x1)-(y2-y1)*(X-x1)'​
 +    :P=B          @ Push result on the stack
 +  »
 +»
 +</​code> ​
  • manual/chapter5/asm.txt
  • Last modified: 2019/12/05 14:03
  • by jojo1973