assembly - MIPS 存储多项式和分支
问题描述
我有一个将两个多项式相除的 mips 汇编程序,但我不确定如何存储值和余数。我一直无法理解 sw 指令的偏移部分是如何工作的。欢迎任何帮助。
## Evaluate (8x^2-3x+12)/(3x^2+2x-16)
.text
.globl main
main:
lui $10, 0x1000 # Init base register
lw $11, 0($10) # Load x
sll $0,$0,0 # noop
ori $12,$0,0 # Init the accumulator
# during the "load delay slot"
ori $13,$0,2 # Evaluate second term coefficient
mult $11,$13 # 2x
mflo $13 # assume 32 bit result
ori $14,$0,16 # register 14 = 16
addu $12,$12,$13 # accumulator = 2x
subu $12,$12,$14 # accumulator = 2x-16
mult $11,$11 # x^2
mflo $11 # assume 32 bit result
ori $13,$0,3 # evaluate third term coefficient
mult $11,$13 # 3x^2
addu $12,$12,$13 # accumulator = 3x^2+2x-16
ori $15,$0,12 # init the accumulator
# during the "load delay slot"
ori $13,$0,3 # Evaluate second term coefficient
mult $11,$13 # 3x
mflo $13 # assume 32 bit result
subu $15,$15,$13 # accumulator = -3x+12
mult $11,$11 # x^2
mflo $11 # assume 32 bit result
ori $13,$0,8 # third term coefficient
mult $11,$13 # 8x^2
mflo $13 # assume 32 bit result
addu $15,$15,$13 # accumulator = 8x^2-3x+12
addu $13,0 # make temp 0
beq $12,$13,equal # branch if denom is 0
sll $0,$0,0 # branch delay slot
addu $16,0 # set Error to 0
div $15,$12 # divide the two accumulators
mflo $12 # the quotient is in $12
mfhi $15 # the remainder is in $15
sw $12,8($10) # store $12 in ratio
sw $15,12($10) # store $15 in remain
ori $16,$0,1 # set Error to 1
sw $16,4($10) # store 1 in error
j cont
sll $0,$0,0 # branch delay slot
equal: ori $16,$0,1 # set Error to 1
sw $16,4($10) # store 1 in error
cont: sll $0,$0,0 # noop
.data
x: .word 1 # Edit this line to change x
error: .word 0 # Error value is placed here
ratio: .word 0 # Ratio value is placed here
remain: .word 0 # Remainder value placed here
## End of file
解决方案
您没有提及您使用的是什么环境,但如果它的 MARS 或 SPIM 为例,那么数据部分 ( .data
) 开始于 address 0x10010000
,而不是0x10000000
,因此第一个全局变量将位于那里而不是您正在考虑的位置。
因此,您的初始lui
值减 1。这将使访问全局变量变得困难。您是否成功加载x
到$11
from 0($10)
?如果不是,这就是原因。
无论您是使用 MARS 还是 SPIM 或其他东西,使用la $10, x
而不是 raw可能会更好lui
。
和指令提供了一个简单的基址寄存器加位移寻址模式lw
,仅此sw
而已。处理器计算有效地址(发送到内存单元进行读取或写入的地址)作为指令中指定的基址寄存器的内容,加上指令的符号扩展的 16 位立即数。因此,您可以从基址寄存器达到 +/-32k。如果基数 in$10
指向,则您正在正确使用商店x
。
但是,如果基址寄存器(此处$10
)指向0x10000000
您将无法访问您的变量x
,因为您需要一个立即值 +65536(又名0x10000
),它大于 MIPS 可以在一条指令中为您提供的值。
但是,许多人会改用数据标签,例如sw $16,error
存储错误而不是sw $16,4($10)
.
可以肯定的是,使用标签访问全局变量是伪指令,汇编器将把它们扩展为两条指令,但它们更容易让我们在汇编中阅读——而且在使用标签时,我们可以移动东西,它们仍然可以工作,而使用偏移量,您必须正确排序/编号。
推荐阅读
- c++ - 芬威克树(BIT)。在 O(logN) 中找到具有给定累积频率的最小索引
- python - PIL 仿射变换中的参数是什么意思?
- powerapps - Power 应用中的异常处理
- c++ - 在 Ubuntu 18.04 上安装 CudaSift
- flutter - 颤振中的 dio 包是否使用隔离来解码 json?
- r - R中两个文件的交集
- mongodb - 从 js 数组中找到对应的对象,并在 mongodb 聚合中使用它的字段
- workbox - 实现 Workbox 的不同方法?
- unity3d - Unity 无法启动 - 无法建立与 Unity 包管理器本地服务器进程的连接
- python - 如何使用 python 根据 pdf 文本的标题将我的文本字符串拆分为多个部分?