Simple assembly language program for theoretical CPU

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

  1. saiai

    saiai New Member

    Joined:
    May 22, 2009
    Messages:
    5
    Likes Received:
    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
    addi // add immediate
    sub
    lui // load upper immediate
    and
    andi
    or
    ori
    xor
    xori
    nor
    sll // shift left logical
    srl // shift right logical
    sra // shift right arithmetic
    lw // load word
    lh // load half word
    lb // load byte
    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
    jal // jump and link
    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. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    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. saiai

    saiai New Member

    Joined:
    May 22, 2009
    Messages:
    5
    Likes Received:
    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
    A-type: <op> <addr>

    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. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    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. saiai

    saiai New Member

    Joined:
    May 22, 2009
    Messages:
    5
    Likes Received:
    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. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    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. saiai

    saiai New Member

    Joined:
    May 22, 2009
    Messages:
    5
    Likes Received:
    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. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    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.)
     
  9. saiai

    saiai New Member

    Joined:
    May 22, 2009
    Messages:
    5
    Likes Received:
    0
    Trophy Points:
    0
    Thanks, I feel I've somewhat got the hang of it now. :pleased:

    Also, your advice has made me want to try to do more than just a "dry run", so I might start looking into some actual CPU design after this. Thanks again!
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice