ARM汇编:如何更改代码,要求输入数字然后打印出来,然后要求输入字符并打印出来?


@ Use these commands to assemble, link, run and debug this program:

@    as -o student_inputC.o student_inputC.s

@    gcc -o student_inputC student_inputC.o

@    ./student_inputC 

@    gdb --args ./student_inputC 


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

@ Ask the user to enter a character.

ldr r0, =charInputPrompt

bl printf



get_input:



@ Set up r0 with the address of input pattern.

@ scanf puts the input value at the address stored in r1. We are going
@ to use the address for our declared variable in the data section - intInput. 
@ After the call to scanf the input is at the address pointed to by r1 which 
@ in this case will be intInput. 


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



ldr r0, =charInputPattern @ Setup to read in one number.

ldr r1, =charInput        @ load r1 with the address of where the



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, =charInput        @ Have to reload r1 because it gets wiped out.

ldr r1, [r1]             @ Read the contents of intInput and store in r1 so that it 



@ Print the input out as a number.

@ r1 contains the value input to keyboard. 

ldr r0, =strOutputNum

bl  printf

b   myexit

ldr r0, =strOutputChar

bl  printf

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 the number: n"

.balign 4

strOutputNum: .asciz "The number value is: %d n"

.balign 4

charInputPrompt: .asciz "Input the character: n"

.balign 4

strOutputChar: .asciz "The character is: %c 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.

.balign 4

charInputPattern: .asciz "%c"  @ integer format for read. 

.balign 4

charInput: .word 0   @ Location used to store the user input 

@ Let the assembler know these are the C library functions. 

.global printf

@  To use printf:
@     r0 - Contains the starting address of the string to be printed. The string
@          must conform to the C coding standards.
@     r1 - If the string contains an output parameter i.e., %d, %c, etc. register
@          r1 must contain the value to be printed. 
@ When the call returns registers: r0, r1, r2, r3 and r12 are changed. 

.global scanf

@  To use scanf:
@      r0 - Contains the address of the input format string used to read the user
@           input value. In this example it is numInputPattern.  
@      r1 - Must contain the address where the input value is going to be stored.
@           In this example memory location intInput declared in the .data section
@           is being used.  
@ When the call returns registers: r0, r1, r2, r3 and r12 are changed.
@ Important Notes about scanf:
@   If the user entered an input that does NOT conform to the input pattern, 
@   then register r0 will contain a 0. If it is a valid format
@   then r0 will contain a 1. The input buffer will NOT be cleared of the invalid
@   input so that needs to be cleared out before attempting anything else.
@
@ Additional notes about scanf and the input patterns:
@    1. If the pattern is %s or %c it is not possible for the user input to generate
@       and error code. Anything that can be typed by the user on the keyboard
@       will be accepted by these two input patterns. 
@    2. If the pattern is %d and the user input 12.123 scanf will accept the 12 as
@       valid input and leave the .123 in the input buffer. 
@    3. If the pattern is "%c" any white space characters are left in the input
@       buffer. In most cases user entered carrage return remains in the input buffer
@       and if you do another scanf with "%c" the carrage return will be returned. 
@       To ignore these "white" characters use " $c" as the input pattern. This will
@       ignore any of these non-printing characters the user may have entered.
@
@ End of code and end of file. Leave a blank line after this.

发生这种情况的原因非常简单。让我们仔细看一下代码:

LDR r0,=StringInputPrompt
BL printf
LDR r0,=charInputPrompt
BL printf

现在忽略分支预测符和乱序执行,汇编按照编写的顺序执行,从上到下。你正在加载一个字符串上面写着输入数字输入R0,然后打印出来,然后输入字符串"然后打印出来。您已经打印了请求输入的字符串,但在打印完两个提示符之前没有接受任何实际输入。

接下来,我们将查看getInput部分:

get_input:
ldr r0, =numInputPattern  @ Setup to read in one number.
ldr r1, =intInput         @ load r1 with the address of where the
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]              @                

ldr r0, =charInputPattern @ Setup to read in one number.
ldr r1, =charInput        @ The problem is here! (added by me)                 
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, =charInput        @ Have to reload r1 because it gets wiped out.
ldr r1, [r1]              

再一次,您正确地接受了输入,但是随后您用=charInput覆盖了r1。了解汇编的重要一点是寄存器和永久内存之间的区别。看看这个:

LDR R0,=intInput
LDR R0,=charInput

有这两个背靠背的就等于没有第一个,即

LDR R0,=charInput

因为每个寄存器一次只能包含一个值,当你加载一个新值时,旧的就会被丢弃。

你的代码的其余部分似乎是工作的,所以一个简单的重新安排你的代码应该修复它:

main:
@ Ask the user to enter a number.
ldr r0, =strInputPrompt 
@ Put the address of my string into the first parameter
bl  printf              
@ Set up r0 with the address of input pattern.
ldr r0, =numInputPattern @ Setup to read in one number.
ldr r1, =intInput        @ load r1 with the address of where the
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]             
@ Print the input out as a number.
ldr r0, =strOutputNum
bl  printf

@ Ask the user to enter a character.

ldr r0, =charInputPrompt
bl printf
ldr r0, =charInputPattern @ Setup to read in one number.
ldr r1, =charInput        @ load r1 with the address of where the
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, =charInput        @ Have to reload r1 because it gets wiped out.
ldr r1, [r1]            

ldr r0, =strOutputChar
bl  printf

b   myexit @ leave the code. 

TL;博士:汇编中指令的顺序很重要。很多。

相关内容

  • 没有找到相关文章

最新更新