How does subtraction work in the Hack VM? - nand2tetris

I'm taking the Nand2Tetris course on Coursera, the one where we translate VM Bytecode to asm, and I'm a bit confused on how the sub opcode is supposed to work in Project 7.
Assuming I've got code that looks like this
push constant 5
push constant 7
sub
I'd expect the output to be 2, but its -2 instead.
7 was the last thing pushed onto the stack, and I'm assuming the first thing popped off it, but it wasn't the first "argument" to sub? Why is that?

This is just the way two-operand stack operations are defined to work. The way to visualize it is that the operator is moved between the two numbers.
This system also makes it much easier to convert from normal notation, since all you have to do is move the operators, not reorder the numbers.
For example, (1+2)/(4-3) becomes 12+43-/

Related

Turing Machine to compare multiple binary numbers

I was wondering how to construct a Turing Machine for
A<B<C<D...<N
with all numbers (A,B,C,D,...,N) being positive binary numbers.
These are a couple examples of how the machine should work:
1001 - Accepts because there is only one number
0<1 - Accepts
0010<1000<0001 - Doesn't accept because 1000!<0001
0100<1010<1010<1000 - Doesn't accept because 1010!<1010
I've tried methods that work to compare only two numbers but I can't seem to find a way to compare multiple (should work for infinite number of inputs) numbers.
Here is a high-level block diagram for solving this problem. You can implement these blocks by using block feature of JFLAP.
Blocks Description
Done? : This block decides whether all comparisons are done, if yes, it accepts, otherwise, it goes to compare the very next two numbers.
A<B : This block is responsible to compare two binary numbers, the one that cursor is pointing at the first digit and the next one. You can use '<' as the separator between A and B and the next number.
cleanup: during the comparison, you might marked 0's and 1's to something else. This block clean up everything and prepare everything for the next comparison.
Hopefully, this gives you an idea to solve the problem.

How to do a base conversion with Little Man Computer?

I need to convert a decimal number to a base between 2 and 9 using Little Man Computer. How do I proceed?
I believe successive divisions are the best method. In my opinion, I must write a code which divides two numbers, then save the integer ratio for the next division, as well as all of the remainders in an array of indefinite size, but I've been struggling with the division code for hours now. I tried searching for a code which divides two numbers, but all the ones I tried have mistakes/don't work. I'm stuck at the easiest part of the problem, I can't imagine how I'm ever going to be able to write a self-modifying code which manages an array of ever-increasing line positions and backtracks through it at the end to extract all the remainders. I'm at a loss here, any help would be appreciated.

How best to represent negative-binary numbers for use in counters and comparators in Verilog HDL?

I have been designing a Delta-Sigma DAC and have run into confusion and despair over the handling of signed numbers in my (sigma)counters and (delta and Vref) comparators.
I have tried to employ signed 2's complement but the EDAcompiler doesn't seem to notice when I do it, its most likely my own mistake!
So basically my question is, how (in Verilog) do I represent negative numbers in a way that they can be used in counters (which can therefore count up and down)? I am aware that a counter register that will hold signed numbers must be declared reg signed [:0]
Thanks!
Gavin
Well I am not that clear on your question. Some compilers may not be able to handle signed registers directly since if I recall correctly it is a Verilog 2001 feature. But generally if you use digital logic that works with signed numbers you shouldn't have an issue. For example if you use an adder ip just mention that inputs are signed numbers. As for the simulator you can select the type of data you need, generally by selecting the register/value, right clicking on the waveform window and changing the type.
Finally if you have to create the logic yourself just use sign extension. so lets say you are working with 4 bit values
-5 would be 11111011 and 5 wold be 00000101. So you can see that for negative numbers the MSB is 1 and for positive its zero. Using this you can interpret the numbers in your code but just make sure that the size is bigger then what you want to use so no overflow occurs.

PIC Assembly: Calling functions with variables

So say I have a variable, which holds a song number. -> song_no
Depending upon the value of this variable, I wish to call a function.
Say I have many different functions:
Fcn1
....
Fcn2
....
Fcn3
So for example,
If song_no = 1, call Fcn1
If song_no = 2, call Fcn2
and so forth...
How would I do this?
you should have compare function in the instruction set (the post suggests you are looking for assembly solution), the result for that is usually set a True bit or set a value in a register. But you need to check the instruction set for that.
the code should look something like:
load(song_no, $R1)
cmpeq($1,R1) //result is in R3
jmpe Fcn1 //jump if equal
cmpeq ($2,R1)
jmpe Fcn2
....
Hope this helps
I'm not well acquainted with the pic, but these sort of things are usually implemented as a jump table. In short, put pointers to the target routines in an array and call/jump to the entry indexed by your song_no. You just need to calculate the address into the array somehow, so it is very efficient. No compares necessary.
To elaborate on Jens' reply the traditional way of doing on 12/14-bit PICs is the same way you would look up constant data from ROM, except instead of returning an number with RETLW you jump forward to the desired routine with GOTO. The actual jump into the jump table is performed by adding the offset to the program counter.
Something along these lines:
movlw high(table)
movwf PCLATH
movf song_no,w
addlw table
btfsc STATUS,C
incf PCLATH
addwf PCL
table:
goto fcn1
goto fcn2
goto fcn3
.
.
.
Unfortunately there are some subtleties here.
The PIC16 only has an eight-bit accumulator while the address space to jump into is 11-bits. Therefore both a directly writable low-byte (PCL) as well as a latched high-byte PCLATH register is available. The value in the latch is applied as MSB once the jump is taken.
The jump table may cross a page, hence the manual carry into PCLATH. Omit the BTFSC/INCF if you know the table will always stay within a 256-instruction page.
The ADDWF instruction will already have been read and be pointing at table when PCL is to be added to. Therefore a 0 offset jumps to the first table entry.
Unlike the PIC18 each GOTO instruction fits in a single 14-bit instruction word and PCL addresses instructions not bytes, so the offset should not be multiplied by two.
All things considered you're probably better off searching for general PIC16 tutorials. Any of these will clearly explain how data/jump tables work, not to mention begin with the basics of how to handle the chip. Frankly it is a particularly convoluted architecture and I would advice staying with the "free" hi-tech C compiler unless you particularly enjoy logic puzzles or desperately need the performance.

solving Project Euler #305

Problem # 305
Let's call S the (infinite) string
that is made by concatenating the
consecutive positive integers
(starting from 1) written down in base
10.
Thus, S =
1234567891011121314151617181920212223242...
It's easy to see that any number will
show up an infinite number of times in
S.
Let's call f(n) the starting position
of the nth occurrence of n in S. For
example, f(1)=1, f(5)=81, f(12)=271
and f(7780)=111111365.
Find Summation[f(3^k)] for 1 <= k <=
13.
How can I go about solving this?
Calculating S to an arbitrary size is deceivingly easy, but as you have probably already found out, not practical, it simply becomes too big .
As is common for the newer Project Euler Problems, brute force simply does not work.
That said, you can still look at S for small values of k and maybe construct a formula that will solve the problem in parts (the first few values are easy to handle in memory). Also, look at Problem 40
Note: remember the one minute rule. (most problems can be solved in a few milliseconds)
My estimate of the running time is O(n2 log n), so this brute force approach is not feasible.
Note that you are supposed to solve Project Euler problems yourself, which IMHO applies in particular to newer problems.