Assembly 手臂部件堆栈值不移动

Assembly 手臂部件堆栈值不移动,assembly,arm,stack,Assembly,Arm,Stack,我正在尝试在ARM汇编中构建一个基本的4函数计算器。我们必须使用Push和Pop,4个函数中的每一个都必须是自己的子例程 由于某种原因,我无法获取子程序的值。教授说我们不需要使用堆栈帧或帧指针,我想这很好,但我不知道为什么这不起作用。我是否在正确的位置使用了PUSH命令?我只需要推动LR吗?如果需要,我应该如何以及在哪里放置它 如果格式混乱,也很抱歉。我不知道如何在堆栈溢出中执行任何操作 .equ READERROR, 0 @Used to check for scanf read error.

我正在尝试在ARM汇编中构建一个基本的4函数计算器。我们必须使用Push和Pop,4个函数中的每一个都必须是自己的子例程

由于某种原因,我无法获取子程序的值。教授说我们不需要使用堆栈帧或帧指针,我想这很好,但我不知道为什么这不起作用。我是否在正确的位置使用了PUSH命令?我只需要推动LR吗?如果需要,我应该如何以及在哪里放置它

如果格式混乱,也很抱歉。我不知道如何在堆栈溢出中执行任何操作

.equ READERROR, 0 @Used to check for scanf read error.
.global main @ Have to use main because of C library uses. 

main:

@*******************
begin:
@*******************

@ Welcome message.

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, =inputPrompt1    @ 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 theinput 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 r3, =intInput       @ load intInput into r3
ldr r3, [r3]            @ Read the contents of intInput and store in r3
mov r2, #-1         @ load -1 into r2
cmp r3, r2          @ is the value entered less than or equal to -1?
ble invalidnums     @ if yes, print invalid message
ldr r0, =inputPrompt2    @ 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, =intInput2       @ load r1 with the address of where theinput value will be stored.

bl scanf            @ scan the keyboard
cmp r0, #READERROR       @ Check for a read error.
ldr r4, =intInput        @ load intInput into r4 
ldr r4, [r4]             @ Read the contents of intInput and store in r4
mov r3, #-1         @ load -1 into r2
cmp r4, r3          @ is the value entered less than or equal to -1?
ble invalidnums     @ if yes, print invalid message

@blt again         @ if invalid return value, ask for another attempt
@mov r1, r0
@ldr r0, =answer
@bl printf         @ print the answer
@b again           @ ask another attempt

@*******************
get_op:
@*******************

ldr r0, =inputPrompt3    @ Put the address of my string into the first parameter
bl  printf               @ Call the C printf to display input prompt.

ldr r0, =charInputPattern @ Setup to read in one number.
ldr r1, =charInput        @ load r1 with the address of where theinput value will be stored.

bl scanf            @ scan the keyboard
cmp r0, #READERROR       @ Check for a read error.
ldr r5, =charInput       @ load charInput into r5 
ldr r5, [r5]             @ Read the contents of charInput and store in r5

push {r3,r4}

cmp r5, #'+'        @ did user enter +?
beq addTest             @ if yes, go to addTest

cmp r5, #'-'        @ did user enter -?
beq subTest             @ if yes, go to subTest

cmp r5, #'*'            @ did user enter *?
beq multTest        @ if yes, go to multTest

cmp r5, #'/'            @ did user enter /?
beq divTest             @ if yes, go to divTest

b begin             @ back to beginning of program

@*******************
addTest:
@*******************
ldr r0, =addOpt        @ Put the address of my string into the first parameter
bl  printf              @ Call the C printf to display input prompt. 

bl addCalc
pop {r0}
mov r1, r0
ldr r0, =answer
bl printf

@*******************
subTest:
@*******************
ldr r0, =subOpt        @ Put the address of my string into the first parameter
bl  printf              @ Call the C printf to display input prompt. 

bl subCalc
pop {r0}
mov r1, r0
ldr r0, =answer
bl printf
@*******************
multTest:
@*******************
ldr r0, =multOpt       @ Put the address of my string into the first parameter
bl  printf              @ Call the C printf to display input prompt. 

bl multCalc
pop {r0}

@*******************
divTest:
@*******************
ldr r0, =divOpt        @ Put the address of my string into the first parameter
bl  printf              @ Call the C printf to display input prompt. 

bl divCalc
pop {r0}

@***********
addCalc:
@***********

pop {r5,r6}
add r6, r5, r6

@cmp r6, #0            @ test if upper word is non-zero (for overflow)
@vs overflow
@movgt r7, #-1     @ if overflow, load -1 as a result
@asrle r7, #1      @ if not, divide by 2
@blgt overflow     @ if overflow, print overflow
@mov r0, r7

push {r6}
bx lr          @ return

@***********
subCalc:
@***********

pop {r5,r6}
subs r6, r5, r6        @ subtract r5-r6 and store in r6
@cmp r6, #0            @ test if upper word is non-zero (for overflow)
@vs overflow
@movgt r7, #-1     @ if overflow, load -1 as a result
@asrle r7, #1      @ if not, divide by 2
@blgt overflow     @ if overflow, print overflow
@mov r0, r7

push {r6}          @ return
bx lr

@***********
multCalc:
@***********

mov r6, #0
umull r7, r6, r4, r5    @ 64-bit multiplication
@cmp r6, #0            @ test if upper word is non-zero (for overflow)
@vs overflow
@movgt r7, #-1     @ if overflow, load -1 as a result
@asrle r7, #1      @ if not, divide by 2
@blgt overflow     @ if overflow, print overflow
mov r0, r7

push {r6}          
bx lr          @ return

@***********
divCalc:
@***********


mov r6, #0
bl divLoop
@cmp r6, #0            @ test if upper word is non-zero (for overflow)
@vs overflow
@movgt r7, #-1     @ if overflow, load -1 as a result
@asrle r7, #1      @ if not, divide by 2
@blgt overflow     @ if overflow, print overflow
@mov r0, r7

push {r6}          
bx lr          @ return

@***********
divLoop:
@***********

subs r4, r4, r5        @ r4-r5 and store in r4. this will be remainder
adds r7, r7, #1        @ increment by 1. this is how many times r4 has been divided
cmp r4, r5         @ if r4 < r5 return to divCalc
bx lr

@***********
overflow:
@***********
push {lr}   
push {fp}   
mov fp, sp         @ create stack frame
ldr r0, =overstr       @ load overflow string
bl printf          @ print overflow string
pop {fp}           @ restore stack frame
pop {pc}           @ return

@***********
returnInput:
@***********
@ reset stack
add sp, #4         @ restore stack
pop {fp}           @ restore frame
pop {pc}           @ return

@***********
again:
@***********
ldr r0, =againstr
bl printf          @ print againstr
sub sp, #1         @ allocate space for one char
mov r1, sp
ldr r0, =charInputPattern
bl scanf           @ scan the keyboard
mov r0, #0
ldrsb r0, [sp], #4     @ load char and restore stack
cmp r0, #'y'       @ compare to 'y'
beq begin          @ if y, go back to the beginning
cmp r0, #'n'       @ compare to 'n'
beq myexit         @ if n, exit the program
b again            @ else, try again

@***********
invalidnums:
@***********
ldr r1, [fp, #8]
mov r0, #-1
str r0, [r1] @set the inputted value to -1
sub sp, #100       @ allocate space for a 100-character string
ldr r0, =charInputPattern
mov r1, sp
bl scanf           @ scan the keyboard
add sp, #100       @ restore stack

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

@***********
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 again



.data

@ Declare the strings and data needed

.balign 4
strInputPrompt: .asciz "Hello. Enter 2 non-negative integers and an operation (+, -, *, or /) and I 
will calculate the answer. \n"

.balign 4
inputPrompt1: .asciz "Enter first non-negative integer: \n "

.balign 4
inputPrompt2: .asciz "Enter second non-negative integer: \n "

.balign 4
inputPrompt3: .asciz "Enter the operation (+, -, *, or /): \n "

.balign 4
addOpt: .asciz "Addition \n "

.balign 4
subOpt: .asciz "Subtraction \n "

.balign 4
multOpt: .asciz "Multiplication \n "

.balign 4
divOpt: .asciz "Division \n "

.balign 4
answer: .asciz "The answer is: \n"

.balign 4
overstr: .asciz "Overflow \n"

.balign 4
againstr: .asciz "Try another calculation? \n"

.balign 4
nl: .asciz "\n"

.balign 4
invalidStr: .asciz "Invalid input, try again \n"

@ Format pattern for scanf call.

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

.balign 4
charInputPattern: .asciz "%s"  @ character format for read.

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

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

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

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


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

.global printf

.global scanf

@end of code and end of file. Leave a blank line after this.
`
.eq READERROR,0@用于检查扫描读取错误。
.global main@必须使用main,因为使用了C库。
主要内容:
@*******************
开始:
@*******************
@欢迎辞。
ldr r0,=strInputPrompt@将我字符串的地址放入第一个参数中
bl printf@调用C printf以显示输入提示。
ldr r0,=inputPrompt1@将我字符串的地址放入第一个参数中
bl printf@调用C printf以显示输入提示。
ldr r0,=numInputPattern@Setup读取一个数字。
ldr r1,=输入@加载r1,输入值存储地址。
bl scanf@扫描键盘
cmp r0,#READERROR@检查读取错误。
beq readerror@如果出现读取错误,请处理它。
ldr r3,=将输入加载到r3时的输入
ldr r3,[r3]@读取输入的内容并存储在r3中
移动r2,#-1@将-1加载到r2中
cmp r3,r2@输入的值是否小于或等于-1?
ble invalidnums@如果是,打印无效消息
ldr r0,=inputPrompt2@将我字符串的地址放入第一个参数中
bl printf@调用C printf以显示输入提示。
ldr r0,=numInputPattern@Setup读取一个数字。
ldr r1,=intInput2@load r1,输入值存储地址。
bl scanf@扫描键盘
cmp r0,#READERROR@检查读取错误。
ldr r4,=将输入加载到r4时的输入
ldr r4,[r4]@读取输入的内容并存储在r4中
移动r3,#-1@将-1加载到r2中
cmp r4,r3@输入的值是否小于或等于-1?
ble invalidnums@如果是,打印无效消息
@再次blt@如果返回值无效,请再次尝试
@mov r1,r0
@ldr r0,=答案
@bl printf@打印答案
@再问一次
@*******************
取得进展:
@*******************
ldr r0,=inputPrompt3@将我字符串的地址放入第一个参数中
bl printf@调用C printf以显示输入提示。
ldr r0,=charInputPattern@Setup读取一个数字。
ldr r1,=charInput@load r1,带有输入值存储地址。
bl scanf@扫描键盘
cmp r0,#READERROR@检查读取错误。
ldr r5,=charInput@将charInput加载到r5中
ldr r5,[r5]@读取charInput的内容并存储在r5中
推送{r3,r4}
CMPR5,#“+”@用户是否输入了+?
beq addTest@如果是,请转到addTest
cmp r5,#'-'@用户是否输入了-?
beq子测试@如果是,转到子测试
cmp r5,#'*'@用户是否输入*?
beq Multest@如果是,请转到Multest
cmp r5,#'/@用户是否输入了/?
beq divTest@如果是,则转到divTest
b开始@返回到程序的开始
@*******************
添加测试:
@*******************
ldr r0,=addOpt@将我字符串的地址放入第一个参数中
bl printf@调用C printf以显示输入提示。
bl addCalc
pop{r0}
mov r1,r0
ldr r0,=答案
bl printf
@*******************
子测验:
@*******************
ldr r0,=subOpt@将字符串的地址放入第一个参数中
bl printf@调用C printf以显示输入提示。
bl副信用证
pop{r0}
mov r1,r0
ldr r0,=答案
bl printf
@*******************
多测试:
@*******************
ldr r0,=multOpt@将我的字符串的地址放入第一个参数中
bl printf@调用C printf以显示输入提示。
bl multCalc
pop{r0}
@*******************
divTest:
@*******************
ldr r0,=divOpt@将我字符串的地址放入第一个参数中
bl printf@调用C printf以显示输入提示。
bl divCalc
pop{r0}
@***********
addCalc:
@***********
pop{r5,r6}
加上r6,r5,r6
@cmp r6,#0@测试大写字是否为非零(用于溢出)
@vs溢出
@movgt r7,#-1@如果溢出,则加载-1
@asrle r7,#1@如果不是,则除以2
@blgt溢出@如果溢出,则打印溢出
@mov r0,r7
推送{r6}
返回时的bx lr
@***********
次级信用证:
@***********
pop{r5,r6}
接头r6、r5、r6@减去r5-r6并存储在r6中
@cmp r6,#0@测试大写字是否为非零(用于溢出)
@vs溢出
@movgt r7,#-1@如果溢出,则加载-1
@asrle r7,#1@如果不是,则除以2
@blgt溢出@如果溢出,则打印溢出
@mov r0,r7
按{r6}@return
bx-lr
@***********
multCalc:
@***********
mov r6,#0
umull r7、r6、r4、r5@64位乘法
@cmp r6,#0@测试大写字是否为非零(用于溢出)
@vs溢出
@movgt r7,#-1@如果溢出,则加载-1
@asrle r7,#1@如果不是,则除以2
@blgt溢出@如果溢出,则打印溢出
mov r0,r7
推送{r6}
返回时的bx lr
@***********
divCalc:
@***********
mov r6,#0
bl divLoop
@cmp r6,#0@测试大写字是否为非零(用于溢出)
@vs溢出
@movgt r7,#-1@如果溢出,则加载-1
@asrle r7,#1@如果不是,则除以2
@blgt溢出@如果溢出,则打印溢出
@mov r0,r7
推送{r6}
返回时的bx lr
@***********
divLoop:
@***********
接头r4、r4、r5@r4-r5和stor
mov r3, #-1         @ load -1 into r2
cmp r4, r3          @ is the value entered less than or equal to -1?
...
bl  printf               @ Call the C printf to display input prompt.
...
bl scanf            @ scan the keyboard
...

push {r3,r4}   <--- HERE

cmp r5, #'+'        @ did user enter +?
@*******************
addTest:
@*******************
ldr r0, =addOpt        @ Put the address of my string into the first parameter
bl  printf              @ Call the C printf to display input prompt. 

bl addCalc
pop {r0}
mov r1, r0
ldr r0, =answer
bl printf

@*******************

@***********
addCalc:
@***********

pop {r5,r6}       <--- (1)
add r6, r5, r6
...    
push {r6}         <--- (2)
bx lr          @ return
cmp r5, #'+'        @ did user enter +?
beq addTest             @ if yes, go to addTest

cmp r5, #'-'        @ did user enter -?
beq subTest             @ if yes, go to subTest

cmp r5, #'*'            @ did user enter *?
beq multTest        @ if yes, go to multTest

cmp r5, #'/'            @ did user enter /?
beq divTest             @ if yes, go to divTest

b begin             @ back to beginning of program

@*******************
addTest:
@*******************
ldr r0, =addOpt        @ Put the address of my string into the first parameter
bl  printf              @ Call the C printf to display input prompt. 

bl addCalc
pop {r0}
mov r1, r0
ldr r0, =answer
bl printf
                      <---- HERE ----
@*******************
subTest:
@*******************
ldr r0, =subOpt        @ Put the address of my string into the first parameter
bl  printf              @ Call the C printf to display input prompt. 

bl subCalc
pop {r0}
mov r1, r0
ldr r0, =answer
bl printf