我可以输入数字并显示我输入的数字.如果我输入10,我需要将1-10之间的所有偶数和所有奇数相加 &g


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

不对输入做任何操作。这只是清理了输入缓冲区。输入缓冲区现在应该是清空的,所以得到另一个输入。

b prompt

myexit:

结束我的代码。强制退出并将控制权返回给OS

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

声明所需的字符串和数据

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

scanf调用的格式模式。

.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

不能使偶函数和奇函数同时工作

第一个问题在这里:

cmp r1, #0
bne odd
cmp r1, #1
bne even

当你只想要最右边的位时,这实际上是将整个数字与0或1进行比较。你需要做这样的事情。我只列出偶数的情况,我想你可以算出奇数的情况。我对ARM汇编有点生疏,还没有测试过这个,但类似的东西应该可以工作:

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: 
我建议仔细阅读PUSHPOP指令以及它们是如何工作的,这是一种比ldr r1,[r1]使用的方法更可靠的临时保存寄存器的方法。如果你需要打印出ARM指令的参考列表,不要感到羞耻——我一直在使用一个。

相关内容