条件(x <10)时如何计算不同的结果

时间:2017-12-03 06:58:41

标签: assembly mips

所以我有一个使用Assembly创建程序的任务,它要求用户输入一个 x 的数字。

如果 x 小于10,则将(x * 2)替换为(x-7)+(x%3)的x并打印出结果。

如果它大于10,那么它只使用等式 (X-7)+(X%3)。

到目前为止,我已为第二部分做了所有事情“(x-7)+(x%3)”。

我需要帮助弄清楚如何找到x&lt; 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

1 个答案:

答案 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教程,并对其进行练习,不要因为效率低下而毁掉这个特定的任务。