Advertisement
Guest User

Untitled

a guest
Oct 10th, 2018
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
ARM 5.39 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.     cmp     r7, r5
  111.     blt     NegRes      ;if negative, call function to switch argument order and add negative flag
  112.     SUB     r5,r7,r5    ;subtract arguments if result is positive
  113.     PUSH    {r5}       
  114.     B       get_new     ;return from subroutine
  115. NegRes
  116.     sub     r5, r5, r7  ;switches order of subtraction
  117.     push    {r5}        ;pushes result onto stack
  118.     mov     r12, #"-"   ;sets negative flag
  119.     b       get_new
  120.  
  121. div
  122.     BL      my_getchar
  123.     CMP     r0,#0x0D    ;verifies that the next character is an enter
  124.     BNE     inv_op      ;if not then the format is incorrect
  125.     BL      my_putchar  ;beginning of line
  126.     MOV     r0,#0x0A    ;LF
  127.     BL      my_putchar  ;outputs line feed between new things
  128.     POP     {r5}
  129.     POP     {r7}
  130.     SDIV    r5,r7,r5    ;divide arguments
  131.     PUSH    {r5}
  132.     B       get_new     ;return from subroutine
  133.  
  134. mult
  135.     BL      my_getchar
  136.     CMP     r0,#0x0D    ;verifies that the next character is an enter
  137.     BNE     inv_op      ;if not then the format is incorrect
  138.     BL      my_putchar  ;beginning of line
  139.     MOV     r0,#0x0A    ;LF
  140.     BL      my_putchar  ;outputs line feed between new things
  141.     POP     {r5}
  142.     POP     {r7}
  143.     MUL     r5,r7,r5    ;multiply arguments
  144.     PUSH    {r5}
  145.     B       get_new     ;return from subroutine
  146.  
  147. Reset  
  148.     pop     {r4}            ;gets final value to be outputted from stack
  149.     MOV     r6, #10         ;stores 10 in r6
  150.     MOV     r1, r4          ;stores final value in r4
  151.     MOV     r11, #0         ;reset r11
  152.     LDR     r7, =ToMemory   ;r7 will contain values stored to memory
  153.  
  154. AsciiToInt
  155.     UDIV    r1, r1, r6          ;divides the value by 10 and stores the result in r1 - eg 1035/10 -> 103 in r1
  156.     LSL     r9, r1, #3 
  157.     ADD     r8, r9, r1, LSL#1   ;this line and the previous multiply the value by 10
  158.     SUB     r3, r4, r8          ;obtains the remainder of the division
  159.     ADD     r10, r3, #0x30      ;converts the remainder into ascii
  160.     STR     r10, [r7], #4       ;stores the ascii value of the remainder into memory to be printed later
  161.     MOV     r4, r1              ;updates the numerator value for the next iteration
  162.     ADD     r11, r11, #1        ;string counter
  163.     CMP     r1, #9             
  164.     BGT     AsciiToInt          ;if the new numerator is >10, iterate. If not, simply store it in memory
  165.     ADD     r1, r1, #0x30       ;converts the numerator to ascii when it is <10
  166.     STR     r1, [r7]            ;stores it in memory
  167.     ADD     r11, r11, #1        ;string counter
  168.    
  169. PrintAscii
  170.     LDR     r0, [r7], #-4   ;little-endian, starts loading from the final value stored in memory from previous subroutine
  171.     BL      my_putchar      ;prints it
  172.     SUB     r11, r11, #1    ;decrement string counter
  173.     CMP     r11, #0         ;check string counter
  174.     BNE     PrintAscii      ;continue if not 0
  175.     cmp     r12, #"-"       ;checks negative flag
  176.     bne     stop            ;if not equal result is positive - stop
  177. NegFlag
  178.     mov     r0, #"-"        ;prints negative sign
  179.     bl      my_putchar
  180.     B       stop
  181.    
  182. stop
  183.     B       stop
  184.    
  185.     ALIGN       ;aligns code (but also data) to a memory boundary
  186.     AREA MyData, DATA, READWRITE
  187.        
  188. cal         DCB "Type the RPN expression with Enter after each argument and operator",0
  189. Inv         DCB "Invalid operation",0
  190. arg         SPACE 100
  191. ToMemory    space 100
  192.     END
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement