【问题标题】:Storing an array into another array将一个数组存储到另一个数组中
【发布时间】:2013-03-11 16:51:54
【问题描述】:

我正在尝试将数组 A 复制到数组 N 中,然后打印该数组(以测试它是否有效)但它输出的只是 -1

这是我的代码:

    ORG    $1000
START:                  ; first instruction of program

    clr.w d1

    movea.w #A,a0
    movea.w #N,a2
    move.w #6,d2
for move.w (a0)+,(a2)+
    DBRA d2,for
    move.w #6,d2
loop
    move.l  (a2,D2),D1  ; get number from array at index D2
    move.b  #3,D0       ; display number in D1.L
    trap    #15

    dbra d2,loop



SIMHALT             ; halt simulator

A dc.w 2,2,3,4,5,6
N dc.l 6


END    START        ; last line of source

为什么-1 只在输出中?如果有更好的解决方案,那将非常有帮助

【问题讨论】:

  • 有些事情一目了然:N dc.l 6 - 我很确定这只会为单个长字分配存储空间(值为 6),而不是为 6 个长字分配存储空间(正如我认为你想要的那样)。 move.l (a2,D2),D1 ; get number from array at index D0 dbra(参见例如here
  • @user786653 你说得对,应该是(a2,D2),D1 ; get number from array at index D2。不知道dbra怎么用错了,我想把d2递减到0,否则循环。我将如何为 6 个 long 分配存储空间?谢谢
  • 链接页面显示了正确和错误的dbra用法示例,找到符合您需求的。如何分配存储取决于您使用的汇编程序,但通常类似于ds.l
  • 据我所知,我的问题可以通过转到endl 来解决,这将启动循环,或者将我的循环次数减少 1,因为它会循环 6+1 次而不是 6 次。我尝试了减量,但它仍然不起作用,我不想使用endl。我忘了分配存储是使用ds.l谢谢。
  • 看起来你的数据大小到处都是。您正在将地址加载为 16 位(好的,您已经在内存中组织了代码低位,但是......),然后复制单词,但是您尝试通过以字节为单位进行索引来打印它们,但加载为长话...

标签: arrays assembly 68000


【解决方案1】:

由于我无法访问您正在使用的任何汇编器/模拟器,因此我无法对其进行实际测试,但这里有一些东西(其中一些已经在 cmets 中注明):

  • dc.l 声明一个 long,您希望 ds.l(或类似的)为 6 个 long 分配存储
  • dbra 分支直到操作数等于-1,所以你可能想转

    movw #loop_times, d0
    loop
       ....
       dbra d0, loop
    

    进入

    movw #loop_times-1, d0
    loop
       ....
       dbra d0, loop
    

(只要loop_times > 0 就有效,否则你必须在进入循环之前检查条件)

  • 您的显示循环有几个问题: 1. 在入口a2 指向超过N 数组的末尾。 2. 即使修复它,索引它的方式也会导致问题。在第一个条目中,您尝试从地址 a2 + 6 获取 4 字节长,然后从 a2 + 5 获取长 ...

您想要的是从地址a2 + 0a2 + 4 中获取longs ...。一种方法是:

    move.w  #6-1, d2    ; note the -1
    movea.l #N, a2
loop
    move.l  (a2)+,D1    ; get next number from array
    ; use d1 here
    dbra    d2,loop

【讨论】:

    【解决方案2】:

    正如已经指出的,你的新数组只有 4 个字节大小,你应该改变

    dc.l 6 到 ds.w 6

    而且您还要处理 7 个元素,因为 DBRA 倒计时到 -1。

    第二,这就是为什么你到处都是 -1,你使用 A2 作为指向新数组的指针,但你没有将它重置为指向新数组中的第一个单词。由于在复制过程中每个元素增加了一个单词,因此在 for 循环完成后,A2 指向数组之后的第一个单词。

    您的模拟器在显示循环中输出多个数字表明您的模拟器没有模拟 MC68000,真正的 MC68000 会在“MOVE.L (A2,D2),D1 " 只要 A2+D2 的总和为奇数 - 68000 就不允许 W/L 大小的访问奇数地址(MC68020 和更高版本允许)。

    干净的 MC68000 兼容代码可能如下所示:

         lea A,a0
         lea N,a2
         moveq #5,d2
     for move.w (a0)+,(a2)+
         dbra d2,for
    
         lea N,a2
         moveq #5,d2
     loop
         move.w  (a2)+,D1   ; get number (16 bits only)
         ext.l d1           ; make the number 32 bits
         moveq  #3,D0       ; display number in D1.L
         trap    #15
         dbra d2,loop
    

    它可能包含一些您尚未遇到的说明。

    【讨论】:

    • 谢谢,但 LEA 是做什么的?
    • LEA(加载有效地址)有点类似于 MOVE,因为它评估第一个参数并将结果加载到目标寄存器中。 LEA 仅是专门的地址(因此它总是生成完整的 32 位结果),更高版本的 MC680x0 可以在地址生成单元而不是 ALU 中执行此操作(更快)。从源代码的角度来看,lea 明确表示对地址进行评估,并且其语法使其不易出错(一个好的汇编程序应该自动选择最佳寻址模式,而无需您指定它)。
    猜你喜欢
    • 2022-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-23
    • 1970-01-01
    • 2020-02-01
    • 1970-01-01
    • 2012-09-11
    相关资源
    最近更新 更多