How does the opcode JUMP work in the EVM Stack? - ethereum

I'm following along on the "Advanced Solidity" tutorial here.
I ran into an example I'm having trouble understanding.
In this example, why does JUMP affect the state of the stack? I expected it to only affect the program counter.
(i.e. I would expect after JUMP, at PC: 11, the length of the stack would be 3, not 2. The JUMP comes after PUSH 0x0B.)
Thanks.

Just to refer to the original docs. As stated in the yellow paper :
0x56 JUMP 1 0 Alter the program counter
Where 1 is the number of items taken out of the stack, 0 the number of items returned. So in your case JUMP removes '0b' from the stack and use it as the destination (PC = 11 = 0x0b).

Figured it out.
JUMP takes the value at the top of the stack to use as the destination.
That value "becomes" the destination.
A JUMP could be thought of as performing a PUSH first, and moving the program counter to the pushed value.
Credit to Martin / #holiman on the ethereum/tests Gitter. Thanks.

Related

How does subtraction work in the Hack VM?

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-/

Max number of words to jump over in the PC-relative addressing mode

I'm reading a book of David Patterson and John Hennesy titled: Computer Organization and Design. In the RISC-V architecture set which the book is about there are two instruction formats related to jumping - SB-type and UJ-type. The former uses 12-bit constant to represent offset (in bytes) to jump from the current instruction and the latter uses 20-bit constant to represent the same. Then the author says the following:
Since the program counter (PC) contains the address of the current instruction, we can branch (SB-type) within +=2^10 words of the current instruction, or jump (UJ) within += 2^18 words of the current instruction, if we use the PC as the register to be added to the address.
I don't understand how they get those 2^10 and 2^18. Since the constant the instructions use is two's complement, then it can represent values from -2^11 to 2^11 - 1 in the first case and -2^19 to 2^19 - 1 in the second case. Since these constants represent bytes, but we want to know how many words we can jump over, therefore we need to divide max value of bytes by four, so the max which we can get is 2^11 / 2^2 = 2^9 words in the first case and 2^17 in the second one.
Could someone please take a look at my calculations above and point me out to what I'm missing and what's wrong with my calculations and thoughts?
UPDATE:
Probably I didn't understand the author correctly. May it be the case that they mean the lower-bound (-2^10) and upper-bound (+2^10)? So they mean that we can never jump beyond 2^10 from the current instruction?

How do I print a specific bit of a number?

I'm struggling with this question:
Prompt the user to enter a number, print the number in 16-bit two's complement
To print the number you will print each bit as either the string "1"
or the string "0", using a loop that will print one bit in each
iteration. Start printing with bit 15. (Recall that we number the bits
starting from 0 at the low order bit.) In your loop test bit 15, and
then print either "1" or "0". Use a shift instruction to get the next
bit into position 15 before repeating.
I unfortunately missed a lecture that was about shifts and using masks, so I don't really have much understanding of how I would go about doing this lab. How can I print a specific bit of a number? I understand that I just keep printing bit 15, and then doing a shift left, but I have no idea this would be done in MIPS. Any help would be very much appreciated.
EDIT:
I understand the shifting perfectly, it's just printing the bit thats confusing me.
For example, if the number I wanted to convert to two's complement was 25 and is in register $t0.
First I print the 15th bit. Then I do a shift left. And then I repeat 15 times.
It should look something like this:
# Print bit
sll $t0, $t0, 1
I just don't get how to print the first bit at spot 15.
break down the problem --
1. how to print the bit, and
2. how to determine the bit's value
You already know how to determine the bit's value, you test bit 15 and keep shifting the other bits into position 15.
How are you expected to "prompt the user" to enter a value? Printing the bit is the same printing a prompt.
Masks are generally used with "bitwise and" or "bitwise or" instructions.
To determine whether a particular single bit is set to 1 in a number,
you take the "bitwise and" of that number with another number (the "mask")
in which that particular bit is set to 1 and all other bits are zero.
(There are other applications where you would want to set more than one bit in
a mask; better get a copy of those lecture notes!)
There are many places to look up the MIPS instruction set. For example, here
or here.
Find a page like those, then search for "shift left" and "bitwise and".
(And remember where you found that document so you can look up other things later!)

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.

Verilog branch instruction MIPS

I am trying to understand how the verilog branch statement works in an immediate instruction format for the MIPS processor. I am having trouble understanding what the following Verilog code does:
IR is the instruction so IR[31:26] would give the opcode.
reg[31:0] BT = PC + 4 + { 14{IR[15]}, IR[15:0], 2'b0};
I see bits and pieces such as we are updating the program counter and that we are taking the last 16 bits of the instruction to get the immediate address. Then we need a 32 bit word so we extend 16 more zeros.
Why is it PC + 4 instead of just PC?
What is 2'b0?
I have read something about sign extension but don't quite understand what is going on here.
Thanks for all the help!
1: Branch offsets in MIPS are calculated relative to the next instruction (since the instruction after the branch is also executed, as the branch delay slot). Thus, we have to use PC +4 for the base address calculation.
2: Since MIPS uses a bytewise memory addressing system (every byte in memory has a unique address), but uses 32-bit (4-byte) words, the specification requires that each instruction be word-aligned; thus, the last two bits of the address point at the bottom byte of the instruction (0x____00).
IN full, the instruction calculates the branch target address by taking the program counter, adding 4 to account for hte branch delay slot, and then adding the sign extended (because the branch offset could be either positive or negative; this is what the 14{IR[15]} does) offset to the target.
Numbers in Verilog can be represented using number of bits tick format of the following number.
2'b11; // 2 bit binary
3'd3 ; // 3 bit decimal
4'ha ; // 4 bit hex
The format describes the following number, the bit pattern used is not changed by the format. Ie 2'b11 is identical to 2'd3;