所以我有一个使用Assembly创建程序的任务,它要求用户输入一个 x 的数字。
如果 x 小于10,则将(x * 2)替换为(x-7)+(x%3)的x并打印出结果。
如果它大于10,那么它只使用等式 (X-7)+(X%3)。
到目前为止,我已为第二部分做了所有事情“(x-7)+(x%3)”。
我需要帮助弄清楚如何找到x< 10以及如何切换到该等式。
.data
Q1: .asciiz "Enter an integer x: "
op1: .asciiz "(x - 7) + (x % 3) = "
op2: .asciiz "((x * 2) - 7) + ((x * 2) % 3) = "
.text
#Get x from user
la $a0, Q1 #Load the prompt
li $v0, 4 #Print the question for the user
syscall
li $v0, 5 #Get x from the user
syscall
move $t0, $v0 #Save x in reg $t0
#Determine if x is less than 10
#TODO not implemented
#Performing the calculations
sub $t1, $t0, 7 #t1 = (x - 7)
rem $t2, $t0, 3 #t2 = (x % 3)
add $t3, $t1, $t2 #t3 = (x - 7) + (x % 3)
#Output results for x > 10
la $a0, op1
li $v0, 4
syscall
move $a0, $t3
li $v0, 1
syscall
#End the program
halt: li $v0, 10
syscall
答案 0 :(得分:2)
从syscall
用法看起来您正在使用MARS / SPIM MIPS模拟器之一。如果您碰巧使用MARS,仅仅 F1 将为您提供帮助窗口,您可以在其中单击包含各种信息的选项卡,包括基本和支持的伪指令的完整列表。在考虑某些算法/任务时,使用几轮思考如何将任务分解为算法和简单步骤,并检查指令集以查看哪些指令可用。
在代码中注释时,您在t0
中将用户值设置为整数,如果小于10,则需要将其乘以2.剩余的计算对于两种情况都相同,因此在你可以这样做:
if (x < 10) x *= 2;
// continue with "(x - 7) + (x % 3) = " calculation
你让编译器的优化器击败了它。如果您要创建一个主要的复制/粘贴意大利面条代码,例如:if (x < 10) { ...formulae with x*2 code... } else { ...same formulae with simple x code...}
,您仍然有一个非常不错的机会,现代编译器会注意到它并将其减少为x
或{{1}的单一计算值取决于条件。
在汇编中你也是优化器,所以让我们再尝试一下(在你意识到你可以在两种情况下重复使用相同的计算之后)。
x*2
可以通过将值左移一位来完成组装,这比计算完全乘法要快得多且操作简单得多(对于人类在纸上做* 10来说就是这样) ,您可以通过两个值的常规乘法来计算它,或者您可以在源数字的末尾添加&#34; 0&#34; ...在二进制中,左移在末尾添加零位。)
integer x *= 2
表示分支,但分支通常对CPU无效。如果可以合理避免,请避免使用它。
在您的情况下,当条件为真时,您需要向左移1位。当条件为假时,您需要保持x的原始值不变。但这等于&#34;左移零位#34;。现在,如果你将条件转换为1/0结果,你可以通过这样的结果向左移动x来达到你需要的效果。
如果您要检查&#34;小于&#34;变种,&#34;左移&#34;变体 - 看看你的选择是什么以及CPU直接支持什么 - 你可能会注意到你只能用两条指令解决这个任务,就像MIPS几乎是为你的任务而构建的:
if
完成。
如果任务本应该让你练习分支,请查看互联网上有关分支的一些MARS / SPIM教程,并对其进行练习,不要因为效率低下而毁掉这个特定的任务。