如何执行本节代码,但在ARM Assembly中使用自动索引

时间:2019-01-24 23:46:20

标签: arrays assembly arm

这行得通,但是我必须使用自动索引来做到这一点,我无法弄清楚那部分。

writeloop:
  cmp r0, #10
  beq writedone
  ldr r1, =array1
  lsl r2, r0, #2
  add r2, r1, r2
  str r2, [r2]
  add r0, r0, #1
  b writeloop

还有我拥有的数据

.balign 4
array1: skip 40

我尝试过的是这个,是的,我知道这可能是一个糟糕的尝试,但是我对此并不陌生

ldr r1, =array1

writeloop:
  cmp r0, #10
  beq writedone
  ldr r2, [r1], #4
  str r2, [r2]
  add r0, r0, #1
  b writeloop

尝试此操作时显示细分错误。怎么了?我想应该发生的是,每次循环通过时,都会将元素r2的=设置为自身的地址,然后递增到下一个元素并执行相同的操作

1 个答案:

答案 0 :(得分:0)

ARM体系结构提供了几种不同的地址模式

From ARM946E-S product overview和许多other sources

  

加载和存储指令具有三种主要寻址模式
  -偏移
  -预索引
  -后索引。
  
它们是通过在基址寄存器中增加或减去立即数或基于寄存器的偏移量而形成的。基于寄存器的偏移量也可以通过移位操作进行缩放。预索引和后索引寻址模式使用基数加偏移量计算来更新基址寄存器。由于PC是通用寄存器,因此可以将32位值直接加载到PC中,以跳转到4GB内存空间中的任何地址。

同样,它们支持回写或寄存器更新,因此是预索引后索引的原因。如果没有回写,后索引没有多大意义。

由于您遇到的问题,我相信您希望将值0-9写入由10个字组成的数组(长度为4个字节)。假设这样,您可以使用索引并通过add更新值。导致

  mov r0, #0       ; start value
  ldr r1, =array1  ; array pointer

writeloop:
  cmp r0, #10
  beq writedone
  str r0, [r1, r0, lsl #2] ; index with r1 base by r0 scaled by *4
  add r0, r0, #1
  b writeloop
writedone:
; code to jump somewhere else and not execute data.

.balign 4
array1: skip 40

出于兴趣,可以通过计数和写下来完成更有效的循环

  mov r0, #9       ; start value
  ldr r1, =array1  ; array pointer

writeloop:
  str r0, [r1, r0, lsl #2] ; index with r1 base by r0 scaled by *4
  subs r0, r0, #1
  bne writeloop

您的原始示例正在将指针写入数组;通常称为“价值等于地址”。如果这是您想要的,

  ldr r0, =array_end ; finished?
  ldr r1, =array1    ; array pointer
write_loop:
  str r1, [r1], #4  ; add four and update after storing
  cmp r0, r1
  bne write_loop
; code to jump somewhere else and not execute data.

.balign 4
array1: skip 40
array_end: