如何在MIPS汇编中使用OR、AND位运算实现指定数学表达式计算
MIPS位运算表达式实现指导
现有代码已知问题修正
- 加载c的注释错误:你定义的
c: .word 1024,代码中原注释$t3 = c = 512错误,实际$t3值为1024 - 运算注释错误:代码中
sll $s0, $t2, 1 # $s0 = 12 = l ^ b注释里的异或符号错误,实际是l * b,因为b值为2左移1位等价于乘2,逻辑正确但注释需要修正 - 数组下标越界风险:你定义的B数组仅18个元素(下标0~17),加载
B[18]会越界,需要先给B数组补1个元素,比如修改为B: .word 23 2 3 4 5 6 7 7 8 3 6 2 4 1 5 6 3 7 7,这样B[18]值为7,偏移18*4=72,把原来的lw $t5, 68($s7)改为lw $t5, 72($s7) - 数组A的下标:你定义的A数组共25个元素(下标0~24),你要赋值的A[25]实际对应A[24],偏移96是对的,注意不要把数组名和表达式里的大写A变量混淆
补全后的完整实现代码
.data print: .asciiz " 𝐴[24] = [(𝑎 ∗ c/512 + 𝑙 ∗ 𝑏) |16]&[𝐴_val|𝐵_val ∗ c/16 − 𝐵[18]] = " space: .asciiz " " A: .word 12 2 3 4 5 6 7 7 8 3 6 2 4 1 5 6 3 7 4 8 5 4 3 2 1 # 补全B数组到19个元素,满足B[18]访问需求 B: .word 23 2 3 4 5 6 7 7 8 3 6 2 4 1 5 6 3 7 7 a: .word 4 b: .word 2 l: .word 6 c: .word 1024 # 表达式中的大写A、大写B变量,如果你指的是数组首元素可以改成lw加载A/B数组第一个word即可 A_val: .word 8 B_val: .word 4 .text main: # 加载基础变量 lw $t0, a # $t0 = a = 4 lw $t1, b # $t1 = b = 2 lw $t2, l # $t2 = l = 6 lw $t3, c # $t3 = c = 1024 la $s5, A # $s5 = 数组A首地址 la $s7, B # $s7 = 数组B首地址 lw $t5, 72($s7) # $t5 = B[18] = 7 lw $t6, A_val # $t6 = 表达式中的A值 lw $t7, B_val # $t7 = 表达式中的B值 # 计算左半部分:(a * c/512 + l * b) | 16 srl $s0, $t3, 9 # $s0 = c / 512 = 1024 >>9 = 2 mul $s1, $t0, $s0 # $s1 = a * c/512 = 4*2=8 mul $s2, $t2, $t1 # $s2 = l * b =6*2=12 add $s3, $s1, $s2 # $s3 = a*c/512 + l*b = 8+12=20 ori $s3, $s3, 16 # 左半部分结果存入$s3:20 | 16 = 36 # 计算右半部分:(A_val | B_val) * c/16 - B[18] or $s4, $t6, $t7 # $s4 = A_val | B_val,符合要求的OR位运算 srl $s0, $t3, 4 # $s0 = c/16 =1024>>4=64 mul $s4, $s4, $s0 # $s4 = (A|B)*c/16 sub $s4, $s4, $t5 # 右半部分结果存入$s4 # 左右半部分做AND位运算,结果存到A[24] and $s5, $s3, $s4 sw $s5, 96($s5) # 结果写回数组A对应位置 # 打印结果 li $v0, 4 la $a0, print syscall li $v0, 1 move $a0, $s5 syscall # 程序正常退出 li $v0, 10 syscall
关键逻辑说明
- 位运算指令:OR运算用
or/ori指令,AND运算用and/andi指令,完全匹配题目要求的位运算规则 - 除法优化:因为除数都是2的幂,所以用逻辑右移
srl代替除法,运算效率更高,512是29所以右移9位,16是24所以右移4位 - 优先级处理:严格按照先乘除后加减、位运算优先级低于算术运算的规则执行,运算顺序和题目要求完全一致
内容的提问来源于stack exchange,提问作者darklord
相关产品推荐
相关产品推荐

