I am given this challenge:
A. Enter a number that specifies the number of elements in an array (force the user to enter a positive number and smaller than 30).
B. Initialize the table with the values entered from the address specified by the TAB label which must be defined as the last instruction in your program to annotate the free memory area.
C. Implement the code that reverses the content of your table.
This is my understanding with an example:
Input a number into my arraylist A, and the number should not be over 30. Here I input 12, 9, 10, 20, 30, 45, where 45 is bigger than 30, so it wouldn’t be put into the table, now the table is
A={12, 9, 10, 20, 30}
).Then the method of reverse table will reverse the order of the table A (now
A={30, 20, 10, 9, 12}
)Finally output the reversed table.
This is what it would look like in Java:
Arraylist<Integer> a=new new ArrayList<>();
a.add(12);a.add(9);a.add(10);a.add(20);a.add(30); // input the numbers
a.reverse(); //reverse the order
output(30, 29, 10, 9, 12)
Here is the code I have currently implemented in LMC:
INP
loop STA array
LDA count
SUB one
STA count
BRP loop
array DAT
DAT
DAT
count DAT 3
one DAT 1
First, I input all the values into an arraylist, but how can I switch their order?
CodePudding user response:
To be honest, there are the most basic things that are missing in your attempt.
The first input of the user is not data, but the size of the data. Your code does not deal with that at all, but instead uses a hard-coded size of 3. The idea that the size of the array is determined by the user, and that's why the first input is the size of the array, otherwise the program would not know when to stop asking for input.
Your code only asks for one input, and then stores that at
array
, but in the next loop you write the counter value in that location. The counter should never be stored in the array.There is no attempt in your code to store a value at the second entry in the array.
There is no attempt in your code to reverse the array.
Arrays
Working with arrays in LMC is quite cumbersome. There is no concept of indirect addressing, and so it needs self-modifying code. The complexity of such code is a lot(!) greater than what you presented, so you'll probably need to study this concept in more depth. Please check also:
- LMC - How to increment an address?
- How can I store an unknown number of inputs in different addresses in LMC?
- Programming arrays in LMC.
Algorithm
The program should:
Read the number of values in the array and store that number (
size
)Check that this number is less than 30
Use
size
to loop, and per iteration:- Read an input
- Store it in the array
- Update the previous program statement, so that next time it executes it will store to one address further in the array
Reverse the array in a loop:
- Read the first array value
- Copy it to a temporary location (
temp
) - Read the last array value
- Copy it to the first array value
- Read the temporary value
- Store it in the last array location
- Alter all the above program statements that access the array, so that "first" becomes "second" and "last" becomes "last-but-one"...etc
- If the address on the left side of the array crosses the address at the right side of the array, then stop: the reversal is complete.
You could then apply a similar loop to output the values of the array, but in comments you wrote:
C. Implement the code that reverses the content of your table. No display is required.
...so I will not include code to display the reversed array. You can check in the memory of the LMC that indeed the array is reversed.
Implementation
Here is an LMC program that applies the above described procedure. You can run it here.
#input: 5 1 2 3 4 5
INP
STA size
SUB thirty
BRP quit
start LDA statab
next STA store
INP
store STA tab
LDA size
SUB one
STA size
BRZ reverse
LDA store
ADD one
BRA next
reverse LDA store
STA storeright
SUB statab
ADD ldatab
STA loadright
LDA ldatab
STA loadleft
LDA statab
swap STA storeleft
loadright LDA tab
STA temp
loadleft LDA tab
storeright STA tab
LDA temp
storeleft STA tab
LDA loadleft
ADD one
STA loadleft
LDA loadright
SUB one
STA loadright
SUB loadleft
BRP continue
quit HLT
continue BRZ quit
LDA storeright
SUB one
STA storeright
LDA storeleft
ADD one
BRA swap
statab STA tab # template code
ldatab LDA tab # template code
one DAT 1
thirty DAT 30
size DAT
temp DAT
tab DAT
<script src="https://cdn.jsdelivr.net/gh/trincot/[email protected]/lmc.js"></script>
If you run it as-is, the input is 5 1 2 3 4 5. The first 5 means there are 5 values that follow in the input. The real data is 1 2 3 4 5. You can change the input to your wishes. Once you have run it, scroll down to check the contents at the tab
label, at the end of the program. There you will see
tab DAT 5
DAT 4
DAT 3
DAT 2
DAT 1
Self-modifying
The self-modifying part of the code is most difficult (obscure) part. For instance, this statement:
loadright LDA tab
...starts as LDA tab
, but then later 1 is added to this instruction (think about that!), so that it is more like LDA tab 1
(this is not valid syntax, but I mean it targets the memory after tab
). So the next time this statement executes it will load from a different address.
The same principle is applied at several places in the program.