Assembly 完成装配程序

Assembly 完成装配程序,assembly,lc3,Assembly,Lc3,我得到了用LC3编写的程序的一部分,并被告知添加缺少的部分。幸运的是,我能够在网上找到答案,但这并不能帮助我理解为什么答案是这样的,或者我知道如何编写特定的说明。这是代码(带答案),我将用字母(a)-(e)标记我们要添加的行。程序确定字符串是否为回文 .ORIG x3000 LEA R0, PTR ADD R1, R0, #0 AGAIN LDR R2, R1, #0 BRz CONT ADD R1, R1, #1 BRnz

我得到了用LC3编写的程序的一部分,并被告知添加缺少的部分。幸运的是,我能够在网上找到答案,但这并不能帮助我理解为什么答案是这样的,或者我知道如何编写特定的说明。这是代码(带答案),我将用字母(a)-(e)标记我们要添加的行。程序确定字符串是否为回文

      .ORIG x3000
      LEA R0, PTR
      ADD R1, R0, #0
AGAIN LDR R2, R1, #0
      BRz CONT
      ADD R1, R1, #1
      BRnzp AGAIN
CONT  ADD R1, R1, #-1 --> (a)
LOOP  LDR R3, R0, #0
      LDR R4, R1, #0 -->(b)
      NOT R4, R4
      ADD R4, R4, #1
      ADD R3, R3, R4
      BRnp NO
      ADD R0, R0, #1 --> (c)
      ADD R1, R1, #-1 --> (d)
      NOT R2, R0
      ADD R2, R2, #1
      ADD R2, R1, R2
      BRnz YES
      BR LOOP --> (e)
YES   AND R5, R5, #0
      ADD   R5, R5, #1
      BRnzp DONE
NO    AND R5, R5, #0
DONE  HALT
PTR   .FILL X4000
.END

这里我认为唯一明显的是(e),因为没有BR循环将您带回循环的顶部。有人能解释一下为什么这些命令会起作用,以及如何开始思考这些命令吗?例如,我如何知道在第(b)部分中添加“LDR R4,R1,#0”?谢谢

在您能够详细理解每一行之前,您需要了解程序试图实现的目标。我们可以看到,这是一个例行检查,以确保PTR后存储的值相等。如果值满足此要求,则此例程将R5设置为1,否则将R5设置为0

行(a):我们需要这一行,因为第一个循环在PTR之后检查每个内存位置,直到找到一个空内存块(搜索null),代码
ADD R1,R1,#-1
将我们从该空内存带到最后一个非零内存位置

行(b):由于我们的子程序需要比较两个不同的内存位置,我们需要加载最初存储在R1中的值。我们将该值加载到R4中的原因是该行后面的代码正在反转R4寄存器

第(c)行和第(d)行:我们必须包含这些行,以便移动到内存中的下一个块进行比较。在下面的示例中,我在PTR之后包含了更多的值:

PTR    .FILL x4000    ; Stored at x3019
       .FILL x400F    ; Stored at x301A
       .FILL x40FF    ; Stored at x301B
       .FILL x4000    ; Stored at x301C
在第一次检查中,R0=x3019R1=x301C。因为存储在x3019的值等于存储在x301C的值,所以我们再次循环


在第二次检查中,R0=x301AR1=x301B。由于x301A和x301B中存储的值彼此不相等,因此我们的例程退出并将R5设置为0

我希望这有帮助,这个子程序有点复杂。如果你有具体的问题,我会尽力帮你回答。我想我的问题是,你怎么知道它在检查内存位置和搜索空值?我看到“加R1,R1,#1”,我想“加1到R1中存储的值,然后存储到R1中。”你怎么知道它在检查内存位置?我很难解释LC-3代码。没问题,asm不像其他高级语言那样直观。由于“BRz CONT”,我们可以看出这就是程序在第一个循环中寻找的内容。它的意思是分支如果为零,但这只会给出空内存块的内存位置,所以“添加R1,R1,#-1”就像回到最后一个“填充”内存位置。这就像在一条有一排房子的街道上开车,你的朋友打电话告诉你他的家是街上最后一个。所以LC3在这条街上巡游,直到它发现一块空地,然后说它一定是我经过的最后一栋房子,并反转了一个记忆块。