0
    .equ READERROR, 0 @Used to check for scanf read error. 

     .global main @ Have to use main because of C library uses. 

     main:


     prompt:


@ Ask the user to enter a number.
 
      ldr r0, =strInputPrompt @ Put the address of my string into the first parameter
      bl  printf              @ Call the C printf to display input prompt. 
  
      ldr r0, =numInputPattern @ Setup to read in one number.
      ldr r1, =intInput        @ load r1 with the address of where the
                            @ input value will be stored. 
      bl  scanf                @ scan the keyboard.
      cmp r0, #READERROR       @ Check for a read error.
      beq readerror            @ If there was a read error go handle it. 
      ldr r1, =intInput        @ Have to reload r1 because it gets wiped out. 
      ldr r1, [r1]             @ Read the contents of intInput and store in r1 so that
                            @ it can be printed
      ldr r0, =strOutputNum
      bl  printf

      ldr r0, =strOutputEven

    loop:
      cmp r1, #101 
      beq end 

   
      cmp r1, #0
      bne odd

      cmp r1, #1
      bne even

   

    odd:
    add r1, r1, LSL #1 /* r1 ← r1 + (r1 << 1) */
    bl printf 
    

    even:
    mov r1, r1, ASR #1     /* r1 ← (r1 >> 1) */
    b end_loop

    end_loop:
    add r2, r2, #1         /* r2 ← r2 + 1 */
    b loop                 /* branch to loop */


@ Print the input out as a number.
@ r1 contains the value input to keyboard. 

  
   


     b   myexit @ leave the code. 


     readerror:

@ Got a read error from the scanf routine. Clear out the input buffer then
@ branch back for the user to enter a value. 
@ Since an invalid entry was made we now have to clear out the input buffer by
@ reading with this format %[^\n] which will read the buffer until the user 
@ presses the CR. 

     ldr r0, =strInputPattern
     ldr r1, =strInputError   @ Put address into r1 for read.
     bl scanf                 @ scan the keyboard.

  

Not going to do anything with the input. This just cleans up the input buffer. The input buffer should now be clear so get another input.

    b prompt


    myexit:

End of my code. Force the exit and return control to OS

    mov r7, #0x01 @ SVC call to exit
    svc 0         @ Make the system call. 

    .data

Declare the strings and data needed

    .balign 4
    strInputPrompt: .asciz "Input a number between 1 and 100: \n"

    .balign 4
    strOutputNum: .asciz "You entered: %d \n"

    .balign 4
    strOutputEven: .asciz "The even numbers from 1 to %d are: \n"

Format pattern for scanf call.

    .balign 4
    numInputPattern: .asciz "%d"  @ integer format for read. 

    .balign 4
    strInputPattern: .asciz "%[^\n]" @ Used to clear the input buffer for invalid input. 

    .balign 4
    strInputError: .skip 100*4  @ User to clear the input buffer for invalid input. 

    .balign 4
    intInput: .word 0   @ Location used to store the user input. 

    .global printf

    .global scanf

cannot get even and odd functions to work

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
MaciG
  • 21
  • 6
  • 1
    Do you have a question? If yes, what is your question? – fuz Oct 26 '21 at 12:28
  • I do not know hot to get it to print, "the even numbers from 1 to (what numbered entered) are:" It will not display what number entered and I cant get it to print out all the even numbers and sum them and then print out all odd numbers and sum them – MaciG Oct 26 '21 at 16:59
  • The output of your program should look something like this: Enter an integer between 1 and 100. You entered 10. The even numbers from 1 to 10 are: 2 4 6 8 10 The even sum is: 30 The odd numbers from 1 to 10 are: 1 3 5 7 9 The odd sum is: 25 – MaciG Oct 26 '21 at 17:01
  • 1
    Okay. So you don't know how to do that. Now what is your question? What specific thing do you want to know? – fuz Oct 26 '21 at 17:50
  • I want to know how to make a loop to print out all each even number, then a loop for each odd number and calculate the sum. – MaciG Oct 26 '21 at 18:09
  • How do you expect the value in `r1` to survive the subroutine call `bl printf`? Didn't your professor teach `aapcs`? – Jake 'Alquimista' LEE Oct 27 '21 at 04:56
  • @Jake'Alquimista'LEE Please don't be mean to newbies. – fuz Oct 27 '21 at 11:12
  • @fuz I'm just getting straight to the point. :-) I just gave two very important hints, didn't I? I'm really mad at professors making assembly as hard and uninteresting as one can possibly do. – Jake 'Alquimista' LEE Oct 27 '21 at 11:51

