Results 1 to 15 of 15

Thread: Help with Assembly assignment

  1. #1
    Join Date
    Dec 2011
    Location
    -bash
    Posts
    515
    Mentioned
    0 Post(s)
    Quoted
    27 Post(s)

    Default Help with Assembly assignment

    I have to implement the following in MIPS assembly language:

    #Write,and test using spim, and assembly language program
    that inputs a positive integer 'N' from the user, followed by 'N' integers.
    Your program should output how many of the 'N' integers have
    a value greater than or equal to 80 but less than 100.
    Here is what I have so far:

    Assembly Code:
    #Author: Banana Colada

    #MIPS Code


    .data           #Let processor know we will be submitting data to our program

    Ask_Input:

    .asciiz "\Please enter the size of the array\n"            
    #This will get a number from the user and store int unsed memory with Ask_Input

    Tell_Input:

    .asciiz "\Numbers greater than or equal to 80 but less than 100: "            
    #This will print all numbers in our array that is greater than 80

    NumArray:

    .space Ask_Input//This doesn't look right


    .text           #enables text input / output. Start of code

    main:           #main function. Program starts here


    la $a0, Ask_Input          
    #load address Ask_Input from memory and store it into arguement register 0

    li $v0, 4           #Load the value 4 into register $v0
    syscall             #reads register $v0 for op code, sees 4 and prints the string located in $a0

    li $s0, NumArray            #Load the address of start of array into address $s0

    loop:

    My problem is, how do I use the input from the user to declare the size of the array?

    E: If possible, I would also like to output the values to the user so where do I store the values that are in the range I am looking for and How?

  2. #2
    Join Date
    May 2012
    Location
    Moscow, Russia
    Posts
    661
    Mentioned
    35 Post(s)
    Quoted
    102 Post(s)

    Default

    I think you should use test assembly command(test eax, 100b) or test equalent in Mips.
    Per aspera ad Astra!
    ----------------------------------------
    Slow and steady wins the race.

  3. #3
    Join Date
    Dec 2011
    Location
    -bash
    Posts
    515
    Mentioned
    0 Post(s)
    Quoted
    27 Post(s)

    Default

    Is that a command or program? And how do I use it?

  4. #4
    Join Date
    May 2012
    Location
    Moscow, Russia
    Posts
    661
    Mentioned
    35 Post(s)
    Quoted
    102 Post(s)

    Default

    Ok, small assembly example: validate the input numbers.

    Code:
    ;C naming  conv: console - get unsigned long
    _cgetul:    xor edx, edx
            mov cx, 10      ; ???-?? ??????
    next:       xor ax, ax          ;
            int 16h             ;
            cmp ah, 1       ; <ESC>?
            jz  cancel
            cmp ah, 1Ch         ; <Enter>?
            jz  done
            cmp al, 30h
            jb  next
            cmp al, 39h
            ja  next
            movzx   eax,al          ; ??????? ?? eax ??????
                lea edx,[edx*4+edx]     ; EDX = EDX * 5
                lea edx,[edx*2+eax-48]  ; EDX = EDX * 2 + ?????? ?? AL - '0'
                int 29h             ; ??????? ?? ?????
                loop    next
    done:       mov eax, edx        ;
            ret
    cancel:     xor eax, eax
            dec eax             ; EAX = -1
            stc                     ;
            ret
    Per aspera ad Astra!
    ----------------------------------------
    Slow and steady wins the race.

  5. #5
    Join Date
    Dec 2011
    Location
    -bash
    Posts
    515
    Mentioned
    0 Post(s)
    Quoted
    27 Post(s)

    Default

    Quote Originally Posted by CynicRus View Post
    Ok, small assembly example: validate the input numbers.
    I mean no offence CynicRus, but that code did not make much sense to me, partly because it has only been 3 weeks since I first set eye on assembly code and I don't even know where to start reading yours from. Here is what I have so far. I decided not to go with the array approach after all. However this one is not working. Infact I am getting no output at all. Help please!:

    Assembly Code:
    #Write,and test using spim, and assembly language program that inputs a positive integer 'N' from the user, followed by 'N' integers. Your program should output how many of the 'N' integers have a value greater than or equal to 80 but less than 100.

    #Author: Banana Colada

    #MIPS Code


    .data
    #Let processor know we will be submitting data to our program

    Ask_Input:

    .asciiz "\tPlease enter number of values\n\t"
    #This will get a number from the user and store int unsed memory with Ask_Input

    Tell_Input:

    .asciiz "\n\tNumbers greater than or equal to 80 but less than 100: "
    #This will get a number from the user and store int unsed memory with Tell_Input

    Ask_Num:

    .asciiz "\tEnter a number:\n\t"
    #Prompts user for a number


    .text           #enables text input / output. Start of code
    main:           #Program starts here

    li      $v0, 4
    la      $a0, Ask_Input#load address Ask_Input from memory and store it into arguement register $a0
    li      $v1, 5  #Get size of array
    syscall     #Get size of the array

    li      $s3, 0  #Will keep track of how many numbers x satisfy (80 <= x < 100)
    loop1:  #loop start
    li      $v0, 4  
    la      $a0, Ask_Num         #Loads address Ask_Num from memory and store it into arguement register 1

    li      $v0, 5
    syscall     #Get number from user
    addi    $v1, $v1, -1 #decrease counter
    bnez    $v1, GetSom #if size is not zero
    blez    $v1, end
    syscall



    end:
    move    $t1, $s3
    li      $v0, 4
    la      $a0, Tell_Input
    lw      $t0, ($t1)
    syscall



    loop2:
    addi    $s3, $s3, 1
    bnez    $v1, loop1
    beq     $v1, $zero, end
    syscall




    GetSom:
    bge     $v0, 100, loop1
    bge     $v0, 80, loop2
    syscall





    li $v0, 10
    syscall

  6. #6
    Join Date
    May 2012
    Location
    Moscow, Russia
    Posts
    661
    Mentioned
    35 Post(s)
    Quoted
    102 Post(s)

    Default

    Unfortunately I'm here I can not help you, because the only familiar with the assembler from Intel(x86).Srry
    Per aspera ad Astra!
    ----------------------------------------
    Slow and steady wins the race.

  7. #7
    Join Date
    Dec 2011
    Location
    -bash
    Posts
    515
    Mentioned
    0 Post(s)
    Quoted
    27 Post(s)

    Default

    Quote Originally Posted by CynicRus View Post
    Unfortunately I'm here I can not help you, because the only familiar with the assembler from Intel(x86).Srry
    Np, thanks anyway for trying. Thing I hate about assembler is how every processor is different and depending on the architecture, one can't apply their knowledge across all assembler lang

  8. #8
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Can Assemble this using FASM.. It's not exactly what you want, but it should get you started. It shouldn't be too hard to translate between different Assemblers. I'm not used to MIPS, but I've used it once or twice.. Not enough to be able to translate this but I'm hoping the comments in the code below might give you clues or help in some way..


    ASM Code:
    format PE console                                               ;Format PE OUT GUI 4.0
    entry main

    include 'macro/import32.inc'

    section '.idata' import data readable                           ;Import Section.
    library msvcrt,'msvcrt.dll'
    import msvcrt, printf, 'printf',\
    exit,'exit', getchar, 'getchar', scanf, 'scanf'

    section '.data' data readable writeable                         ;Constants/Static Section.  This section can store variables.
    Size dd 0                                                       ;Array Size. A Dword Initialized to 0
    PromptValue db "Enter A Number: ", 13, 10, 0                    ;Prompt User For A Number.
    FuncPrint db 13, 10, 13, 10, "Calling Function: %s", 13, 10, 0  ;Statement For Function.
    Response db 13, 10, 13, 10, "You Entered: %d", 13, 10, 0        ;Statement For Number.
    InputFormat db "%d", 0                                          ;Format Data
    IntArray dd 0                                                   ;Declare Dword Initialized to 0
    Index dd 0


    section '.code' code readable executable
    main:
       push ebp
       mov ebp,esp

       push PromptValue                   ;Ask the user to Enter a number.
       call [printf]
       add esp, 4

       push Size
       push InputFormat
       call [scanf]                       ;Call scanf with the "%d" and the variable to hold the integer.
       add esp, 8

       push [Size]
       push Response
       call [printf]                      ;Print the value the user entered with "%d".
       add esp, 8

       mov ecx, [Size]                    ;Store the Array Size/Number in the count register.
       mov [Index], 0                     ;Set the Index variable to 0.

       ASSIGN:                            ;The beginning of a loop.
          push ecx                        ;Backup our count because printf discards it.
          mov ecx, [Index]                ;Move our index to the new count register.
          inc [Index]                     ;Increment the index.
          mov [IntArray + 4 * ecx], ecx   ;Change the value at the array's index to the current count.
          pop ecx                         ;Restore our old count.
       loop ASSIGN                        ;Loop if Count is > 0.. else break.


                                          ;TODO: Add Loop to print array..


       mov [Index], 65                    ;Store the character A in variable called Index.
       push Index                         ;Pass Index to the function as a parameter by pushing it onto the stack.
       call Function                      ;Call the function.
       add esp, 4                         ;Restore the stack pointer..


       mov esp, ebp
       pop ebx

       call [getchar]                     ;Wait until the user presses a key before we exit.
       call [getchar]

       mov eax, 0                         ;Return 0.
    ret


    Function:
       push ebp
       mov ebp, esp
       mov eax, [ebp + 8]                 ;Function Parameter

       push eax
       push FuncPrint
       call [printf]                      ;Print the Parameter Passed..
       add esp, 8

       mov esp, ebp
       pop ebp
    ret
    Last edited by Brandon; 01-25-2013 at 06:54 AM.
    I am Ggzz..
    Hackintosher

  9. #9
    Join Date
    Dec 2011
    Location
    -bash
    Posts
    515
    Mentioned
    0 Post(s)
    Quoted
    27 Post(s)

    Default

    Yo Brandon, can you please look at my code and tell me why it is not working. All it does it print out the prompt and then it stops. I didn't know you knew some assembly otherwise I would be pm'ing you this question

  10. #10
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by [Re]cUrSivE View Post
    Yo Brandon, can you please look at my code and tell me why it is not working. All it does it print out the prompt and then it stops. I didn't know you knew some assembly otherwise I would be pm'ing you this question
    I know a lot of languages; I learn very fast. Just C++ is my favourite. x86 ASM is my second favourite. Though.. It's very tedious.

    Uhh.. I tried.. I of course had to download that hideous MIPS simulator? Thing.. came in a jar file.. and I used this site to help:

    http://logos.cs.uic.edu/366/notes/mi...20tutorial.htm


    It gets the input but I can't seem to figure out why it won't print it back.. I'll try again, run it and see if it works though.

    EDIT.. Solved the stupid printing.. I accidentally put an extra System Call after the move $t0, $a0.. Removed it below.. I'll comment the line so you can see..

    I have to say.. I HATED writing this.. It sucks.. I've never seen a Java/.jar assembler in my life.. Had the hardest time figuring out how to use it -__-
    You might have a hard time convincing me to write "MIPS ASM" in future posts :l Interesting though, so I might.


    To get strings from the user (I'm really really really tired.. So, I'll comment it in the morning.. If I don't, just tag me or msg me or something.. Iunno.. Good night):
    Code:
    .data       				#Data Section.
    
    Input:		.space 1024
    Prompt:	        .asciiz "Enter A String:\n"
    Notice:		.asciiz "You Entered: "
    Space:		.asciiz " "
    NewLine:	.asciiz "\n"
    
    
    
    
    .text
    
    main:
    li $v0, 4		#4 means to print string.
    la $a0, Prompt		#Pass the value to print on screen. Similar to pushing stuff into eax.
    syscall			#Perform the system call for printing string.
    
    li $v0, 8		#8 means to read string.
    la $a0, Input		#Point To The Variable Which will hold our User Input.
    la $a1, 1024		#That Variable is a size of 1024. That way, we don't overflow.
    syscall			#Get the user input via the system call to read string.
    
    la $a0 Input            #Point to our string.
    move $t0, $a0		#Save/Copy Input-String into $t0.
    #syscall                #Commented out for reasons explained in my post.. 
    
    la $a0, Notice		#Point to our Notice string which tells the user what they entered.
    li $v0, 4		#4 means to print string.
    syscall			#Carry out the print via system call.
    
    la $a0, Input		#Point to our Input-String.
    move $a0, $t0		#Move/Copy the saved Input string to the loaded address/register.
    li $v0, 4		#4 means to print. Here we are going to print the user input after telling them our Notice.
    syscall			#Invoke the print via System call.
    
    li $v0, 10		#Exit the program.
    syscall			#Invoke exiting via System call.


    Your assignment (Getting integers from the user):

    Code:
    .data       				#Data Section.
    
    Input:		.word 0
    Prompt:	        .asciiz "\nEnter An Array Length:\n"
    Prompt_Two:	.asciiz "\nEnter Another Number:\n"
    Notice:		.asciiz " Is >= 80 AND < 100"
    Space:		.asciiz " "
    NewLine:	.asciiz "\n"
    
    
    
    
    .text
    
    main:
    li $v0, 4		#4 means to print string.
    la $a0, Prompt		#Pass the value to print on screen.
    syscall			#Perform the system call for printing string.
    
    li $v0, 5		#5 means to read input. This reads the length from the user.
    syscall			#Get the user input via the system call to read string.
    move $s3, $v0   #Store the length of the array.. Similar to ECX register in x86.
    
    
    GetNumbers:     #Beginning of the loop.
    
    subi $s3, $s3, 1        #Decrease the count.. This determines whether we break out of the loop or not.
    beqz $s3, EndNumbers    #if our count = 0, break out of the loop.
    
    li $v0, 4               #Ask the user to enter another number.
    la $a0, Prompt_Two
    syscall
    
    li $v0, 5               #wait for user input.
    syscall
    move $a0, $v0           #store their number in the $a0 register. Similar to eax
    
    blt $v0, 80, GetNumbers    #if the number is less than 80, don't bother printing it.
    bge $v0, 100, GetNumbers   #or.. if it is greater than 100, don't print it either..
    
    li $v0, 1               #print integer.. this will print the number..
    syscall
    li $v0, 4               #print string.. this will print the Notice.. thus, it prints:  SOmeNumber: Is >= 80 && < 100.
    la $a0, Notice
    syscall
    
    b GetNumbers             #continue the loop.. The loop only breaks when count reaches 0.
    
    EndNumbers:
    
    
    
    li $v0, 10		#Exit the program.
    syscall			#Invoke exiting via System call.


    EDIT:

    I added comments to the code so you can see how the code works.. Surprised I learned mips so quickly. :l
    Last edited by Brandon; 01-25-2013 at 04:26 PM.
    I am Ggzz..
    Hackintosher

  11. #11
    Join Date
    Dec 2011
    Location
    -bash
    Posts
    515
    Mentioned
    0 Post(s)
    Quoted
    27 Post(s)

    Default

    @Brandon

    Thanks Brandon. Would your solution work if I was trying also to do some arithmetic with the value I got? Assuming the user only enters numbers, how would I take that number and add it to something then print the sum?

  12. #12
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Yeah just add the register the number is in with whatever else you want to add it with.

    I added the comments to the code above so you can see what is stored where and what it does.


    If you want to add numbers the user enters, according to the code above, the number the user entered is stored in $a0 and $v0. Let me know if you can follow the comments I added. Hopefully I wrote them properly.


    What you can do is:

    Code:
    addi $a0, $a0, 500    #adds 500 + $a0 to a0.
    addi $a0, $v0, 500    #adds 500 + $v0 to $a0.
    
    mov $v0, 0             #Set $v0 register to hold a value of 0.
    addi $a0, $v0, 500   #add 500 to $a0 because $v0 is = to 0.
    
    #etc.. etc..
    Last edited by Brandon; 01-25-2013 at 04:43 PM.
    I am Ggzz..
    Hackintosher

  13. #13
    Join Date
    Dec 2011
    Location
    -bash
    Posts
    515
    Mentioned
    0 Post(s)
    Quoted
    27 Post(s)

    Default subi -> addi

    Thanks Brandon. I noticed you did this:

    Code:
    subi $s3, $s3, 1        #Decrease the count.. This determines whether we break out of the loop or
    I learned today that there really is no subtract in MIPS. So what it actually does is to add the negative of the number to value in the register and store in the register specified.

    So it does this instead:

    Code:
    addi $s3, $s3, -1        #Decrease the count.. This determines whether we break out of the loop or

    What does mean?
    Code:
    b GetNumbers             #continue the loop.. The loop only breaks when count reaches 0.
    what does the b do?


    EDIT: Works now!

    Code:
    #Write,and test using spim, and assembly language 
    #program that inputs a positive integer 'N' from 
    #the user, followed by 'N' integers. Your program 
    #should output how many of the 'N' integers have a 
    #value greater than or equal to 80 but less than 100.
    
    #Author: Banana Colada
    
    #MIPS Code
    
    
    .data
    #Let processor know we will be submitting data to our program
    
    Ask_Input:              .asciiz "\tPlease enter number of values\n\t"
    #This will get a number from the user and store int unsed memory with Ask_Input
    
    Tell_Input:             .asciiz "\tNumbers greater than or equal to 80 but less than 100:\n\t "
    #This will get a number from the user and store int unsed memory with Tell_Input
    
    Ask_Num:                .asciiz "\tEnter a number:\n\t"
    #Prompts user for a number
    
    
    
    
    
    
    
    .text                       #enables text input / output. Start of code
    
    main:                       #Program starts here
    
    li $v0, 4                   #4 means to print string
    la $a0, Ask_Input           #load address Ask_Input from memory and store it into arguement register $a0
    syscall                     #Perform system call for printing string
    
    
    li $v0, 5                   #5 means to read in a number
    syscall                     #Get user input using syscall
    move $s3, $v0               #Store length of array in register $s3
    
    li $s0, 0		    #Load the number 0 into address s0, this will be our counter
    GetNum:                     #Get numbers loop
    
    blez $s3, Exit		    #First we check that the length of the array is greater than zero
    li $v0, 4                   #4 means to print a string
    la $a0, Ask_Num         
    syscall                     #Ask for another number
    
    li $v0, 5
    syscall                     #Get a number from the user
    move $s1, $v0               #Store the number in register $s1
    
    addi $s3, $s3, -1           #Decrease count of numbers
    bgez $s3, CheckNum    	    #Check our numbers
    syscall
    
    
    
    CheckNum:
    blt $v0, 80, GetNum         #If the number is less than 80, loop again
    bge $v0, 100, GetNum        #If number is greater than or equal to 100, go back to loop
    
    addi $s0, $s0, 1	    #Add a one to the sum of numbers that meet requirement
    b GetNum                    #branch to the start of the loop
    
    
    
    Exit:
    
    li $v0, 4                   #4 means to read in a string
    la $a0, Tell_Input
    syscall			    #Print our string
    
    move $a0, $s0		    #move the value in $s0 to $a0
    li $v0, 1                   #1 means to print a number
    syscall                     #print the number
    
    li $v0, 10		    #Exit code
    syscall
    Why is it only while using $a0 that it prints the correct output?

  14. #14
    Join Date
    Feb 2011
    Location
    The Future.
    Posts
    5,600
    Mentioned
    396 Post(s)
    Quoted
    1598 Post(s)

    Default

    Quote Originally Posted by [Re]cUrSivE View Post
    Thanks Brandon. I noticed you did this:

    Code:
    subi $s3, $s3, 1        #Decrease the count.. This determines whether we break out of the loop or
    I learned today that there really is no subtract in MIPS. So what it actually does is to add the negative of the number to value in the register and store in the register specified.

    So it does this instead:

    Code:
    addi $s3, $s3, -1        #Decrease the count.. This determines whether we break out of the loop or

    What does mean?
    Code:
    b GetNumbers             #continue the loop.. The loop only breaks when count reaches 0.
    what does the b do?

    be means branch if equal.. it's like je which means jump if equal in x86. AKA if (condition) goto Label in C/C++.
    bnez means branch if not equal to zero.
    b means to branch unconditionally. Aka jmp in x86 or goto Label in C/C++


    Thus:

    b GetNumbers will jump directly to the GetNumbers Label.. This just so happens to be the beginning of the loop.
    be $a0, 50, GetNumbers will jump to GetNumbers if $a0 register contains the value 50.

    etc..


    it's like this:

    C++ Code:
    for (int I = 10; I > 0; --I)  //This is 4 instructions.. (move $s3, 10)..  (beqz $s3, EndLabel), (Addi $s3, $s3, -1), (b LoopAgain)
    {
            //Do something.
    }

    Which is equivalent to:

    ASM Code:
    move $s3, 10                         ;Set I as 10.. Every loop, we can decrease I by 1.

    For:                                 ;The beginning of the for-loop.
            beqz  $s3, Break             ;If I == 0, break out of the loop. Jump to the break label.
            ;Do Something..
            addi $s3, $s3, -1            ;Decrease I by 1 every time we loop. Remember? The for-loop decrements at the end of the loop. AKA Last Instruction.
    b For                                ;Loop again by jumping to the For label.
     

    Break:


    To be fair to any mathematician/physicist/programmer, addition and subtraction are the exact same really..

    -5 + 3

    is the same as

    3 - 5

    So saying there is no subtraction(just add negative value) can easily be worded the other way by saying there is no addition(just subtract negative value)..

    Bedmas says other-wise though but in assembly it doesn't matter.
    Last edited by Brandon; 01-25-2013 at 09:15 PM.
    I am Ggzz..
    Hackintosher

  15. #15
    Join Date
    Dec 2011
    Location
    -bash
    Posts
    515
    Mentioned
    0 Post(s)
    Quoted
    27 Post(s)

    Default

    Quote Originally Posted by Brandon View Post

    To be fair to any mathematician/physicist/programmer, addition and subtraction are the exact same really..

    -5 + 3

    is the same as

    3 - 5

    So saying there is no subtraction(just add negative value) can easily be worded the other way by saying there is no addition(just subtract negative value)..

    Bedmas says other-wise though but in assembly it doesn't matter.
    I wasn't saying that there is no subtraction. I am saying that in the way it is implemented in MIPS, subtraction calls add and adds the negative of the number. Hence there is no code (so to speak) for sub because it just calls another function (add)

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •