汇编中将字符转换为整数的方法——后缀表达式作业求助
MIPS汇编实现后缀表达式求值:字符转整数的解决方案
作业要求:编写MIPS汇编程序,读取用户输入的后缀表达式,输入'='时输出结果,必须用栈实现。目前栈中存储的是字符类型输入,不清楚如何将其转为整数以进行运算,当前完成的代码如下:
.text globl main main: #Preload the operations li $s1, '+' li $s2, '-' li $s3, '*' li $s4, '/' li $s5, '=' li $v0,4 la $a0,prompt syscall li $v0, 12 syscall move $t0, $v0 sub $sp, $sp, 4 sw $t0, ($sp) bne $t0, '=', loop li $v0, 4 la $a0, error syscall li $v0, 10 syscall loop: li $v0,4 la $a0,prompt syscall li $v0,12 syscall move $t1, $v0 beq $t1, '=', result_process beq $t1, ' ', loop sub $sp, $sp, 4 sw $t1, ($sp) blt $t1, '0', operations bgt $t1, '9', operations j loop li $v0, 10 syscall operations: lw $t2, ($sp) add $sp, $sp, 4 lw $t3, ($sp) add $sp, $sp, 4 beq $t1, '+', add_process beq $t1, '-', sub_process beq $t1, '*', mul_process beq $t1, '/', div_process add_process: add $t4, $t2, $t3 sub $sp, $sp, 4 sw $t4, ($sp) j loop sub_process: sub $t4, $t2, $t3 sub $sp, $sp, 4 sw $t4, ($sp) j loop mul_process: mul $t4, $t2, $t3 sub $sp, $sp, 4 sw $t4, ($sp) j loop div_process: beq $t3, '0', error_div div $t4, $t2, $t3 sub $sp, $sp, 4 sw $t4, ($sp) j loop result_process: lw $t5, ($sp) add $sp, $sp, 4 li $v0,4 la $a0, result syscall move $a0, $t5 li $v0, 11 syscall li $v0,10 syscall error_div: li $v0,4 la $a0, div_error syscall li $v0, 10 syscall .data prompt: .asciiz "\nPostfix (input): " error: .asciiz "\nInvalid Postfix!" div_error: .asciiz "\nDivide by zero!" test: .asciiz "\nWorks!" result: .asciiz "\nPostfix evaluation: "
字符转整数的核心逻辑
MIPS没有专门的字符转整数指令,但可以利用ASCII码的连续特性实现:数字字符'0'-'9'的ASCII码值是48到57,将字符值减去'0'的ASCII码(48)就能得到对应的整数。
例:字符'5'的ASCII码是53,53-48=5,即对应整数5。
代码修改要点
1. 入栈前转换数字字符
读取到'0'-'9'的字符时,先转成整数再入栈,替换原来直接存储字符的逻辑:
# 替换loop中原有的数字判断代码 blt $t1, '0', operations bgt $t1, '9', operations # 字符转整数:减去'0'的ASCII码 sub $t1, $t1, '0' sub $sp, $sp, 4 sw $t1, ($sp) j loop
同时要删除原来直接存字符的sub $sp, $sp, 4; sw $t1, ($sp),避免重复入栈。
2. 修正运算逻辑与零值判断
栈中存储整数后,除法的零判断要改为判断整数0,而非字符'0':
# 替换div_process中的零判断 beq $t3, 0, error_div
另外要注意后缀表达式的运算顺序:栈顶弹出的是第二个操作数,次顶是第一个操作数,因此减法、除法要调整运算顺序(比如3 4 -实际是3-4,需用次顶值减栈顶值)。
3. 结果输出修正
当前用li $v0,11输出字符,栈中存储整数后要改用li $v0,1输出整数:
result_process: lw $t5, ($sp) add $sp, $sp, 4 li $v0,4 la $a0, result syscall move $a0, $t5 li $v0, 1 # 改为整数输出的系统调用 syscall li $v0,10 syscall
4. 初始输入的转换处理
main函数中第一次读取的字符也要做数字转换处理,避免初始字符入栈导致后续运算错误。
完整修改后的代码示例
.text .globl main main: #Preload the operations li $s1, '+' li $s2, '-' li $s3, '*' li $s4, '/' li $s5, '=' li $v0,4 la $a0,prompt syscall li $v0, 12 syscall move $t0, $v0 # 处理初始输入:数字转整数 blt $t0, '0', check_initial_eq bgt $t0, '9', check_initial_eq sub $t0, $t0, '0' check_initial_eq: sub $sp, $sp, 4 sw $t0, ($sp) bne $t0, '=', loop li $v0, 4 la $a0, error syscall li $v0, 10 syscall loop: li $v0,4 la $a0,prompt syscall li $v0,12 syscall move $t1, $v0 beq $t1, '=', result_process beq $t1, ' ', loop # 判断是否为数字,转整数后入栈 blt $t1, '0', push_data bgt $t1, '9', push_data sub $t1, $t1, '0' push_data: sub $sp, $sp, 4 sw $t1, ($sp) # 仅运算符进入运算处理 blt $t1, '0', operations bgt $t1, '9', operations j loop li $v0, 10 syscall operations: lw $t2, ($sp) add $sp, $sp, 4 lw $t3, ($sp) add $sp, $sp, 4 beq $t1, '+', add_process beq $t1, '-', sub_process beq $t1, '*', mul_process beq $t1, '/', div_process add_process: add $t4, $t3, $t2 sub $sp, $sp, 4 sw $t4, ($sp) j loop sub_process: sub $t4, $t3, $t2 sub $sp, $sp, 4 sw $t4, ($sp) j loop mul_process: mul $t4, $t3, $t2 sub $sp, $sp, 4 sw $t4, ($sp) j loop div_process: beq $t2, 0, error_div div $t4, $t3, $t2 sub $sp, $sp, 4 sw $t4, ($sp) j loop result_process: lw $t5, ($sp) add $sp, $sp, 4 li $v0,4 la $a0, result syscall move $a0, $t5 li $v0, 1 syscall li $v0,10 syscall error_div: li $v0,4 la $a0, div_error syscall li $v0, 10 syscall .data prompt: .asciiz "\nPostfix (input): " error: .asciiz "\nInvalid Postfix!" div_error: .asciiz "\nDivide by zero!" test: .asciiz "\nWorks!" result: .asciiz "\nPostfix evaluation: "
额外说明
- 上述代码仅支持单个数字的后缀表达式,若需处理多位数,需额外编写多位数拼接逻辑(比如将连续输入的
'1'和'2'拼接成整数12)。 - 后缀表达式的运算顺序必须严格遵循:栈顶弹出的是第二个操作数,次顶是第一个操作数,否则会出现运算结果颠倒的问题。
内容的提问来源于stack exchange,提问作者Fear de Beard ____
相关产品推荐
相关产品推荐

