Thread: ASSEMBLY LEVEL Programming

  1. #1
    Registered User
    Join Date
    May 2012
    Posts
    210

    ASSEMBLY LEVEL Programming

    Hi guys!
    I'm trying to understand Assembly language after moving on from C programming. This forum has helped me ALOT thats why I couldnt help but post here. So I have this code for adding 1 to the number 46. It works perfectly. I wanted to introduce a counter every time they left shift it aka when "lhi" and "addui" are used. So in total there would be bla shifts. and the answer displayed in the end would be bla.
    I attempted to do this by writing this after everytime lhi and addui would appear
    Code:
     add r31,r0,1
    Register 0 is automatocally programmed to 0 so 0+1 = 1 would be stored in R31. And that would display in the end. But I'm afraid it's not as simple as this. Please bear with me. I am very interested in learning this.
    Code:
    .global _exit.global _open
    .global _close
    .global _read
    .global _write
    .global _printf
    .global _a
    
    
            .align 4
    _a:
            .word 46
    
    
    LC0:
            .ascii "Value of a is %d\12\0"
            .align 4
    .global _main
    _main:
            ;; Initialize Stack Pointer
            add r14,r0,r0
            lhi r14, ((memSize-4)>>16)&0xffff
            addui r14, r14, ((memSize-4)&0xffff)
            ;; Save the old frame pointer 
    sw -4(r14),r30
            ;; Save the return address 
            sw -8(r14),r31
            ;; Establish new frame pointer 
            add r30,r0,r14
            ;; Adjust Stack Pointer 
            add r14,r14,#-24
            ;; Save Registers 
            sw 0(r14),r3
            sw 4(r14),r4
            sw 8(r14),r5
            lhi r3,(_a>>16)&0xffff
            addui r3,r3,(_a&0xffff)
            lhi r4,(_a>>16)&0xffff
            addui r4,r4,(_a&0xffff)
            lw r4,0(r4)
            add r4,r4,#1
            sw 0(r3),r4
            sub r14,r14,#8
            lhi r5,(LC0>>16)&0xffff
            addui r5,r5,(LC0&0xffff)
            sw 0(r14),r5
            lhi r3,(_a>>16)&0xffff
    addui r3,r3,(_a&0xffff)
            lw r5,0(r3)
            sw 4(r14),r5
            jal _printf
            nop
            add r14,r14,#8
    L1:
            ;; Restore the saved registers
            lw r3,-24(r30)
            nop
            lw r4,-20(r30)
            nop
            lw r5,-16(r30)
            nop
            ;; Restore return address
            lw r31,-8(r30)
            nop
            ;; Restore stack pointer
            add r14,r0,r30
            ;; Restore frame pointer
            lw r30,-4(r30)
            nop
            ;; HALT
     jal _exit
            nop
    
    
    _exit:
            trap #0
            jr r31
            nop
    _open:
            trap #1
            jr r31
            nop
    _close:
            trap #2
            jr r31
            nop
    _read:
            trap #3
            jr r31
            nop
    _write:
            trap #4
            jr r31
            nop
    _printf:
            trap #5
            jr r31
            nop

  2. #2
    Registered User
    Join Date
    May 2012
    Posts
    210
    typo!!! *NOT BLA but actually 5 shifts

  3. #3
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    I don't know the processor, but looking at your code, you can initialize R31 to zero and later increment it using these instructions:

    Code:
    ; ...
            add r31,r0,r0
    ; ...
            add r31,r31,#1

  4. #4
    Registered User
    Join Date
    May 2012
    Posts
    210
    Well I'm using it on Putty and it's DLX
    I added what you said but there is no change whatsoever the answer is still 47
    Even though I have stored the value of 47 I want it to print out 5.
    Thats the point of the counter.
    I havent changed the printf statement because I want to see what it prints. it supposed to be printing whatever is in r31. And that is the counter.
    So the code is the same as above this is what I did
    Code:
    _main:
            add r31,r0,r0
    ;;;  Initialize Stack Pointer
                    add r14,r0,r0
                    lhi r14, ((memSize-4)>>16)&0xffff
                    addui r14, r14, ((memSize-4)&0xffff)
    add r31,r31,#1
    ;;;  Save the old frame pointer
                    sw -4(r14),r30

  5. #5
    Registered User
    Join Date
    Jan 2011
    Posts
    144
    general question:
    Is there any forum such as this one dedicated to assembly language?

  6. #6
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    When you call (branch and link) to _printf, where does it get it's values from, some registers or from the stack? I didn't see any changes made to include R31 in the printed output, or does _printf always print the contents of R31? Doing a web search it seems you would need to store R31 at 0(R14) then call _printf.

    It would help to know how _printf() is supposed to work. Do you have a document or manual that you could post a link to?

    As far as other forums, try a web search for "DLX assembly language".
    Last edited by rcgldr; 09-15-2013 at 06:12 PM.

  7. #7
    - - - - - - - - oogabooga's Avatar
    Join Date
    Jan 2008
    Posts
    2,808
    DLX - Wikipedia, the free encyclopedia

    What's up with all the "nop" instructions?

    There aren't really any shifts in your code. They all occur on immediate values and would be precalculated by the assembler, not executed by the processor. (Since immediate values can only be 16 bits, a 32 bit value must be loaded in two steps, hence the use of the shifts and masks.)

    You can't use r31 for your counter since that register is dedicated to holding return addresses.

    Below I've removed your use of r5 (substituting r4 which was unemployed in the code where r5 was used) and used r5 for the counter.

    I wasn't sure exacly what you wanted to count, so I counted every time _a was loaded or stored. And I didn't bother to download a simulator to run it, so it likely contains an error or two.

    Code:
    ;; r0   always contains 0
    ;; r14  stack pointer
    ;; r30  frame pointer
    ;; r31  return address
    
    
    .global _exit
    .global _open
    .global _close
    .global _read
    .global _write
    .global _printf
    .global _a
    .global _main
     
            .align 4
    _a:
            .word 46
     
    LC0:
            .ascii "Value of a is %d\12\0"
            .align 4
    
    LC1:
            .ascii "Counter: %d\12\0"
            .align 4
    
    
    _main:
            ;; Initialize Stack Pointer
    ;; r14 = 0
            add r14, r0, r0
    
    ;; r14 = memSize - 4
            lhi   r14,      ((memSize-4)>>16)&0xffff
            addui r14, r14, ((memSize-4)     &0xffff)
    
            ;; Save the old frame pointer
    ;; *(r14 - 4) = r30
            sw -4(r14), r30
    
            ;; Save the return address 
    ;; *(r14 - 8) = r31
            sw -8(r14), r31
    
            ;; Establish new frame pointer 
    ;; r30 = r14
            add r30, r0, r14
    
            ;; Adjust Stack Pointer 
    ;; r14 -= 24
            add r14, r14, #-24
    
            ;; Save Registers 
            sw 0(r14), r3       ;; *(r14)   = r3
            sw 4(r14), r4       ;; *(r14+4) = r4
            sw 8(r14), r5       ;; *(r14+8) = r5
    
    
    ;; r5 = 0   (set counter to 0)
            add r5, r0, r0
    
    ;; _a++
    
      ;; r3 = &_a
            lhi   r3,     (_a>>16)&0xffff
            addui r3, r3, (_a     &0xffff)
    
      ;; r4 = _a
        ;; r4 = &_a
            lhi   r4,     (_a>>16)&0xffff
            addui r4, r4, (_a     &0xffff)
    
        ;; r4 = *r4
            lw  r4,    0(r4)
    
      ;; r5++  (_a was loaded into r4 above)
            add r5, r5, #1
    
      ;; r4++
            add r4,    r4,   #1
    
      ;; *(r3) = r4  (i.e., _a = r4)
            sw  0(r3), r4
    
      ;; r5++  (_a was stored into 0(r3) above)
            add r5, r5, #1
    
    
     ;; printf("Value of a is %d\n", _a)
    
      ;; r14 -= 8
            sub r14, r14, #8
    
      ;; r4 = LC0  (address of printf format string)
            lhi   r4,     (LC0>>16)&0xffff
            addui r4, r4, (LC0     &0xffff)
    
      ;; *(r14) = r4
            sw 0(r14),r4
    
      ;; r4 = _a
        ;; r3 = &_a
            lhi   r3,     (_a>>16)&0xffff
            addui r3, r3, (_a     &0xffff)
    
        ;; r4 = *(r3)
            lw r4,0(r3)
    
      ;; r5++   (yet another load of _a above)
            add r5, r5, #1
    
       ;; *(r14+4) = r4
            sw 4(r14),r4
    
      ;; printf()
            jal _printf
    
      ;; r14 += 8
            add r14, r14, #8
    
    
    ;; printf("Counter: %d\n", r5)
    
      ;; r14 -= 8
            sub r14, r14, #8
    
      ;; r4 = LC1  (address of printf format string)
            lhi   r4,     (LC1>>16)&0xffff
            addui r4, r4, (LC1     &0xffff)
    
      ;; *(r14) = r4
            sw 0(r14),r4
    
      ;; *(r14+4) = r5
            sw 4(r14),r5
    
      ;; printf()
            jal _printf
    
      ;; r14 += 8
            add r14, r14, #8
    
    
    L1:
            ;; Restore the saved registers
            lw r3, -24(r30)
            lw r4, -20(r30)
            lw r5, -16(r30)
    
            ;; Restore return address
            lw r31, -8(r30)
    
            ;; Restore stack pointer
            add r14, r0, r30
    
            ;; Restore frame pointer
            lw r30, -4(r30)
    
            ;; HALT
            jal _exit
    
    
    _exit:
            trap #0
            jr r31
    _open:
            trap #1
            jr r31
    _close:
            trap #2
            jr r31
    _read:
            trap #3
            jr r31
    _write:
            trap #4
            jr r31
    _printf:
            trap #5
            jr r31
    Last edited by oogabooga; 09-15-2013 at 06:35 PM.
    The cost of software maintenance increases with the square of the programmer's creativity. - Robert D. Bliss

  8. #8
    Registered User
    Join Date
    May 2012
    Posts
    210
    Thanks guys so it seems like everyone is really confused about what is supposed to happen.
    Basically this code is given and I have to modify it to be able to calculate the ceiling log. So for example if A=13 then the ceiling log is 4.
    This is basically a warm up exercise to get a grasp of assembly language.
    This is what I did
    Code:
    .global _open        .global _close
            .global _read
            .global _write
            .global _printf
            .global _a
    
    
            .align 4
    _a:
            .word 13
    
    
    LC0:
            .ascii "output is %d\12\0"
            .align 4
            .global _main
    _main:
    ;;; ; Initialize Stack Pointer
            add r14,r0,r0
            lhi r14, ((memSize-4)>>16)&0xffff
            addui r14, r14, ((memSize-4)&0xffff)
    ;;; ; Save the old frame pointer
            sw -4(r14),r30
    ;;; ; Save the return address
            sw -8(r14),r31
    ;;; ; Establish new frame pointer
            add r30,r0,r14
    ;;; ; Adjust Stack Pointer
            add r14,r14,#-24
    ;;; ; Save Registers
            sw 0(r14),r3
            sw 4(r14),r4
            sw 8(r14),r5
            lhi r3,(_a>>16)&0xffff
            addui r3,r3,(_a&0xffff)
            lhi r4,(_a>>16)&0xffff
            addui r4,r4,(_a&0xffff)
            lw r4,0(r4)
            srai r4,r4,#1
            sw 0(r3),r4
            sub r14,r14,#8
            lhi r5,(LC0>>16)&0xffff
            addui r5,r5,(LC0&0xffff)
            sw 0(r14),r5
            lhi r3,(_a>>16)&0xffff
            addui r3,r3,(_a&0xffff)
            lw r5,0(r3)
            sw 4(r14),r5
            jal _printf
            nop
            add r14,r14,#8
    L1:
    ;;; ; Restore the saved registers
            lw r3,-24(r30)
            nop
            lw r4,-20(r30)
            nop
            lw r5,-16(r30)
            nop
    ;;; ; Restore return address
            lw r31,-8(r30)
            nop
    ;;; ; Restore stack pointer
            add r14,r0,r30
    ;;; ; Restore frame pointer
            lw r30,-4(r30)
    ;;; ;  HALT
                            jal _exit
                            nop
    
    
    _exit:
                            trap #0
                            jr r31
                            nop
    _open:
                            trap #1
                            jr r31
                            nop
    _close:
                            trap #2
                            jr r31
                            nop
    _read:
                            trap #3
                            jr r31
                            nop
    _write:
                            trap #4
                            jr r31
                            nop
    _printf:
                            trap #5
                            jr r31
                            nop

    I am getting an answer of 6; whereas it should be 4.

    The only changes I made in the code are
    Code:
     .word 13
    and
    Code:
     srai r4,r4,#1
    instead of add

    so this is what I am thinking of doing
    if I divide 13 by 2 until the answer comes to 0. and then count it it will equal 4.
    In other words
    Code:
    division: 13/2  6/2  3/2  1/2
    counter:  1       2     3     4
    Do you guys get a feel of what I'm saying.
    So if I wanted to do that how should I go about it?


    1

  9. #9
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by kiwi101 View Post
    if I divide 13 by 2 until the answer comes to 0. and then count it it will equal 4.
    You need to add a loop that keeps shifting r4 to the right until it equals zero, while incrementing another register by 1 for each loop. I don't understand why you get the address of "a" in r3, then again in r4, only to then load r4 with the value of "a". After getting the address of "a" in r3, then just do a lw r4,0(r3).

  10. #10
    Registered User
    Join Date
    May 2012
    Posts
    210
    Bear with me please. I am a noob in general and especially when it comes to assembly level
    this is what I have done:
    Code:
    Save Registers                                                                          sw 0(r14),r3
                    sw 4(r14),r4
                    sw 8(r14),r5
                    lhi r3,(_a>>16)&0xffff
                    addui r3,r3,(_a&0xffff)
                    lhi r4,(_a>>16)&0xffff
                    addui r4,r4,(_a&0xffff)
                    lw r4,0(r4)
    
    
                    srai r4,r4,#1
                    BNEZ r4, _L1 ;;;;; if r4 is not equal to 0 then branch to _l1
                    _L1:
                    r6,r0,1 ;;;;; then add 1 to r6
                    sw 0(r3),r4
    See what I did after srai

    so what do I do this like 4 times to get the answer 4? Is there a more concise method of doing this?

  11. #11
    Registered User
    Join Date
    May 2012
    Posts
    210
    So this is what I thought of:
    Code:
    Save Registers                                                                          sw 0(r14),r3
                    sw 4(r14),r4
                    sw 8(r14),r5
                    lhi r3,(_a>>16)&0xffff
                    addui r3,r3,(_a&0xffff)
                    lhi r4,(_a>>16)&0xffff
                    addui r4,r4,(_a&0xffff)
                    lw r4,0(r4)
                    BNEZ r4, _l2 ;;;;; if r4 isnt equal to 0 go to _l2
    _l2:
                    srai r4,r4,#1  ;;;;;divide 13/2 = 6
                    add r6,r0,1 ;;;;;;counter is r6 add value of 1 to it
    Last edited by kiwi101; 09-16-2013 at 10:19 PM.

  12. #12
    Registered User
    Join Date
    May 2012
    Posts
    210
    I get an error saying that BNEZ us unkown opcode and it's not branching to _l2 WHYYY???

  13. #13
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    Quote Originally Posted by kiwi101 View Post
    I get an error saying that BNEZ us unkown opcode and it's not branching to _l2 WHYYY???
    Maybe it only works for lower case, or it's because you didn't specify a register. Here is an example code fragment. I don't have a DLX simulator, so not completely sure about this, but you'll get the idea.

    Code:
    ; ...
            lhi     r3,(_a>>16)&0xffff      ;r3 = address of a
            addui   r3,r3,(_a&0xffff)
            subi    r5,r0,#1                ;r5 = -1
            lw      r4,0(r3)                ;r4 = a
            beqz    r4,_l2                  ;br if r4 is zero
    _l1:
            addi    r5,r5,#1                ;increment r5
            srli    r4,r4,#1                ;shift r4 right 1 bit
            bnez    r4,_l1                  ;loop till r4 is zero
    _l2:                                    ;r5 equal log
    Last edited by rcgldr; 09-17-2013 at 12:08 AM.

  14. #14
    Registered User
    Join Date
    May 2012
    Posts
    210
    Wow that makes so much more sense then what I had written.

    1. _l2 function:
    add r31, r5,r0 ;value in r31 is now r5

    Essentially that is what is being printed

    But then 0 gets printed when I do this

  15. #15
    Registered User
    Join Date
    Apr 2013
    Posts
    1,658
    try this
    Code:
    ; ...
    _l2:                                    ;r5 equal log
            subi    r14,r14,#8
            lhi     r3,(LCO>>16)&0xffff     ;r3 = address of LC0
            addui   r3,r3,(LCO&0xffff)
            sw      r3,0(r14)               ;0(r14) = address of LC0
            sw      r5,4(r14)               ;4(414) = log
            jal     _printf                 ;display log
            addi    r14,r14,#8              ;restore r14
    Last edited by rcgldr; 09-17-2013 at 12:20 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Entry Level Programming Jobs
    By bengreenwood in forum General Discussions
    Replies: 5
    Last Post: 09-21-2009, 12:14 PM
  2. API Programming in network level
    By rchiu5hk in forum C++ Programming
    Replies: 0
    Last Post: 09-07-2009, 10:42 PM
  3. low level programming book
    By CChakra in forum C Programming
    Replies: 5
    Last Post: 09-08-2008, 01:23 PM
  4. Low level programming question
    By phooey in forum C++ Programming
    Replies: 2
    Last Post: 02-16-2003, 08:59 AM
  5. loooow-level socket programming
    By skacy in forum C++ Programming
    Replies: 7
    Last Post: 04-08-2002, 05:22 PM