1 Answers1

0

The first problem is here:

  cmp r1, #0
  bne odd

  cmp r1, #1
  bne even

This actually compares the entire number to 0 or 1, when you only want the rightmost bit. You'll need to do something like this. I'll only list the even case, I think you can figure out the odd. I'm a bit rusty at ARM assembly and haven't tested this but something like it should work:

     tst r1,#1  @ sets the flags as you did "AND r1,r1,#1" but doesn't change r1
     bne odd    @ now you will jump to label "odd" if r1 is odd, or keep
                @ going if it's even.

@ if it isn't odd, it must be even, so your even code goes here!

     push r1-r2   @ technically this is a thumb mode only instruction but if your  
                  @ assembler allows unified syntax it should get assembled as the  
                  @ 32-bit instruction "STMFD sp!,{r1-r2}"
                  @ this saves r1 and r2 on the stack, we get them back with POP.
                  @ C functions assume the stack is aligned to 8 bytes so we have to push 
                  @ an even number of registers even though we only needed to push R1.

         ldr r0,=strOutputEven   @ r1 still contains intInput
         bl printf               @ prints "The even numbers from 1 to %d are,"
     pop R1-R2                   @ unified syntax for "LDMFD sp!,{r1-r2}"

@ now we'll do the loop:

     ldr r0,=numInputPattern
     mov r1,#0                   @ we don't need the input anymore
     mov r2,#0                   @ the sum goes here

loop_even:
     add r1,r1,#2               
     cmp r1,#101
     bcc exitLoop               @ if R1 is greater than or equal to 101, exit.

     PUSH R0-R3                @ I can't remember what printf alters so better safe than sorry.
          bl printf
     POP R0-R3

     add r2,r2,r1               @ add R1 to R2 and store the result in R2.
     b loop_even

exitloop:
     mov r1,r2                  @ put the sum into r1 so we can print it
     bl printf                  @ print the string

     b my_exit                  @ we're done!

odd: 

I would recommend reading up on the PUSH and POP instructions and how they work, it's a much more reliable way of temporarily preserving registers than the method you used with ldr r1,[r1]. Don't feel ashamed if you need to print out a reference list of the ARM instructions - I use one all the time.

puppydrum64
  • 1,598
  • 2
  • 15
  • Don't push/pop all registers around a call, [that's really clunky](https://stackoverflow.com/a/56178078/224132). Check a summary of the calling convention: `r4-r11` are call-preserved: https://en.wikipedia.org/wiki/Calling_convention#ARM_(A32). Or at *worst*, push/pop the one or two registers you're using for a loop counter. – Peter Cordes Nov 04 '21 at 00:37
  • Also, coding style: indent instructions one level to the right of labels. And usually leave a blank line after the end of a loop. For example, see my code-review answer [Checking if a number is prime in NASM Win64 Assembly](https://codereview.stackexchange.com/a/204965). Other minor style things: `bcc` is Branch if Carry Clear. There's a synonym for that which has a more meaningful name for this situation, `blo`, Branch if (unsigned) Lower. http://www-mdp.eng.cam.ac.uk/web/library/enginfo/mdp_micro/lecture3/lecture3-3-3.html (it has a typo for BCC, showing it as C=1) – Peter Cordes Nov 04 '21 at 00:44
  • When I'm writing code in a real editor I'm used to being able to use the tab key to indent but that doesn't seem to work on this website, it just moves me over to the "Submit your answer" button. – puppydrum64 Nov 04 '21 at 10:18
  • Right, so use a couple spaces or something. SO has limited horizontal space compared to real code anyway. Or if you want, edit your code in something else and copy/paste it in. – Peter Cordes Nov 04 '21 at 10:20