Advertisement
Guest User

Untitled

a guest
Mar 19th, 2018
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ;This program reads in a number and generates that many random 16-bit values.
  2. ;In this program, because we are using push and pop routines, we assume the contents of R0 will not
  3. ;be guarentee across subroutine calls.
  4. ;So, do not save R0 onto the stack.
  5.  
  6.   .orig x3000
  7.  
  8.   LD R6,STACKBASE     ;initialize stack
  9.  
  10. ;Code to read in a number.
  11. ;Register Dictionary for reading
  12. ;R0 - for I/O
  13. ;R1 - index into array Data
  14. ;R2 - element at current array index
  15. ;R3 - value of digit in question (between 0 and 15 for hex, 0 and 9 for decimal).  In the end R3 contains the result.
  16. ;R4 - The number being computed (the number represented by the input). THis will be copied into R3 at the end.
  17. ;R5 - scratch register.
  18. ;read in input and store into Data. Aside aside 4 bytes which is enough.
  19.  
  20.   LEA R0,StrPrompt  ;print user for input.
  21.   trap x22
  22.   LEA R1,Data
  23. ReadLoop
  24.   trap x20
  25.    
  26.   ADD R3,R0,#-10    ;R3 will be 0 if user hit <ENTER>
  27.   BRz DoneRead  
  28.  
  29.   STR R0,R1,#0    ;store character read into array Data
  30.   ADD R1,R1,#1    ;increment array index
  31.   BR ReadLoop  
  32.      
  33. DoneRead
  34.   AND R0,R0,#0    ;set R0 to 0
  35.   STR R0,R1,#0    ;put null-terminating character onto string read (optional)
  36.  
  37.   LEA R0,StrNewline
  38.   trap x22
  39.   LEA R0,Data     ;echo input string  to console
  40.   trap x22  
  41.  
  42.  
  43. ProcessInput      ;process the input
  44.   AND R4,R4,#0    ;zero out result  
  45.   LEA R1,Data     ;get start of input string
  46.   LDR R2,R1,#0    ;get first character(must be # or x).
  47.   LD R3,chPound   ;Load the character '#' into R3
  48.  
  49.   ADD R3,R3,R2    ;is the character '#'?
  50.   BRz HandleDec   ;yes
  51. HandleHex
  52.   ADD R1,R1,#1    
  53.   LDR R2,R1,#0    ;get first digit
  54.  
  55. HexCalc
  56.   LD R3,ch9
  57.   ADD R3,R3,R2    ;see if it is > 9
  58.   BRp HexGt9      ;yes
  59.   LD R3,ch0
  60.   ADD R3,R3,R2    ;compute digits value
  61.   BR HexNextChar
  62. HexGt9  
  63.   LD R3,chF
  64.   ADD R3,R3,R2    ;see if it is > 'F'
  65.   BRp HexGtF      ;yes
  66.   LD R3,chA  
  67.   ADD R3,R3,R2    ;compute value of digit
  68.   ADD R3,R3,#10   ;R3 holds value of digit
  69.  
  70.   BR HexNextChar
  71. HexGtF
  72.   ;must be between 'a' and 'f'  
  73.   LD R3,chLittleA  
  74.   ADD R3,R3,R2    ;compute value of digit
  75.   ADD R3,R3,#10   ;R3 holds value of digit
  76. HexNextChar
  77.   ADD R4,R4,R3
  78.   ADD R1,R1,#1
  79.   LDR R2,R1,#0    ;get new digit
  80.   ADD R2,R2,#0    ;see if value is zero (remember, we null terminated the string)
  81.   BRz Done        ;yes, we are done!
  82.  
  83.   ADD R4,R4,R4    ;multiply result by 16 using four add instructions
  84.   ADD R4,R4,R4    ;Add R4 to itself 4 times to multiply R4 by 16.
  85.   ADD R4,R4,R4
  86.   ADD R4,R4,R4  
  87.    
  88.   BR HexCalc      ;deal with current digit
  89.  
  90. ;This handle conversion of decimal numbers.
  91. HandleDec
  92.   ADD R1,R1,#1    
  93.   LDR R2,R1,#0    ;get first digit (must be between 0 and 9, since it is a decimal digit)
  94.  
  95. DecCalc    
  96.   LD R3,ch0
  97.   ADD R3,R3,R2    ;compute digits value
  98.   ADD R4,R4,R3    ;add digit to result
  99. DecNextChar
  100.   ADD R1,R1,#1
  101.   LDR R2,R1,#0    ;get new digit
  102.   ADD R2,R2,#0    ;see if value is zero (remember, we null terminated the string)
  103.   BRz Done        ;yes, we are done!
  104.   ADD R5,R4,R4    ;multiply R4 by 10
  105.   ADD R5,R5,R5    ;since we do not have a multiply, we have to use a workaround.
  106.   ADD R5,R5,R5
  107.   ADD R3,R4,R4    ;At this point R3 = 2*R4, R5 = 8*R4.
  108.   ADD R4,R3,R5    ;R4 = R3+R5 which is 10*R4
  109.  
  110.   BR DecCalc      ;deal with current digit  
  111. Done
  112.   ADD R3,R4,#0    ;copy final result into R3.
  113.  
  114. ;------------------------------------------------------------------------
  115. ;Main part of code for generating random numbers
  116.      
  117.   HALT
  118.  
  119.  
  120. ;-----------------------------------------------------------------------------
  121. ;Data section
  122. Data        .blkw   4 ;set aside 4 bytes for the input characters
  123. StrPrompt .stringz  "\nEnter a *3* character number (include leading zeroes):"
  124. StrGen    .stringz  " random numbers: "
  125. StrNewline  .stringz  "\n"
  126. StrUnderflow  .stringz  "\nStack Underflow, SP will not be changed."
  127.  
  128. Space     .fill  #32    ; space character
  129.  
  130. chPound   .fill   #-35  ;negative of the ASCII code for the '#' character
  131. ch0       .fill   #-48  ;negative of the ASCII code for the '0' character
  132. ch9       .fill   #-57  ;negative of the ASCII code for the '9' character
  133. chA       .fill   #-65  ;negative of the ASCII code for the 'A' character
  134. chF       .fill   #-70  ;negative of the ASCII code for the 'F' character
  135. chLittleA .fill   #-97  ;negative of the ASCII code for the 'a' character
  136.  
  137.    
  138. STACKBASE .fill   xFD00 ;start of stack
  139.  
  140.  
  141. ;------------------------------------------------------
  142. ;Subroutine Push
  143. ;pushes the contents of R0 onto the stack
  144. ;R0- contains data to be pushed.
  145. Push
  146. ADD R6,R6,#1 ;increment stack pointer
  147. STR R0,R6,#0 ;Store R0 into the stack
  148. RET
  149. ;------------------------------------------------------
  150. ;Subroutine Pop
  151. ;pops the contents of Top of Stack into R0
  152. ;R0 - will contain value of data popped.
  153. Pop
  154. LDR R0,R6,#0 ;Load top of stack into R0
  155. ADD R6,R6,#-1 ;Decrement stack pointer
  156. RET
  157. ;----------------------------------------------
  158. ;Subroutine Rand16 - generates a 16-bit positive random integer
  159. ;
  160. ;To make it positive we simply force the msb to be zero, which means we only need
  161. ;to produce 15 random bits per number.
  162.  
  163. ;Stack Frame:
  164. ;R5+0 - return value
  165.  
  166. Rand16
  167. RET
  168. ;static variables for Rand1
  169. StrSeed .stringz "asdfghjkl;' `1234567890-= ~!@#$%^&*()_+ qwertyuiop[]\ QWERTYUIOP{}| zxcvbnm,./ ASDFGHJKL: ZXCVBNM<>?"
  170.  
  171. ;----------------------------------------------
  172. ;Subroutine Rand1 - generates a random bit according to the rules specified in the assignment
  173.  
  174. ;Stack Frame:
  175. ;R5+0 - return value (the random bit in bit position 0)
  176.  
  177. Rand1
  178. RET
  179.  
  180. ;----------------------------------------------
  181. ;Subroutine Modulo - finds the remainder when dividing a non-negative number by a positive number
  182. ;
  183. ;implemented as A % B = A - (A/B) * B
  184.  
  185. ;Data Dictionary
  186. ;R1 - A
  187. ;R2 - B
  188. ;R3 - A/B
  189. ;R4 - Result
  190.  
  191. ;Stack Frame:
  192. ;R5+0 - return value (will hold the value of A % B)
  193. ;R5+1 - Parameter 2 (B)
  194. ;R5+2 - Parameter 1 (A)
  195.  
  196. Modulo
  197.     ADD R0,R1,#0
  198.     JSR Push
  199.  
  200.     ADD R0,R2,#0
  201.     JSR Push
  202.  
  203.     ADD R0,R3,#0
  204.     JSR Push
  205.    
  206.     ADD R0,R4,#0
  207.     JSR Push
  208.  
  209.     ADD R0,R5,#0
  210.     JSR Push
  211.    
  212.     ADD R5,R6,#5
  213.    
  214. Do_Mod
  215.     LDR R1,R5,#2
  216.     LDR R2,R5,#1
  217.     ;;Do A/B
  218.     JSR Push ;Leave one space for return value
  219.    
  220.     ADD R0,R2,#0
  221.     JSR Push
  222.    
  223.     ADD R0,R1,#0
  224.     JSR Push
  225.    
  226.     JSR Divide
  227.     JSR Pop ;Garbage
  228.     JSR Pop ;Garbage
  229.     JSR Pop ;Return value of A/B
  230.     ADD R3,R0,#0 ;R3 contains A/B
  231.    
  232. Multiply_Loop
  233.     ADD R3,R3,R3
  234.     ADD R2,R2,#-1
  235.     BRp Multiply_Loop
  236.    
  237.     NOT R3,R3
  238.     ADD R3,R3,#1
  239.     ADD R1,R3,R1
  240.     STR R1,R5,#0
  241.    
  242. End_Mod
  243.     JSR Pop
  244.     ADD R5,R0,#0
  245.    
  246.     JSR Pop
  247.     ADD R4,R0,#0
  248.  
  249.     JSR Pop
  250.     ADD R3,R0,#0
  251.  
  252.     JSR Pop
  253.     ADD R2,R0,#0
  254.  
  255.     JSR Pop
  256.     ADD R1,R0,#0
  257.    
  258.     RET
  259. ;---------------------------------------------------  
  260. ;Subroutine Divide - Divides a non-negative number by a positive number
  261.  
  262. ;Data Dictionary
  263. ;R1 - A (Dividend)
  264. ;R2 - B (Divisor)
  265. ;R3 - D (Division Counter)
  266.  
  267. ;Stack Frame:
  268. ;R5+0 - return value (will hold the value of paramter 1 / parameter 2)
  269. ;R5+1 - Parameter 2 (The divisor)
  270. ;R5+2 - Parameter 1 (The Dividend)  
  271. Divide
  272.     ADD R0,R1,#0
  273.     JSR Push
  274.  
  275.     ADD R0,R2,#0
  276.     JSR Push
  277.  
  278.     ADD R0,R3,#0
  279.     JSR Push
  280.  
  281.     ADD R0,R5,#0
  282.     JSR Push
  283.  
  284.     ADD R5,R6,#4
  285.     ;;Code Here
  286.     LDR R1,R5,#2 ;Load dividend
  287.     LDR R2,R5,#1 ;Load Divisor
  288.     AND R3,R3,#0 ;Initialize counter
  289.    
  290.     NOT R2,R2
  291.     ADD R2,R2,#1 ;Two's complement of divisor
  292.    
  293. Do_Div 
  294.     ADD R6,R2,R1
  295.     BRn End_Div
  296.     ADD R3,R3,#1
  297.     BR  Do_Div
  298.    
  299. End_Div
  300.     STR R5,R3,#0 ;Store result on stack
  301.    
  302.     JSR Pop
  303.     ADD R5,R0,#0
  304.  
  305.     JSR Pop
  306.     ADD R3,R0,#0
  307.  
  308.     JSR Pop
  309.     ADD R2,R0,#0
  310.  
  311.     JSR Pop
  312.     ADD R1,R0,#0
  313.    
  314.     RET
  315.  
  316. ;Constants required by print  
  317. ASCII_MINUS_SIGN  .fill #45   ;ASCII CODE for '-'
  318. ASCII_ZERO    .fill #48   ;ASCII CODE for '0'
  319.  
  320. ;---------------------------------------------------  
  321. ;Subroutine Print - Prints the argument on the stack onto the console. Will print both postive and negative numbers and zero.
  322.  
  323. ;Data Dictionary
  324. ;R0 -  Used for printing (should point to start of string before printing), and scratch register
  325. ;R5 - Frame pointer
  326. ;R6 - Stack Pointer
  327. ;R1 - parameter (which I call n)
  328. ;R2 - pointer to the local string allocated on the stack
  329. ;R3 - copy of the parameter value
  330. ;R4 - holds result of division
  331. ;R7 - return address to caller
  332.  
  333. ;Stack Frame:
  334. ;R5-13 - Start of string for holding number to be printed.
  335. ;R5-6 - Saved R7
  336. ;R5-5 - Saved R4
  337. ;R5-4 - Saved R3
  338. ;R5-3 - Saved R2
  339. ;R5-2 - Saved R1
  340. ;R5-1 - Saved R5
  341. ;R5+0 - Number to be printed (which I'll call n)
  342.  
  343.  
  344. Print
  345.   ADD R0,R7,#0
  346.   JSR Push          ;save R7 (since we will be using it)
  347.  
  348.   ADD R0,R5,#0     ;save R5, important since this routine may be called from another routine.
  349.   JSR Push
  350.  
  351.   ADD R5,R6,#2      ;make R5 point to return value
  352.  
  353.   ADD R0,R1,#0      ;save R1 (since we will be using it)
  354.   JSR Push
  355.  
  356.   ADD R0,R2,#0
  357.   JSR Push          ;save R2 (since we will be using it)
  358.  
  359.   ADD R0,R3,#0
  360.   JSR Push          ;save R3 (since we will be using it)
  361.  
  362.   ADD R0,R4,#0
  363.   JSR Push          ;save R4 (since we will be using it)
  364.  
  365.  
  366.   ADD R6,R6,#-7     ;set aside 7 bytes on stack for string (number is at most 5 digits, optional -, and must have a null terminator)
  367.  
  368.   ADD R2,R5,#-8     ;point to end of allocated space for string
  369.   AND R0,R0,#0      ;put #0 into R0
  370.   STR R0,R2,#0      ;put ascii code 0 into end of string memory
  371.  
  372.    
  373.   LDR R1,R5,#0      ;get arg (at R5+0)
  374.   ADD R3,R1,#0      ;make a copy of the parameter
  375.   ;need to determine if number is negative or not
  376.  
  377.   BRzp PosPrint
  378.  
  379.   NOT R1,R1         ;negate the negative
  380.   ADD R1,R1,#1      ;to get a positive number
  381.                     ;will put in - sign at the end
  382. PosPrint
  383.   ADD R2,R2,#-1     ;R2 points to the spot in string to place next digit  
  384.  
  385.   ;We will use standard div/mod by 10 to extract the digits of n.
  386.   ;Also the string needs to be built backwards, starting list the least significant digit.
  387.   ;For example, in the number 123, we need to get the 3 first, 2 second and the 1 last.
  388.  
  389.   ADD R0,R1,#0  
  390.   JSR Push          ;push R1 onto stack
  391.   AND R0,R0,#0      ;set R0 to 10
  392.   ADD R0,R0,#10
  393.   JSR Push          ;push #10 onto stack
  394.   ADD R6,R6,#-1     ;set space for return value
  395.  
  396.   JSR Divide        ;divide number by 10
  397.  
  398.   JSR Pop
  399.   ADD R1,R0,#0      ;R1 is now old R1 divide by 10
  400.  
  401. ; no need to remove the arguments, we're using them again anyway
  402. ;  ADD R6,R6,#2      ;remove args from stack
  403.  
  404.   ADD R6,R6,#-1     ;set space for return value
  405.  
  406.   JSR Modulo        ;number mod 10
  407.  
  408.   JSR Pop           ;R0 contains the last digit of number
  409.  
  410.   ADD R6,R6,#2      ;remove args from stack
  411.  
  412.   LD R4,ASCII_ZERO
  413.   ADD R0,R0,R4      ;R0 contains ASCII code for the digit
  414.   STR R0,R2,#0      ;store the digit (ASCII Code) into the string
  415.  
  416.   ADD R1,R1,#0      ;test value of number n.
  417.   BRp PosPrint      ;continue if it is positive
  418.  
  419. DonePrint
  420.  
  421.   ;deal with - sign if necessary
  422.  
  423.   ADD R3,R3,#0      ;look at n (recall R3 contains it)
  424.   BRzp NoMinus      ;see if it is non-negative, if so, do nothing
  425.  
  426.   ADD R2,R2,#-1     ;otherwise, add a '-' to the string.
  427.   LD R0,ASCII_MINUS_SIGN
  428.   STR R0,R2,#0
  429. NoMinus
  430.   ;Now print the string
  431.  
  432.   ADD R0,R2,#0      ;R0 now contains the
  433.   trap x22          ;print string.
  434.  
  435.   ADD R6,R6,#7      ;remove space for string on stack
  436.  
  437.   ;restore stack before returning
  438.  
  439.   JSR Pop
  440.   ADD R4,R0,#0  ;retore R4
  441.  
  442.   JSR Pop
  443.   ADD R3,R0,#0  ;retore R3
  444.  
  445.   JSR Pop       ;retore R2
  446.   ADD R2,R0,#0
  447.  
  448.   JSR Pop
  449.   ADD R1,R0,#0  ;retore R1
  450.  
  451.   JSR Pop       ;retore R5
  452.   ADD R5,R0,#0
  453.  
  454.   JSR Pop
  455.   ADD R7,R0,#0  ;retore R7
  456.  
  457.   RET
  458.  
  459.   .end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement