Trying to make an LC3 binary code that checks if 2 numbers are equal - lc3

I am trying to make a machine instruction program that asks for two user inputs(single digit) and then checks that two numbers are the same. Then it stores the first user input into the Register R3, and the second user input into R4. If two numbers are the same, the R5 will be set 1. Otherwise, R5 is 0. Finally, print out the check result R5(The printing result is Optional).

Related

Reversing byte input with basic assembly code

I'm participating in a ctf where one task is to reverse a row of input bytes using an assembly-ish environment. The input is x bytes long and the last byte is always 0x00. One example would be :
Input 4433221100, output 0011223344
I'm thinking that a loop that loops until it reaches input 00 is a place to start.
Do any of you have a suggestion on how to approach this? I don't need specific code examples, but some advice to point me in the right direction would be great. I only have basic alu operations, jumps and conditional jumps, storing and reading memory addresses, and some other basic stuff available. All alu operations are mod 256.
Yes, finding the length by searching for the 0 byte to find the end / length is one way to start. Depending on where you want the destination, it's possible to copy in the same loop that searches for the end.
If you want to reverse in-place, you need to find the end first (with a separate loop). Then you can load from both ends, store registers to opposite locations, and walk your pointers inward until they cross, standard in-place reverse that you can find examples of anywhere.
If you want make a reversed copy into other space, you could do it in one pass over the source (without finding the length first). Store output starting from the end of a buffer, decrementing the output pointer as you increment the read pointer. When you're done, you have a pointer to the start of the reversed copy, which you can pass to an output function. You won't know where you're going to stop, so the buffer needs to be big enough. But since you're just passing the pointer to another function, it's fine that you don't know (until you're done copying) where the start of the reversed copy will be.
You could still separately find the length and then copy, but that would be pointlessly inefficient.
If you need the reversed copy to start at some known position in another buffer (e.g. to append to another string or array), you would need the length or a pointer to the end before you store anything, so it's a 2-pass operation like reversing in-place.
You can then read the source backwards and write the destination forwards (or "output" each byte 1 at a time to some IO stream). Your loop termination condition could be a down-counter or a pointer compare using a pointer in a register, comparing src against the already-known start of the source or dst against the calculated end of the destination.
Or you can read the source forwards until you reach the position you found for the end, storing in reverse order starting from the calculated end of where the destination should go.
(If your machine is like 6502 and can easily index into a static array, but not easily keep a whole pointer in a register, obviously you'll want to use indices that count from 0. That makes detecting the start even easier, like sub reg, 1 / jnz if subtract already sets flags for a conditional branch to test.)
save your stackpointer in a variable
for each byte of the string
push byte onto the stack
repeat if byte was <> 0
pull byte from stack
output byte
repeat until old_stackpointer is reached
in 6502 assembler this could look like
tsx
stx OLD_STACKPTR
ldy#$ff
loop:
iny
lda INPUT,y
pha
bne loop
ldy#$ff
loop2:
iny
pla
sta INPUT,y
tsx
cpx OLD_STACKPTR
bne loop2

Design an algorithm to input 2 numbers and then output the lowest number in little man computing

I have a program I'm doing and I want to input two numbers so that the LMC can output the smallest one. MY code is giving me the biggest number, help me fix it.
INP
STA first
INP
STA second
SUB second
BRP secondBig
LDA second
OUT
BRA endProgram
secondBig LDA second
OUT
endProgram HLT
first DAT
second DAT
You're storing both input values in first, which means you overwrite the first one with the second.
Both before and after fixing the above, your code isn't outputting the biggest, it is outputting the second (regardless of relative size). Single-stepping, or actually reading the code, should tell you why.
Invert your conditional branch: use BRN (branch negative) instead of BRP.
Alternately, switch the logic branches that decide which value will be available for output.
The problem was that you compared the second input with itself. You could insert LDA first just before SUB second, but if you invert the output blocks, you can avoid that extra LDA
It is also confusing that you have a label "secondBig", when in fact you are not looking for the biggest number, but the smallest
Correction:
#input: 4 7
INP
STA first
INP
STA second
SUB first
BRP firstLeast
LDA second
OUT
BRA endProgram
firstLeast LDA first
OUT
endProgram HLT
first DAT
second DAT
<script src="https://cdn.jsdelivr.net/gh/trincot/lmc#v0.7/lmc.js"></script>

crc32 calculating (i'm in despair)

I have been hanging on it too much time...
I've read «A Painless Guide to CRC Error Detection Algorithms» several times. May be I not completely understand theory, but practice seems as clear as sky, but something wrong.
I'm not about code and particular realization, but conceptual (a plain method).
I do this:
1. Take a single byte.
2. Take a uint and fill it with 0xffffffff.
3. Check if the highest bit is 1.
4. Shift one bit to the left.
5. Put the next bit from source byte.
6. It Step3 checking is true, then XOR it with 0x04C11DB7.
7. After data is end, reverse (reflect) working uint.
8. XOR it with 0xffffffff
And it works... but only with zeros (I've checked 1,2,3,4 bytes of zeros). But when I take a byte 0x01 it fails (online calculators show different result). I just can't catch what am I doing wrong.
Step by step (mine version with lowest bit first):
01.Initialization 0xffffffff
02.Shift<< 0fffffffe
03.Place that single 1 0xffffffff
04.XOR 0xfb3ee248
05.Shift<< 0xf67dc490
06.XOR 0xf2bcd927
07.Shift<< 0xe579b24e
08.XOR 0xe1b8aff9
09.Shift<< c3715ff2
10.XOR 0xc7b04245
11.Shift<< 0x8f60848a
12.XOR 8ba1993d
13.Shift<< 0x1743327a
14.XOR 0x13822fcd
15.Shift<< 0x27045f9a
16.Shift<< 0x4e08bf34
17.Reflect 0x2cfd1072
18.XOR (0xffffffff) 0xd302ef8d (the result)
Please help! What is wrong with it?
At last, I've got the reciept. It took much time, but I reinvented it ))
Share it with anyone, who need it:
1. Take first 4 bytes from message (if it less than 4 byte - add zeros). May be you will need to reflect bits in EVERY byte (I have to, but I think it depends on particular architecture). Put it into Register (uint).
2. Make Register XOR 0xFFFFFFFF.
3. Shift one bit left.
4. Place the next message's bit (the lowest one first) to the right side of Register.
5. If shifted bit was 1, than Register XOR 0x04C11DB7.
6. Do steps 3-5 until the end of the message.
7. Do steps 3-5 for 32 bits of zeros (if the message is less than 32 bits, than this number must correspond with input length).
7. Reflect bits in the whole Register.
8. Make Register XOR 0xffffffff.
That's it - you have the CRC32, which all online calculators show and, at least, correct for deflate, PNG, etc.

How to BR with nzp=000 in LC3

I tried to write the inst x0000 which means BR with nzp=0 and offset 0.
I wrote BR #0 in the simulator.
Instead of giving me that x0000 on the simulator,
I get 0x0E00 which means nzp is 111.
What is the correct way of doing this?
You cannot have nzp=000. A number is either negative, zero or positive.
According to this course on LC3 from UPenn
LC-3 has three 1-bit condition code registers
N - negative
Z - zero
P - positive (greater than zero)
Exactly one will be set at all times.
Based on the last instruction that altered a register.
You can do NOP because if nzp=000 it means that the PC won't change, so you just need to pass this instruction.
Another option is do LABEL .fill x0000 because the instruction code of BR with nzp=0 and offset 0 will be just 000.
BR will assemble to branch-always, which is exactly the same as BRnzp, which is why you're seeing that in the assembled code.

Splitting files with redundancy

I need a cmd tool or an algorithm description to do the following:
Given a file of any size (size < 1GB) I need to split the file into n parts (n may be any reasonable number) and 1 file with metadata.
Metadata is something similar to "parity" byte in RAID systems, that will allow me to restore the whole file if one part of the file is lost. So, the metadata is kind of 'extra' or redundant info that helps to restore original file.
Other n parts should not have any extra information.
For now, I tries to use pacrhive and par2 tools but they don't implement the idea I described above.
Also I tried to get into Forward error corrections (FEC) and Reed-Solomon codes but also didn't succeed there.
Thanks for any help.
You can apply something almost identical to RAID 5 (although that's for hard drives, the same logic applies).
So, send the 1st byte to the 1st file, the 2nd to the 2nd, ..., the nth to the nth, the (n+1)th to the 1st, the (n+2)th to the 2nd, etc.
Then just put the parity of each bit across the n files into the last file, i.e.:
1st bit of last file = 1st bit of 1st file
XOR 1st bit of 2nd file
XOR ...
XOR 1st bit of nth file
2nd bit of last file = XOR of 2nd bits of all the other files as above
This will allow you to restore any file (including the 'metadata' file) by just calculating the parity of the rest of files.

Resources