【愚公系列】2022年06月 ARM汇编 LDM和STM
LDM(载入多个值)和STM(存储多个值)
.data
array_buff:
.word 0x00000000 /* array_buff[0] */
.word 0x00000000 /* array_buff[1] */
.word 0x00000000 /* array_buff[2]. This element hasa relative address of array_buff+8 */
.word 0x00000000 /* array_buff[3] */
.word 0x00000000 /* array_buff[4] */
.text
.global _start
_start:
adr r0, words+12 /* address of words[3] -> r0 /
(我们使用ADR指令(偷懒的办法)将数组第四部分(word[3])的地址传送给R0。我们用R0指向word数组的中间位置,所以我们可以从这开始向前或者向后移动指针)
ldr r1, array_buff_bridge / address of array_buff[0] -> r1 */
ldr r2, array_buff_bridge+4 /* address of array_buff[2] -> r2 /
(执行完上面的两条命令后,R1,R2中分别包含了 array_buff[0]的地址和 array_buff[2]的地址)
ldm r0, {r4,r5} / words[3] -> r4 = 0x03;words[4] -> r5 = 0x04 /
(使用LDM指令,将R0指向的内存中,取两个字的数据出来。由于之前我们让R0指向了word[3],因此word[3]的值会被存入R4, word[4]的会被存入R5)
stm r1, {r4,r5} / r4 -> array_buff[0] = 0x03;r5 -> array_buff[1] = 0x04 /
(使用STM指令将多个值写入内存。STM指令将R4,R5寄存器的值0x3和0x4存入R1指向的内存空间中。由于之前我们让R1指向 array_buff的第一个元素,所以指令执行后 array_buff[0] = 0x00000003 ,array_buff[1] =0x00000004。如果没有特别说明,LDM和STM指令操作的基本单位是一个字(32位等于4个字节))
ldmia r0, {r4-r6} / words[3] -> r4 = 0x03,words[4] -> r5 = 0x04; words[5] -> r6 = 0x05; */
stmia r1, {r4-r6} /* r4 -> array_buff[0] = 0x03;r5 -> array_buff[1] = 0x04; r6 -> array_buff[2] = 0x05 /
( 执行完上面的两条指令后,寄存器R4-R6分别包含了 0x3,0x4,0x5 ,内存地址0x000100D0, 0x000100D4,和 0x000100D8中也包含了0x3,0x4,0x5)
ldmib r0, {r4-r6} / words[4] -> r4 = 0x04; words[5] -> r5= 0x05; words[6] -> r6 = 0x06 */
stmib r1, {r4-r6} /* r4 -> array_buff[1] = 0x04;r5 -> array_buff[2] = 0x05; r6 -> array_buff[3] = 0x06 */
(LDMIB指令先将源地址增加4字节(一个字),然后开始载入数据。该方法仍能让我们载入一串前向数据,但第一个数据的起始地址相较源地址有4个字节的偏移。这就是为什么我们用LDMIB指令将内存中的第一个元素载入R4后,R4是0x04(word[4]),而不是R0指向的0x3(word[3])
执行之后,寄存器R4-R6存储了0x4,0x5,0x6, 0x100D4, 0x100D8, 和0x100DC也存储了 0x4,0x5,0x6。)
ldmda r0, {r4-r6} /* words[3] -> r6 = 0x03; words[2]-> r5 = 0x02; words[1] -> r4 = 0x01 */
ldmdb r0, {r4-r6} /* words[2] -> r6 = 0x02;words[1] -> r5 = 0x01; words[0] -> r4 = 0x00 /
(使用LDMDA向相反方向执行运算。R0指向word[3],载入操作开始后,我们向后将 words[3], words[2]和words[1]载入R6, R5, R4。注意,连寄存器都是反着被载入的。所以指令将 R6赋值为0x00000003, R5赋值为0x00000002, R4赋值为0x00000001。这里的逻辑是,每次载入操作完成后向后减少内存地址所以是反向赋值。)
stmda r2, {r4-r6} / r6 -> array_buff[2] = 0x02;r5 -> array_buff[1] = 0x01; r4 -> array_buff[0] = 0x00 */
stmdb r2, {r4-r5} /* r5 -> array_buff[1] = 0x01;r4 -> array_buff[0] = 0x00; */
bx lr
words:
.word 0x00000000 /* words[0] */
.word 0x00000001 /* words[1] */
.word 0x00000002 /* words[2] */
.word 0x00000003 /* words[3] */
.word 0x00000004 /* words[4] */
.word 0x00000005 /* words[5] */
.word 0x00000006 /* words[6] */
array_buff_bridge:
.word array_buff /* address of array_buff, or inother words - array_buff[0] */
.word array_buff+8 /* address of array_buff[2] */
- 点赞
- 收藏
- 关注作者
评论(0)