# Simple assembly language program for theoretical CPU

Discussion in 'Assembly Language Programming (ALP) Forum' started by saiai, May 22, 2009.

1. ### saiaiNew Member

Joined:
May 22, 2009
Messages:
5
0
Trophy Points:
0
I'm currently working on a school assignment using a theoretical CPU with a very limited instruction set. The available instructions are as follows:

Code:
```add // add registers
sub
and
andi
or
ori
xor
xori
nor
sll // shift left logical
srl // shift right logical
sra // shift right arithmetic
sw // store word
sh
sb
beq // branch on equal
bne // branch on not equal
blt // branch on less than
ble // branch on less than or equal
j // jump
jr // jump register
```
Registers are named as r0, r1, ..., r31. One part of the assignment is to write a very simple program for this CPU in assembly language, "such as 1+1=2". I'm an extreme beginner at assembly language and would therefore like to ask for some tips. For example, would the below program work to calculate 1+1? (comments ignored):

addi r1, r0, 1 // add 1 to zero register, store in r1
addi r2, r0, 1 // add 1 to zero register, store in r2
add r3, r2, r1 // add r1 and r2, store in r3
sb r3 0(r1) // store contents of r3 to memory address 1 (r1 = 1 and dpl = 0)

I may be completely off track with this so please tell me if it looks weird. Also, if you have any ideas about slightly more complex programs (that use a branching instruction, for example) I'd greatly appreciate your suggestions.

Last edited by a moderator: May 22, 2009
2. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
You need to know more than just the keyword to write programs. For example, what does addi a,b,c mean, is it a+b=c, or a=b+c, or b=a+c, or (accumulator)=a+b+c, or *a=*b+*c, or something else?

Are there any details about the CPU posted anywhere; are you using a theoretical one of your own design or a design you got from somewhere?

3. ### saiaiNew Member

Joined:
May 22, 2009
Messages:
5
0
Trophy Points:
0
Thanks for the reply. I've added descriptions and syntax below. rs = source register, rt = target register, rd = destination register.

Code:
```add // rd <-- rs + rt // R-type
addi // rt <-- rs + imm // I-type
sub // rd <-- rs - rt // R-type
lui // rt <-- imm <<16 (shift) // I-type
and // rd <-- rs AND rt (bitwise) // R-type
andi // rt <-- rs AND imm // I-type
or // rd <-- rs OR rt // R-type
ori // rd <-- rs OR imm // I-type
xor // rd <-- rs XOR rt // R-type
xori // rt <-- rs OR imm // I-type
nor // rd <-- rs NOR rt // R-type
sll // rd <-- rs llshift aux[10, 6] // R-type
srl // rd <-- rs lrshift aux[10, 6] // R-type
sra // rd <-- rs arshift aux[10, 6] // R-type
lw // rt <-- mem(rs + dpl) // I-type
lh
lb
sw // mem(rs + dpl) <-- rt // I-type
sh
sb
beq // if rs == rt then PC = PC + dpl // I-type
bne // if rs !== rt then PC = PC + dpl // I-type
blt // if rs < rt then PC = PC + dpl // I-type
ble // if rs <= rt then PC = PC + dpl // I-type
j // PC <-- addr // A-type
jal // r31 <-- PC + 4; PC <-- addr // A-type
jr // PC <-- rs // R-type```
-- SYNTAX --
R-type: <op> rd, rs, rt
I-type: <op> rt, rs, imm

Registers are named as r0, r1, ..., r31. One part of the assignment is to write a very simple program for this CPU in assembly language, "such as 1+1=2". I'm an extreme beginner at assembly language and would therefore like to ask for some tips. For example, would the below program work to calculate 1+1? (comments ignored):
Code:
```addi r1, r0, 1 // add 1 to zero register, store in r1
addi r2, r0, 1 // add 1 to zero register, store in r2
add r3, r2, r1 // add r1 and r2, store in r3
sb r3 0(r1) // store contents of r3 to memory address 1 (r1 = 1 and dpl = 0)```
I haven't been able to find more details about the CPU design online. It is presented in a textbook for the class I'm taking. I'm currently doing an exchange year in Japan so the textbook is in Japanese and even though I can understand it fairly well it does make things slightly harder. :goofy:

4. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
I would say probably not, because it depends on the initial value of r0.
If r0 starts off as zero, what do you think the result will be? If you're not sure, take it a step at a time.
What is the result of addi r1,r0,1?
Then when you've worked that out, what is the result of addi r2,r0,1?
And so on. That's how you solve problems like this.

5. ### saiaiNew Member

Joined:
May 22, 2009
Messages:
5
0
Trophy Points:
0
Since r0, the zero register, has a constant value 0, my reasoning is that
Code:
`addi r1, r0, 1`
will add together 0 + 1 (r0 and imm 1) and store the result (=1) in r1. Is this incorrect?

6. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
Why are you asking if this is incorrect?
What exactly don't you understand about
Code:
```addi // rt <-- rs + imm // I-type
```
Also what happens if you run the program; does it do what you expect?

I'm puzzled about why you want to know in advance what will happen. Experimentation is key to learning and you will develop the skills to perform a dry run in your head only in conjunction with much experimentation. What's the worst that can happen if you just try it and see what happens? If it doesn't do what you expect then you can start to figure out why.

7. ### saiaiNew Member

Joined:
May 22, 2009
Messages:
5
0
Trophy Points:
0
Thanks for the feedback.

Perhaps I've explained my problem poorly. This instruction set and its syntax is, afaik, not supported by an actual CPU. It is merely a hypothetical one introduced for this particular assignment. However, one may assume that it accepts the instructions and syntax mentioned above.

I'm only interested in knowing whether my suggested program is a reasonable approach for a program that performs some simple operations, such as 1+1=2. Had it been a high-level programming language, I might have created two variables say x and y, assign x = 1 and let y = x + x, but since I have no previous experience in assembly language I'm not sure how to appropriately represent such operations.

If I wanted to be able to compile and test the program I would need to design the actual CPU, right? Is this doable with only the information given in this thread?

Does this make things any clearer or have I just proven my ignorance? :freak:

8. ### xpi0t0sMentor

Joined:
Aug 6, 2004
Messages:
3,009
203
Trophy Points:
63
Occupation:
Senior Support Engineer
Location:
England
OK, fair point, I had missed the fact that this CPU doesn't actually exist. So you have no choice but to dry run it in your head. I'm reluctant just to say "yes" or "no" because it's in discovering the answer for yourself that you will learn. But maybe nobody's actually bothered to explain how to dry run a program, so here's how I would do it. We'll assume that r0 starts off at zero:

Initiali register values: r0=0; r1=?; r2=?; r3=? (? means unknown value)

Let's look at the first instruction: addi r1, r0, 1 // add 1 to zero register, store in r1

If this works correctly, the new values of the registers above will be:
r0=0; r1=1; r2=?; r3=?

After addi r2, r0, 1 // add 1 to zero register, store in r2
the registers should contain r0=0; r1=1; r2=1; r3=?

After add r3, r2, r1 // add r1 and r2, store in r3
the registers should contain r0=0; r1=1; r2=1; r3=2

sb r3 0(r1) // store contents of r3 to memory address 1 (r1 = 1 and dpl = 0)
Memory location 1 should now contain the value 2.

(note "should". That comes from many years of experience with computers and finding it's always a good idea to hedge your bets. Feel free to replace this with "will" if you see fit.)

Joined:
May 22, 2009
Messages:
5