有人可以帮助我理解stmdb,ldmia,以及如何用arm汇编语言实现这个C++代码吗?
Can someone help me understand stmdb, ldmia, and how I can go about implementing this C++ code in arm assembly language?
所以我有这段代码,其中N是两个数组的大小。
int i;
for (i = 0; i < N; i++)
{
if (listA[i] < listB[i])
{
listA[i] = listB[i];
}
}
我正在尝试将其实现为 ARM 程序集子例程,但我完全不知道如何处理数组。到目前为止,我有这个:
sort1:
stmdb sp!, {v1-v5, lr}
ldmia sp!, {v1-v5, pc}
我假设我必须使用 cmp 来比较值,但我什至不确定要使用什么寄存器。有人有任何指导吗?
编辑:
好的,我现在有这段代码:
sort1:
stmdb sp!, {v1-v5, lr} @ Copy registers to stack
ldr v1, [a1], #0 @ Load a1
str v1, [a2], #0 @ Copy elements of a1 to a2
ldmia sp!, {v1-v5, pc} @ Copy stack back into registers
这会复制 10 个元素数组的前四个元素,所以我假设如果我将"#0"更改为"#4",它会导致接下来的四个元素发生变化,但事实并非如此。为什么?
首先,正如你所演示的,加载/存储多个指令主要用于堆栈操作(尽管它们也可以进行有效的memcpy
(。简而言之,它们按顺序从/从base address
到base address + (number of registers * 4)
的连续内存块加载/存储指定的寄存器。
在给出的示例中,stmdb sp!, {v1-v5, lr}
在"递减前"寻址模式1 中存储 6 个寄存器,因此有效基址sp-24
- 它将v1
的内容存储在 sp-24
v2
sp-20
,...最多 lr
在 sp-4
.由于存在基本寄存器写回的!
语法,它将从sp
中减去 24,使其指向 v1
的存储值。ldmia
是完全相反的 - "Increment After"表示有效基址sp
,因此它将加载寄存器从sp
到sp+20
,然后将24加到sp
。请注意,它将堆叠的lr
值直接加载到pc
中 - 这样您就可以在单个指令中恢复寄存器并执行函数返回。
至于常规加载/存储指令,它们有 3 种寻址模式 - 偏移、预索引和后索引。 ldr v1, [a1], #0
是后索引的,意思是"从a1
中的地址加载v1
,然后将 0 加到 a1
",因此将#0
更改为 #4
不会影响使用的地址,只有之后写回基本寄存器的值。如果你已经实现了循环,效果就会变得清晰可见。
考虑一些示例 C 表达式如何映射到这些寻址模式可能会有所帮助:
int a; // r0
int *b; // r1
a = b[1]; // ldr r0, [r1, #4] (offset)
a = *(b+1); // similarly
a = *(++b); // ldr r0, [r1, #4]! (pre-indexed)
a = *(b++); // ldr r0, [r1], #4 (post-indexed)
请记住,偏移值也可以是寄存器而不是即时值,因此有几种可能的方法可以实现像给定的循环。
对于权威参考,我建议通读 ARM 架构参考手册的说明部分,或者阅读 Cortex-A 系列程序员指南,以获取不太详尽但更易于访问的介绍。
<小时 />[1] 这意味着一个降序堆栈 - 存在相应的"递减后"和"递增之前"寻址模式,用于运行升序堆栈。
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- 有人可以帮助我理解stmdb,ldmia,以及如何用arm汇编语言实现这个C++代码吗?