Advertisement
Guest User

Untitled

a guest
Oct 10th, 2018
89
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ARM 4.97 KB | None | 0 0
  1. PRESERVE8
  2.     AREA MyCode, CODE, READONLY
  3.     EXPORT calc
  4. calc
  5.     import my_fprint
  6.     import my_getchar
  7.     import my_putchar
  8.     mov     r0, #0x0A
  9.     BL      my_fprint
  10.     LDR     r0,=cal     ;"NEW CALCULATOR"
  11.     BL      my_fprint   ;prints cal and empties register
  12.  
  13. resetarg
  14.     LDR     r8, =arg        ;load address of the argument in r8
  15.  
  16. get_new
  17.     MOV     r10, #0         ;register to store argument
  18.     BL      my_getchar
  19.     MOV     r10,r0     
  20.     BL      my_putchar 
  21.    
  22.     CMP     r10, #0x0D      ;CR
  23.     BEQ     Ascii           ;if cr -> end of number -> convert ascii to int
  24.    
  25.     CMP     r10, #"="  
  26.     BEQ     equals          ;breaks if character entered is "="
  27.    
  28.     CMP     r10, #0x30
  29.     BLT     op              ;assume '+', '-', '/', '*' only op lt 0x30
  30.    
  31.     cmp     r10, #0x39      ;if gt 0x39 and not "=", invalid character
  32.     bgt     inv_op
  33.    
  34.     STR     r10, [r8], #4   ;store input in arg
  35.     ADD     r6,r6,#1        ;string counter
  36.     B       get_new         ;if char entered not op or CR, get next digit
  37.  
  38. Ascii
  39.     LDR     r8, =arg
  40.     MOV     r0, #0x0A   ;LF
  41.     BL      my_putchar  ;outputs line feed between new things
  42.     MOV     r1, #0
  43.     MOV     r2, #0
  44.     MOV     r3, #0
  45.  
  46. AsciiToDec
  47.     LDRB    r2, [r8],#4     ;loads r8 into r2, updates memory address
  48.     SUB     r2, r2, #0x30   ;subtracts 0x30 (0x35 = 5, 0x37 = 7, etc.)
  49.     LSL     r3,r1,#3        ;multiplies previous input by 8
  50.     ADD     r1,r3,r1, LSL #1;r1 = previous input *10
  51.     ADD     r1, r2, r1      ;adds previous input *10 to current input
  52.     SUB     r6,r6,#1        ;decrement string counter
  53.     CMP     r6, #0          ;check if end of string is reached
  54.     BNE     AsciiToDec      ;keep going if not
  55.     PUSH    {r1}            ;pushes final converted value onto stack
  56.     B       resetarg        ;get next argument
  57.  
  58. op
  59.     CMP     r6, #0
  60.     BNE     inv_op
  61.    
  62.     CMP     r10,#"+"
  63.     BEQ     plus
  64.  
  65.     CMP     r10,#"-"
  66.     BEQ     minus
  67.    
  68.     CMP     r10,#"/"
  69.     BEQ     div
  70.    
  71.     CMP     r10,#"*"
  72.     BEQ     mult
  73. inv_op
  74.     MOV     r0, #0x0A       ;LF
  75.     BL      my_putchar      ;outputs line feed
  76.     LDR     r0, =Inv        ;prints error message
  77.     BL      my_fprint
  78.     B       stop
  79. equals
  80.     BL      my_getchar
  81.     CMP     r0,#0x0D    ;verifies that the next character is an enter
  82.     BNE     inv_op      ;if not then the format is incorrect
  83.     BL      my_putchar
  84.     MOV     r0,#0x0A    ;LF
  85.     BL      my_putchar  ;outputs line feed between new things
  86.     B       Reset
  87.  
  88. plus
  89.     BL      my_getchar
  90.     CMP     r0,#0x0D    ;verifies that the next character is an enter
  91.     BNE     inv_op      ;if not then the format is incorrect
  92.     BL      my_putchar  ;beginning of line
  93.     MOV     r0,#0x0A    ;LF
  94.     BL      my_putchar  ;outputs line feed between new things
  95.     POP     {r5}
  96.     POP     {r7}
  97.     ADD     r5,r7,r5    ;ADD arguments
  98.     PUSH    {r5}
  99.     B       get_new     ;return from subroutine
  100.  
  101. minus
  102.     BL      my_getchar
  103.     CMP     r0,#0x0D    ;verifies that the next character is an enter
  104.     BNE     inv_op      ;if not then the format is incorrect
  105.     BL      my_putchar  ;beginning of line
  106.     MOV     r0,#0x0A    ;LF
  107.     BL      my_putchar  ;outputs line feed between new things
  108.     POP     {r5}
  109.     POP     {r7}
  110.     SUB     r5,r7,r5    ;subtract arguments
  111.     PUSH    {r5}
  112.     B       get_new     ;return from subroutine
  113.  
  114. div
  115.     BL      my_getchar
  116.     CMP     r0,#0x0D    ;verifies that the next character is an enter
  117.     BNE     inv_op      ;if not then the format is incorrect
  118.     BL      my_putchar  ;beginning of line
  119.     MOV     r0,#0x0A    ;LF
  120.     BL      my_putchar  ;outputs line feed between new things
  121.     POP     {r5}
  122.     POP     {r7}
  123.     SDIV    r5,r7,r5    ;divide arguments
  124.     PUSH    {r5}
  125.     B       get_new     ;return from subroutine
  126.  
  127. mult
  128.     BL      my_getchar
  129.     CMP     r0,#0x0D    ;verifies that the next character is an enter
  130.     BNE     inv_op      ;if not then the format is incorrect
  131.     BL      my_putchar  ;beginning of line
  132.     MOV     r0,#0x0A    ;LF
  133.     BL      my_putchar  ;outputs line feed between new things
  134.     POP     {r5}
  135.     POP     {r7}
  136.     MUL     r5,r7,r5    ;multiply arguments
  137.     PUSH    {r5}
  138.     B       get_new     ;return from subroutine
  139.  
  140. Reset  
  141.     pop     {r4}            ;gets final value to be outputted from stack
  142.     MOV     r6, #10         ;stores 10 in r6
  143.     MOV     r1, r4          ;stores final value in r4
  144.     MOV     r11, #0         ;reset r11
  145.     LDR     r7, =ToMemory   ;r7 will contain values stored to memory
  146.  
  147. AsciiToInt
  148.     UDIV    r1, r1, r6          ;divides the value by 10 and stores the result in r1 - eg 1035/10 -> 103 in r1
  149.     LSL     r9, r1, #3 
  150.     ADD     r8, r9, r1, LSL#1   ;this line and the previous multiply the value by 10
  151.     SUB     r3, r4, r8          ;obtains the remainder of the division
  152.     ADD     r10, r3, #0x30      ;converts the remainder into ascii
  153.     STR     r10, [r7], #4       ;stores the ascii value of the remainder into memory to be printed later
  154.     MOV     r4, r1              ;updates the numerator value for the next iteration
  155.     ADD     r11, r11, #1        ;string counter
  156.     CMP     r1, #9             
  157.     BGT     AsciiToInt          ;if the new numerator is >10, iterate. If not, simply store it in memory
  158.     ADD     r1, r1, #0x30       ;converts the numerator to ascii when it is <10
  159.     STR     r1, [r7]            ;stores it in memory
  160.     ADD     r11, r11, #1        ;string counter
  161.    
  162. PrintAscii
  163.     LDR     r0, [r7], #-4   ;little-endian, starts loading from the final value stored in memory from previous subroutine
  164.     BL      my_putchar      ;prints it
  165.     SUB     r11, r11, #1    ;decrement string counter
  166.     CMP     r11, #0         ;check string counter
  167.     BNE     PrintAscii      ;continue if not 0
  168.     B       stop
  169.    
  170. stop
  171.     B       stop
  172.    
  173.     ALIGN       ;aligns code (but also data) to a memory boundary
  174.     AREA MyData, DATA, READWRITE
  175.        
  176. cal         DCB "Type the RPN expression with Enter after each argument and operator",0
  177. Inv         DCB "Invalid operation",0
  178. arg         SPACE 100
  179. ToMemory    space 100
  180.     END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement